equal
  deleted
  inserted
  replaced
  
    
    
     1 // A Small Compiler for a Simple Functional Language  | 
     1 // A Small Compiler for a Simple Functional Language  | 
     2 // (it does not include a parser and lexer)  | 
     2 // (it does not include a parser and lexer)  | 
     3   | 
     3   | 
     4 // Abstract syntax trees  | 
     4 // abstract syntax trees  | 
     5 abstract class Exp  | 
     5 abstract class Exp  | 
     6 abstract class BExp   | 
     6 abstract class BExp   | 
     7 abstract class Decl  | 
     7 abstract class Decl  | 
     8   | 
     8   | 
     9 // function declarations  | 
     9 // functions and declarations  | 
    10 case class Def(name: String, args: List[String], body: Exp) extends Decl  | 
    10 case class Def(name: String, args: List[String], body: Exp) extends Decl  | 
    11 case class Main(e: Exp) extends Decl  | 
    11 case class Main(e: Exp) extends Decl  | 
    12   | 
    12   | 
    13 // expressions  | 
    13 // expressions  | 
    14 case class Call(name: String, args: List[Exp]) extends Exp  | 
    14 case class Call(name: String, args: List[Exp]) extends Exp  | 
    73 // convenient string interpolations for  | 
    73 // convenient string interpolations for  | 
    74 // generating instructions, labels etc  | 
    74 // generating instructions, labels etc  | 
    75 import scala.language.implicitConversions  | 
    75 import scala.language.implicitConversions  | 
    76 import scala.language.reflectiveCalls  | 
    76 import scala.language.reflectiveCalls  | 
    77   | 
    77   | 
         | 
    78 // convenience for code-generation (string interpolations)  | 
    78 implicit def sring_inters(sc: StringContext) = new { | 
    79 implicit def sring_inters(sc: StringContext) = new { | 
    79   def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"  | 
    80   def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"  // instructions  | 
    80   def l(args: Any*): String = sc.s(args:_*) ++ ":\n"  | 
    81   def l(args: Any*): String = sc.s(args:_*) ++ ":\n"          // labels  | 
    81   def m(args: Any*): String = sc.s(args:_*) ++ "\n"  | 
    82   def m(args: Any*): String = sc.s(args:_*) ++ "\n"           // methods  | 
    82 }  | 
    83 }  | 
    83   | 
    84   | 
    84 // variable / index environments  | 
    85 // variable / index environments  | 
    85 type Env = Map[String, Int]  | 
    86 type Env = Map[String, Int]  | 
    86   | 
    87   | 
   128     compile_exp(a1, env) ++ compile_exp(a2, env) ++ i"if_icmpge $jmp"  | 
   129     compile_exp(a1, env) ++ compile_exp(a2, env) ++ i"if_icmpge $jmp"  | 
   129   case Bop("<=", a1, a2) =>  | 
   130   case Bop("<=", a1, a2) =>  | 
   130     compile_exp(a1, env) ++ compile_exp(a2, env) ++ i"if_icmpgt $jmp"  | 
   131     compile_exp(a1, env) ++ compile_exp(a2, env) ++ i"if_icmpgt $jmp"  | 
   131 }  | 
   132 }  | 
   132   | 
   133   | 
   133 // compile function for declarations and main  | 
   134 // compile functions and declarations  | 
   134 def compile_decl(d: Decl) : String = d match { | 
   135 def compile_decl(d: Decl) : String = d match { | 
   135   case Def(name, args, a) => {  | 
   136   case Def(name, args, a) => {  | 
   136     val env = args.zipWithIndex.toMap  | 
   137     val env = args.zipWithIndex.toMap  | 
   137     val is = "I" * args.length  | 
   138     val is = "I" * args.length  | 
   138     m".method public static $name($is)I" ++  | 
   139     m".method public static $name($is)I" ++  | 
   162   | 
   163   | 
   163   | 
   164   | 
   164   | 
   165   | 
   165   | 
   166   | 
   166 // An example program (factorials)  | 
   167 // An example program (factorials)  | 
         | 
   168 //  | 
         | 
   169 // def fact(n) = if n == 0 then 1 else n * fact(n - 1);  | 
         | 
   170 // def facT(n, acc) = if n == 0 then acc else facT(n - 1, n * acc);  | 
         | 
   171 //   | 
         | 
   172 // fact(10) ; facT(15, 1)  | 
         | 
   173 //   | 
         | 
   174   | 
   167   | 
   175   | 
   168 val test_prog =   | 
   176 val test_prog =   | 
   169   List(Def("fact", List("n"), | 
   177   List(Def("fact", List("n"), | 
   170          If(Bop("==",Var("n"),Num(0)), | 
   178          If(Bop("==",Var("n"),Num(0)), | 
   171             Num(1),  | 
   179             Num(1),  |