Main.scala 1.7 KB
Newer Older
Sapphie's avatar
Sapphie committed
1
2
3
4
5
6
7
package l3

import java.io.PrintWriter
import java.nio.file.{ Files, Paths }

import l3.SymbolicCL3TreeModule.Tree

Sapphie's avatar
Sapphie committed
8
9
10
11
import CL3TreeFormatter._ // Implicits required for CL3 tree printing
import CPSTreeFormatter._ // Implicits required for CPS tree printing
import CPSTreeChecker._   // Implicits required for CPS tree checking

Sapphie's avatar
Sapphie committed
12
13
14
object Main {
  def main(args: Array[String]): Unit = {
    val backEnd: Tree => TerminalPhaseResult = (
Sapphie's avatar
Sapphie committed
15
16
17
18
      CL3ToCPSTranslator
        andThen treePrinter("---------- After translation to CPS")
        andThen treeChecker
        andThen CPSInterpreterHigh
Sapphie's avatar
Sapphie committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    )

    val basePath = Paths.get(".").toAbsolutePath
    Either.cond(! args.isEmpty, args.toIndexedSeq, "no input file given")
      .flatMap(L3FileReader.readFilesExpandingModules(basePath, _))
      .flatMap(p => L3Parser.parse(p._1, p._2))
      .flatMap(CL3NameAnalyzer)
      .flatMap(backEnd) match {
      case Right((retCode, maybeMsg)) =>
        maybeMsg foreach println
        sys.exit(retCode)
      case Left(errMsg) =>
        println(s"Error: $errMsg")
        sys.exit(1)
    }
  }

  private lazy val outPrintWriter =
    new PrintWriter(System.out, true)

Sapphie's avatar
Sapphie committed
39
40
41
  private def treeChecker[T <: CPSTreeModule](implicit c: CPSTreeChecker[T]) =
    passThrough(c)

Sapphie's avatar
Sapphie committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  private def treePrinter[T](msg: String)(implicit f: Formatter[T]): T => T =
    passThrough { tree =>
      outPrintWriter.println(msg)
      f.toDoc(tree).writeTo(80, outPrintWriter)
      outPrintWriter.println()
    }

  private def seqPrinter[T](msg: String): Seq[T] => Seq[T] =
    passThrough { program =>
      outPrintWriter.println(msg)
      program foreach outPrintWriter.println
    }

  private def passThrough[T](f: T => Unit): T => T =
    { t: T => f(t); t }
}