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), |