progs/compile.scala
changeset 668 9ce78065f68d
parent 625 6709fa87410b
child 674 e0a41a1f24cf
equal deleted inserted replaced
667:412556272333 668:9ce78065f68d
   118     def l(args: Any*): String = sc.s(args:_*) ++ ":\n"
   118     def l(args: Any*): String = sc.s(args:_*) ++ ":\n"
   119 }
   119 }
   120 
   120 
   121 
   121 
   122 // environments 
   122 // environments 
   123 type Env = Map[String, String]
   123 type Env = Map[String, Int]
   124 
   124 
   125 // arithmetic expression compilation
   125 // arithmetic expression compilation
   126 def compile_aexp(a: AExp, env : Env) : String = a match {
   126 def compile_aexp(a: AExp, env : Env) : String = a match {
   127   case Num(i) => i"ldc $i"
   127   case Num(i) => i"ldc $i"
   128   case Var(s) => i"iload ${env(s)}"
   128   case Var(s) => i"iload ${env(s)}"
   148 
   148 
   149 // statement compilation
   149 // statement compilation
   150 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match {
   150 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match {
   151   case Skip => ("", env)
   151   case Skip => ("", env)
   152   case Assign(x, a) => {
   152   case Assign(x, a) => {
   153     val index = if (env.isDefinedAt(x)) env(x) else 
   153     val index = if (env.isDefinedAt(x)) env(x) else env.keys.size
   154                     env.keys.size.toString
       
   155     (compile_aexp(a, env) ++ i"istore $index", env + (x -> index))
   154     (compile_aexp(a, env) ++ i"istore $index", env + (x -> index))
   156   } 
   155   } 
   157   case If(b, bl1, bl2) => {
   156   case If(b, bl1, bl2) => {
   158     val if_else = Fresh("If_else")
   157     val if_else = Fresh("If_else")
   159     val if_end = Fresh("If_end")
   158     val if_end = Fresh("If_end")
   178   }
   177   }
   179   case Write(x) => 
   178   case Write(x) => 
   180     (i"iload ${env(x)}" ++ 
   179     (i"iload ${env(x)}" ++ 
   181      i"invokestatic XXX/XXX/write(I)V", env)
   180      i"invokestatic XXX/XXX/write(I)V", env)
   182   case Read(x) => {
   181   case Read(x) => {
   183     val index = if (env.isDefinedAt(x)) env(x) else 
   182     val index = if (env.isDefinedAt(x)) env(x) else env.keys.size
   184                     env.keys.size.toString
       
   185     (i"invokestatic XXX/XXX/read()I" ++ 
   183     (i"invokestatic XXX/XXX/read()I" ++ 
   186      i"istore $index", env + (x -> index))
   184      i"istore $index", env + (x -> index))
   187   }
   185   }
   188 }
   186 }
   189 
   187