diff --git a/src/main/scala/config/Config.scala b/src/main/scala/config/Config.scala index 5ae84865..ebed6b6e 100644 --- a/src/main/scala/config/Config.scala +++ b/src/main/scala/config/Config.scala @@ -23,18 +23,25 @@ abstract class View { } abstract class Parameters extends View { - final def ++ (x: Parameters): Parameters = new ChainParameters(this, x) - final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = Parameters(f) ++ this - final def alterPartial(f: PartialFunction[Any,Any]): Parameters = Parameters((_,_,_) => f) ++ this + final def ++ (x: Parameters): Parameters = + new ChainParameters(this, x) + + final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = + Parameters(f) ++ this + + final def alterPartial(f: PartialFunction[Any,Any]): Parameters = + Parameters((_,_,_) => f) ++ this + + final def alterMap(m: Map[Any,Any]): Parameters = + new MapParameters(m) ++ this protected[config] def chain[T](site: View, tail: View, pname: Field[T]): Option[T] protected[config] def find[T](pname: Field[T], site: View) = chain(site, new TerminalView, pname) } object Parameters { - def empty: Parameters = new EmptyParameters + def empty: Parameters = new EmptyParameters def apply(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = new PartialParameters(f) - def root(p: Parameters) = p } class Config(p: Parameters) extends Parameters { @@ -69,3 +76,10 @@ private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) else tail.find(pname, site) } } + +private class MapParameters(map: Map[Any, Any]) extends Parameters { + protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = { + val g = map.get(pname) + if (g.isDefined) Some(g.get.asInstanceOf[T]) else tail.find(pname, site) + } +} diff --git a/src/main/scala/util/GeneratorUtils.scala b/src/main/scala/util/GeneratorUtils.scala index 5d67ff32..4270456b 100644 --- a/src/main/scala/util/GeneratorUtils.scala +++ b/src/main/scala/util/GeneratorUtils.scala @@ -29,25 +29,25 @@ case class ParsedInputNames( * canonical ways of building various JVM elaboration-time structures. */ trait HasGeneratorUtilities { - def getConfig(names: ParsedInputNames): Config = { - new Config(names.fullConfigClasses.foldRight(Parameters.empty) { case (currentName, config) => + def getConfig(fullConfigClassNames: Seq[String]): Config = { + new Config(fullConfigClassNames.foldRight(Parameters.empty) { case (currentName, config) => val currentConfig = try { Class.forName(currentName).newInstance.asInstanceOf[Config] } catch { case e: java.lang.ClassNotFoundException => - throwException(s"""Unable to find part "$currentName" from "${names.configs}", did you misspell it?""", e) + throwException(s"""Unable to find part "$currentName" from "$fullConfigClassNames", did you misspell it?""", e) } currentConfig ++ config }) } - def getParameters(names: ParsedInputNames): Parameters = getParameters(getConfig(names)) + def getParameters(names: Seq[String]): Parameters = getParameters(getConfig(names)) - def getParameters(config: Config): Parameters = Parameters.root(config.toInstance) + def getParameters(config: Config): Parameters = config.toInstance - def elaborate(names: ParsedInputNames, params: Parameters): Circuit = { + def elaborate(fullTopModuleClassName: String, params: Parameters): Circuit = { val gen = () => - Class.forName(names.fullTopModuleClass) + Class.forName(fullTopModuleClassName) .getConstructor(classOf[Parameters]) .newInstance(params) .asInstanceOf[RawModule] @@ -69,17 +69,8 @@ trait HasGeneratorUtilities { } res.toString } - - def writeOutputFile(targetDir: String, fname: String, contents: String): File = { - val f = new File(targetDir, fname) - val fw = new FileWriter(f) - fw.write(contents) - fw.close - f - } } - /** Standardized command line interface for Scala entry point */ trait GeneratorApp extends App with HasGeneratorUtilities { lazy val names: ParsedInputNames = { @@ -95,11 +86,10 @@ trait GeneratorApp extends App with HasGeneratorUtilities { } // Canonical ways of building various JVM elaboration-time structures - lazy val td = names.targetDir - lazy val config = getConfig(names) - lazy val world = config.toInstance - lazy val params = Parameters.root(world) - lazy val circuit = elaborate(names, params) + lazy val td: String = names.targetDir + lazy val config: Config = getConfig(names.fullConfigClasses) + lazy val params: Parameters = config.toInstance + lazy val circuit: Circuit = elaborate(names.fullTopModuleClass, params) val longName: String // Exhaustive name used to interface with external build tool targets @@ -137,6 +127,14 @@ trait GeneratorApp extends App with HasGeneratorUtilities { writeOutputFile(td, s"${names.configs}.${extension}", contents ()) } } + + def writeOutputFile(targetDir: String, fname: String, contents: String): File = { + val f = new File(targetDir, fname) + val fw = new FileWriter(f) + fw.write(contents) + fw.close + f + } } object ElaborationArtefacts {