progs/while/compile.sc
changeset 961 c0600f8b6427
parent 943 5365ef60707e
child 974 0cb4bf2469d1
equal deleted inserted replaced
960:c7009356ddd8 961:c0600f8b6427
    79 // convenient string interpolations 
    79 // convenient string interpolations 
    80 // for instructions and labels
    80 // for instructions and labels
    81 
    81 
    82 extension (sc: StringContext) {
    82 extension (sc: StringContext) {
    83     def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"
    83     def i(args: Any*): String = "   " ++ sc.s(args:_*) ++ "\n"
    84     def l(args: Any*): String = sc.s(args:_*) ++ ":\n"
    84     def l(args: Any*): String = sc.s(args:_*) ++ ":"
    85 }
    85 }
    86 
    86 
    87 // this allows us to write things like
    87 // this allows us to write things like
    88 // i"iadd" and l"Label"
    88 // i"iadd" and l"Label"
    89 
    89 
   129   case If(b, bl1, bl2) => {
   129   case If(b, bl1, bl2) => {
   130     val if_else = Fresh("If_else")
   130     val if_else = Fresh("If_else")
   131     val if_end = Fresh("If_end")
   131     val if_end = Fresh("If_end")
   132     val (instrs1, env1) = compile_block(bl1, env)
   132     val (instrs1, env1) = compile_block(bl1, env)
   133     val (instrs2, env2) = compile_block(bl2, env1)
   133     val (instrs2, env2) = compile_block(bl2, env1)
   134     (compile_bexp(b, env, if_else) ++
   134     (s"""|${compile_bexp(b, env, if_else)}
   135      instrs1 ++
   135          |${instrs1}
   136      i"goto $if_end" ++
   136          |${i"goto $if_end"}
   137      l"$if_else" ++
   137          |${l"$if_else"}
   138      instrs2 ++
   138          |${instrs2}
   139      l"$if_end", env2)
   139          |${l"$if_end"}""".stripMargin, env2)
   140   }
   140   }
   141   case While(b, bl) => {
   141   case While(b, bl) => {
   142     val loop_begin = Fresh("Loop_begin")
   142     val loop_begin = Fresh("Loop_begin")
   143     val loop_end = Fresh("Loop_end")
   143     val loop_end = Fresh("Loop_end")
   144     val (instrs1, env1) = compile_block(bl, env)
   144     val (instrs1, env1) = compile_block(bl, env)
   145     (l"$loop_begin" ++
   145     (s"""|${l"$loop_begin"}
   146      compile_bexp(b, env, loop_end) ++
   146          |${compile_bexp(b, env, loop_end)}
   147      instrs1 ++
   147          |$instrs1
   148      i"goto $loop_begin" ++
   148          |${i"goto $loop_begin"}
   149      l"$loop_end", env1)
   149          |${l"$loop_end"}""".stripMargin, env1)
   150   }
   150   }
   151   case Write(x) => 
   151   case Write(x) => 
   152     (i"iload ${env(x)} \t\t; $x" ++ 
   152     (i"iload ${env(x)} \t\t; $x" ++ 
   153      i"invokestatic XXX/XXX/write(I)V", env)
   153      i"invokestatic XXX/XXX/write(I)V", env)
   154 }
   154 }
   164 }
   164 }
   165 
   165 
   166 // main compilation function for blocks
   166 // main compilation function for blocks
   167 def compile(bl: Block, class_name: String) : String = {
   167 def compile(bl: Block, class_name: String) : String = {
   168   val instructions = compile_block(bl, Map.empty)._1
   168   val instructions = compile_block(bl, Map.empty)._1
   169   (beginning ++ instructions ++ ending).replaceAllLiterally("XXX", class_name)
   169   (beginning ++ instructions ++ ending).replace("XXX", class_name)
   170 }
   170 }
   171 
   171 
   172 
   172 
   173 
   173 
   174 
   174