package amyc import ast._ import utils._ import parsing._ import analyzer._ import java.io.File object Main extends MainHelpers { private def parseArgs(args: Array[String]): Context = { var ctx = Context(new Reporter, Nil) args foreach { case "--printTokens" => ctx = ctx.copy(printTokens = true) case "--printTrees" => ctx = ctx.copy(printTrees = true) case "--printNames" => ctx = ctx.copy(printNames = true) case "--interpret" => ctx = ctx.copy(interpret = true) case "--type-check" => ctx = ctx.copy(typeCheck = true) case "--help" => ctx = ctx.copy(help = true) case file => ctx = ctx.copy(files = ctx.files :+ file) } ctx } def main(args: Array[String]): Unit = { val ctx = parseArgs(args) if (ctx.help) { val helpMsg = { """Welcome to the Amy reference compiler, v.1.5 | |Default behavior is to compile the program to WebAssembly and print the following files: |(1) the resulting code in WebAssembly text format (.wat), |(2) the resulting code in WebAssembly binary format (.wasm), |(3) a wrapper JavaScript file, to be run by nodejs (.js) and |(4) a wrapper html file publishable by a web server (.html) | |Options: | --printTokens Print lexer tokens (with positions) after lexing and exit | --printTrees Print trees after parsing and exit | --printNames Print trees with unique namas after name analyzer and exit | --type-check Type-check the program and print trees | --help Print this message """.stripMargin } println(helpMsg) sys.exit(0) } val pipeline = AmyLexer.andThen( if (ctx.printTokens) DisplayTokens else Parser.andThen( if (ctx.printTrees) treePrinterN("Trees after parsing") else NameAnalyzer.andThen( if (ctx.printNames) treePrinterS("Trees after name analysis") else TypeChecker.andThen( treePrinterS("Trees after type checking"))))) val files = ctx.files.map(new File(_)) try { if (files.isEmpty) { ctx.reporter.fatal("No input files") } if (ctx.interpret) { ctx.reporter.fatal("Unsupported actions for now") } files.find(!_.exists()).foreach { f => ctx.reporter.fatal(s"File not found: ${f.getName}") } pipeline.run(ctx)(files) ctx.reporter.terminateIfErrors() } catch { case AmycFatalError(_) => sys.exit(1) } } } trait MainHelpers { import SymbolicTreeModule.{Program => SP} import NominalTreeModule.{Program => NP} def treePrinterS(title: String): Pipeline[(SP, SymbolTable), Unit] = { new Pipeline[(SP, SymbolTable), Unit] { def run(ctx: Context)(v: (SP, SymbolTable)) = { println(title) println(SymbolicPrinter(v._1)(true)) } } } def treePrinterN(title: String): Pipeline[NP, Unit] = { new Pipeline[NP, Unit] { def run(ctx: Context)(v: NP) = { println(title) println(NominalPrinter(v)) } } } }