progs/fun/fun_llvm.sc
changeset 958 fddf099a82f8
parent 905 15973df32613
child 959 64ec1884d860
equal deleted inserted replaced
957:34b3aeb65fbe 958:fddf099a82f8
    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 {
   110 }   
   139 }   
   111 
   140 
   112 //initial continuation
   141 //initial continuation
   113 def CPSi(e: Exp) = CPS(e)(KReturn)
   142 def CPSi(e: Exp) = CPS(e)(KReturn)
   114 
   143 
       
   144 
       
   145 
   115 //some testcases:
   146 //some testcases:
   116 // (1 + 2) * 3
   147 // (1 + 2) * 3
   117 println(CPSi(Aop("*", Aop("+", Num(1), Num(2)), Num(3))).toString)
   148 println(CPSi(Aop("*", Aop("+", Num(1), Num(2)), Num(3))).toString)
   118 
   149 
   119 // 3 * (1 + 2)
   150 // 3 * (1 + 2)
   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))