71 |
71 |
72 override def toString = |
72 override def toString = |
73 s"IF $x1\nTHEN\n${pad(e1)}\nELSE\n${pad(e2)}" |
73 s"IF $x1\nTHEN\n${pad(e1)}\nELSE\n${pad(e2)}" |
74 } |
74 } |
75 case class KReturn(v: KVal) extends KExp |
75 case class KReturn(v: KVal) extends KExp |
|
76 |
|
77 // some functions for drawing KVal-trees |
|
78 // inspired by William Bradford Larcombe |
|
79 |
|
80 def draw_vals(vs: List[KVal], prefix: String) : String = { |
|
81 val vsi = vs.iterator |
|
82 vsi.map(v => draw_val(v, prefix, vsi.hasNext)).mkString |
|
83 } |
|
84 |
|
85 def draw_val(k: KVal, prefix: String, more: Boolean) : String = { |
|
86 val full_prefix = s"$prefix${if more then "├" else "└"}" |
|
87 val childPrefix = s"$prefix${if more then "│" else ""} " |
|
88 s"\n${full_prefix}" ++ |
|
89 (k match { |
|
90 case KVar(x) => x |
|
91 case KNum(n) => n.toString |
|
92 case Kop(op, v1 , v2) => s"KOp($op) ${draw_vals(List(v1, v2), childPrefix)}" |
|
93 case KCall(nme, as) => s"KCall($nme) ${draw_vals(as, childPrefix)}" |
|
94 case KWrite(v) => s"KWrite ${draw_val(v, childPrefix, false)}" |
|
95 }) |
|
96 } |
|
97 |
|
98 def draw(k: KVal) = "│" ++ draw_val(k, "", false) |
|
99 |
|
100 // val k1 = KVar("foo") |
|
101 // val k2 = KNum(1) |
|
102 // val k3 = Kop("-", Kop("+", k1, k2), KNum(2)) |
|
103 // println(draw(k3).mkString) |
|
104 // println(draw(KCall("bar", List(k1,k2,k3,k2,k1))).mkString) |
76 |
105 |
77 |
106 |
78 // CPS translation from Exps to KExps using a |
107 // CPS translation from Exps to KExps using a |
79 // continuation k. |
108 // continuation k. |
80 def CPS(e: Exp)(k: KVal => KExp) : KExp = e match { |
109 def CPS(e: Exp)(k: KVal => KExp) : KExp = e match { |
182 println(CPSi(e10).toString) |
213 println(CPSi(e10).toString) |
183 |
214 |
184 |
215 |
185 |
216 |
186 |
217 |
187 |
|
188 // convenient string interpolations |
218 // convenient string interpolations |
189 // for instructions, labels and methods |
219 // for instructions, labels and methods |
190 import scala.language.implicitConversions |
220 import scala.language.implicitConversions |
191 import scala.language.reflectiveCalls |
221 import scala.language.reflectiveCalls |
192 |
222 |
193 implicit def sring_inters(sc: StringContext) = new { |
223 extension (sc: StringContext) { |
194 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
224 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
195 def l(args: Any*): String = sc.s(args:_*) ++ ":\n" |
225 def l(args: Any*): String = sc.s(args:_*) ++ ":\n" |
196 def m(args: Any*): String = sc.s(args:_*) ++ "\n" |
226 def m(args: Any*): String = sc.s(args:_*) ++ "\n" |
197 } |
227 } |
198 |
228 |
269 |
299 |
270 // main compiler functions |
300 // main compiler functions |
271 def compile(prog: List[Decl]) : String = |
301 def compile(prog: List[Decl]) : String = |
272 prelude ++ (prog.map(compile_decl).mkString) |
302 prelude ++ (prog.map(compile_decl).mkString) |
273 |
303 |
274 |
|
275 // pre-2.5.0 ammonite |
|
276 // import ammonite.ops._ |
|
277 |
|
278 // post 2.5.0 ammonite |
|
279 // import os._ |
|
280 |
|
281 |
|
282 @main |
304 @main |
283 def main(fname: String) = { |
305 def main(fname: String) = { |
284 val path = os.pwd / fname |
306 val path = os.pwd / fname |
285 val file = fname.stripSuffix("." ++ path.ext) |
307 val file = fname.stripSuffix("." ++ path.ext) |
286 val tks = tokenise(os.read(path)) |
308 val tks = tokenise(os.read(path)) |