diff -r 0367aa7c764b -r 217e66d7aeff progs/fun-bare.scala --- a/progs/fun-bare.scala Mon Sep 30 12:27:15 2019 +0100 +++ b/progs/fun-bare.scala Tue Oct 01 00:29:48 2019 +0100 @@ -1,12 +1,12 @@ // A Small Compiler for a Simple Functional Language // (it does not include a parser and lexer) -// Abstract syntax trees +// abstract syntax trees abstract class Exp abstract class BExp abstract class Decl -// function declarations +// functions and declarations case class Def(name: String, args: List[String], body: Exp) extends Decl case class Main(e: Exp) extends Decl @@ -75,10 +75,11 @@ import scala.language.implicitConversions import scala.language.reflectiveCalls +// convenience for code-generation (string interpolations) implicit def sring_inters(sc: StringContext) = new { - def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" - def l(args: Any*): String = sc.s(args:_*) ++ ":\n" - def m(args: Any*): String = sc.s(args:_*) ++ "\n" + def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" // instructions + def l(args: Any*): String = sc.s(args:_*) ++ ":\n" // labels + def m(args: Any*): String = sc.s(args:_*) ++ "\n" // methods } // variable / index environments @@ -130,7 +131,7 @@ compile_exp(a1, env) ++ compile_exp(a2, env) ++ i"if_icmpgt $jmp" } -// compile function for declarations and main +// compile functions and declarations def compile_decl(d: Decl) : String = d match { case Def(name, args, a) => { val env = args.zipWithIndex.toMap @@ -164,6 +165,13 @@ // An example program (factorials) +// +// def fact(n) = if n == 0 then 1 else n * fact(n - 1); +// def facT(n, acc) = if n == 0 then acc else facT(n - 1, n * acc); +// +// fact(10) ; facT(15, 1) +// + val test_prog = List(Def("fact", List("n"),