progs/compile.scala
changeset 369 43c0ed473720
parent 323 4ce07c4abdb4
child 373 b018234c9126
equal deleted inserted replaced
368:a9911966c0df 369:43c0ed473720
   109 
   109 
   110 // arithmetic expression compilation
   110 // arithmetic expression compilation
   111 def compile_aexp(a: AExp, env : Env) : Instrs = a match {
   111 def compile_aexp(a: AExp, env : Env) : Instrs = a match {
   112   case Num(i) => List("ldc " + i.toString + "\n")
   112   case Num(i) => List("ldc " + i.toString + "\n")
   113   case Var(s) => List("iload " + env(s) + "\n")
   113   case Var(s) => List("iload " + env(s) + "\n")
   114   case Aop("+", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("iadd\n")
   114   case Aop("+", a1, a2) => 
   115   case Aop("-", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n")
   115     compile_aexp(a1, env) ++ 
   116   case Aop("*", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n")
   116     compile_aexp(a2, env) ++ List("iadd\n")
       
   117   case Aop("-", a1, a2) => 
       
   118     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n")
       
   119   case Aop("*", a1, a2) => 
       
   120     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n")
   117 }
   121 }
   118 
   122 
   119 // boolean expression compilation
   123 // boolean expression compilation
   120 def compile_bexp(b: BExp, env : Env, jmp: String) : Instrs = b match {
   124 def compile_bexp(b: BExp, env : Env, jmp: String) : Instrs = b match {
   121   case True => Nil
   125   case True => Nil
   122   case False => List("goto " + jmp + "\n")
   126   case False => List("goto " + jmp + "\n")
   123   case Bop("=", a1, a2) => 
   127   case Bop("=", a1, a2) => 
   124     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpne " + jmp + "\n")
   128     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ 
       
   129     List("if_icmpne " + jmp + "\n")
   125   case Bop("!=", a1, a2) => 
   130   case Bop("!=", a1, a2) => 
   126     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpeq " + jmp + "\n")
   131     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ 
       
   132     List("if_icmpeq " + jmp + "\n")
   127   case Bop("<", a1, a2) => 
   133   case Bop("<", a1, a2) => 
   128     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpge " + jmp + "\n")
   134     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ 
       
   135     List("if_icmpge " + jmp + "\n")
   129 }
   136 }
   130 
   137 
   131 // statement compilation
   138 // statement compilation
   132 def compile_stmt(s: Stmt, env: Env) : (Instrs, Env) = s match {
   139 def compile_stmt(s: Stmt, env: Env) : (Instrs, Env) = s match {
   133   case Skip => (Nil, env)
   140   case Skip => (Nil, env)
   134   case Assign(x, a) => {
   141   case Assign(x, a) => {
   135     val index = if (env.isDefinedAt(x)) env(x) else env.keys.size.toString
   142     val index = if (env.isDefinedAt(x)) env(x) else 
       
   143                     env.keys.size.toString
   136     (compile_aexp(a, env) ++ 
   144     (compile_aexp(a, env) ++ 
   137      List("istore " + index + "\n"), env + (x -> index))
   145      List("istore " + index + "\n"), env + (x -> index))
   138   } 
   146   } 
   139   case If(b, bl1, bl2) => {
   147   case If(b, bl1, bl2) => {
   140     val if_else = Fresh("If_else")
   148     val if_else = Fresh("If_else")
   157      instrs1 ++
   165      instrs1 ++
   158      List("goto " + loop_begin + "\n") ++
   166      List("goto " + loop_begin + "\n") ++
   159      List("\n" + loop_end + ":\n\n"), env1)
   167      List("\n" + loop_end + ":\n\n"), env1)
   160   }
   168   }
   161   case Write(x) => 
   169   case Write(x) => 
   162     (List("iload " + env(x) + "\n" + "invokestatic XXX/XXX/write(I)V\n"), env)
   170     (List("iload " + env(x) + "\n" + 
       
   171            "invokestatic XXX/XXX/write(I)V\n"), env)
   163   case Read(x) => {
   172   case Read(x) => {
   164     val index = if (env.isDefinedAt(x)) env(x) else env.keys.size.toString
   173     val index = if (env.isDefinedAt(x)) env(x) else 
       
   174                     env.keys.size.toString
   165     (List("invokestatic XXX/XXX/read()I\n" + 
   175     (List("invokestatic XXX/XXX/read()I\n" + 
   166           "istore " + index + "\n"), env + (x -> index))
   176           "istore " + index + "\n"), env + (x -> index))
   167   }
   177   }
   168 }
   178 }
   169 
   179 
   189   List(Read("n"),                       //  read n;                     
   199   List(Read("n"),                       //  read n;                     
   190        Assign("minus1",Num(0)),         //  minus1 := 0;
   200        Assign("minus1",Num(0)),         //  minus1 := 0;
   191        Assign("minus2",Num(1)),         //  minus2 := 1;
   201        Assign("minus2",Num(1)),         //  minus2 := 1;
   192        Assign("temp",Num(0)),           //  temp := 0;
   202        Assign("temp",Num(0)),           //  temp := 0;
   193        While(Bop("<",Num(0),Var("n")),  //  while n > 0 do  {
   203        While(Bop("<",Num(0),Var("n")),  //  while n > 0 do  {
   194           List(Assign("temp",Var("minus2")),                          //  temp := minus2;
   204           List(Assign("temp",Var("minus2")),    //  temp := minus2;
   195                Assign("minus2",Aop("+",Var("minus1"),Var("minus2"))), //  minus2 := minus1 + minus2;
   205                Assign("minus2",Aop("+",Var("minus1"),Var("minus2"))), 
   196                Assign("minus1",Var("temp")),                          //  minus1 := temp;
   206                                         //  minus2 := minus1 + minus2;
   197                Assign("n",Aop("-",Var("n"),Num(1))))),                //  n := n - 1 };
   207                Assign("minus1",Var("temp")), //  minus1 := temp;
       
   208                Assign("n",Aop("-",Var("n"),Num(1))))), //  n := n - 1 };
   198        Write("minus1"))                 //  write minus1
   209        Write("minus1"))                 //  write minus1
   199 
   210 
   200 
   211 
   201 
   212 
   202 // prints out the JVM-assembly program
   213 // prints out the JVM-assembly program