progs/while/compile.sc
changeset 943 5365ef60707e
parent 828 bdcaecdee9eb
child 961 c0600f8b6427
equal deleted inserted replaced
942:c82a45f48bfc 943:5365ef60707e
     1 // A Small Compiler for the WHILE Language
     1 // A Small Compiler for the WHILE Language
     2 // (it does not use a parser nor lexer)
     2 // (it does not use a parser nor lexer)
     3 //
     3 //
     4 // cal with 
     4 // call with 
     5 //
     5 //
     6 //   amm compile.sc test
     6 //   amm compile.sc test
     7 //   amm compile.sc test2
     7 //   amm compile.sc test2
     8 
     8 //
       
     9 // test2 includes a run of the JVM instructions. This
       
    10 // requires that jasmin.jar is present in the same 
       
    11 // directory.
     9 
    12 
    10 // the abstract syntax trees
    13 // the abstract syntax trees
    11 abstract class Stmt
    14 abstract class Stmt
    12 abstract class AExp
    15 abstract class AExp
    13 abstract class BExp 
    16 abstract class BExp 
    31 case object False extends BExp
    34 case object False extends BExp
    32 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp
    35 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp
    33 
    36 
    34 
    37 
    35 // compiler headers needed for the JVM
    38 // compiler headers needed for the JVM
    36 // (contains methods for read and write)
    39 // (contains a method for write)
    37 val beginning = """
    40 val beginning = """
    38 .class public XXX.XXX
    41 .class public XXX.XXX
    39 .super java/lang/Object
    42 .super java/lang/Object
    40 
    43 
    41 .method public static write(I)V 
    44 .method public static write(I)V 
    73   x ++ "_" ++ counter.toString()
    76   x ++ "_" ++ counter.toString()
    74 }
    77 }
    75 
    78 
    76 // convenient string interpolations 
    79 // convenient string interpolations 
    77 // for instructions and labels
    80 // for instructions and labels
    78 import scala.language.implicitConversions
    81 
    79 import scala.language.reflectiveCalls
    82 extension (sc: StringContext) {
    80 
       
    81 implicit def sring_inters(sc: StringContext) = new {
       
    82     def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"
    83     def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"
    83     def l(args: Any*): String = sc.s(args:_*) ++ ":\n"
    84     def l(args: Any*): String = sc.s(args:_*) ++ ":\n"
    84 }
    85 }
    85 
    86 
    86 // this allows us to write things like
    87 // this allows us to write things like
   148      l"$loop_end", env1)
   149      l"$loop_end", env1)
   149   }
   150   }
   150   case Write(x) => 
   151   case Write(x) => 
   151     (i"iload ${env(x)} \t\t; $x" ++ 
   152     (i"iload ${env(x)} \t\t; $x" ++ 
   152      i"invokestatic XXX/XXX/write(I)V", env)
   153      i"invokestatic XXX/XXX/write(I)V", env)
   153   //case Read(x) => {
       
   154   //  val index = env.getOrElse(x, env.keys.size) 
       
   155   //  (i"invokestatic XXX/XXX/read()I" ++ 
       
   156   //   i"istore $index \t\t; $x", env + (x -> index))
       
   157   //}
       
   158 }
   154 }
   159 
   155 
   160 // compilation of a block (i.e. list of instructions)
   156 // compilation of a block (i.e. list of instructions)
   161 def compile_block(bl: Block, env: Env) : (String, Env) = bl match {
   157 def compile_block(bl: Block, env: Env) : (String, Env) = bl match {
   162   case Nil => ("", env)
   158   case Nil => ("", env)
   198 def test() = 
   194 def test() = 
   199   println(compile(fib_test, "fib"))
   195   println(compile(fib_test, "fib"))
   200 
   196 
   201 
   197 
   202 
   198 
   203 
       
   204 
       
   205 // compiling and running .j-files
   199 // compiling and running .j-files
   206 //
   200 //
   207 // JVM files can be assembled with 
   201 // JVM files can be assembled with 
   208 //
   202 //
   209 //    java -jar jasmin.jar fib.j
   203 //    java -jar jasmin.jar fib.j
   216 def run(bl: Block, class_name: String) = {
   210 def run(bl: Block, class_name: String) = {
   217     val code = compile(bl, class_name)
   211     val code = compile(bl, class_name)
   218     os.write.over(os.pwd / s"$class_name.j", code)
   212     os.write.over(os.pwd / s"$class_name.j", code)
   219     os.proc("java", "-jar", "jasmin.jar", s"$class_name.j").call()
   213     os.proc("java", "-jar", "jasmin.jar", s"$class_name.j").call()
   220     os.proc("java", s"$class_name/$class_name").call(stdout = os.Inherit, stdin = os.Inherit)
   214     os.proc("java", s"$class_name/$class_name").call(stdout = os.Inherit, stdin = os.Inherit)
       
   215     ()
   221 }
   216 }
   222 
   217 
   223 
   218 
   224 @main
   219 @main
   225 def test2() =
   220 def test2() =
   264 
   259 
   265 */
   260 */
   266 
   261 
   267 
   262 
   268 
   263 
   269 
       
   270 
       
   271 // runs with amm2 and amm3