equal
  deleted
  inserted
  replaced
  
    
    
     1 // A Small Compiler for the WHILE Language  | 
     1 // A Small Compiler for the WHILE Language  | 
     2 // (it does not use a parser and lexer)  | 
     2 // (stub for including arrays)  | 
     3   | 
     3   | 
     4 // the abstract syntax trees  | 
     4 // the abstract syntax trees  | 
     5 abstract class Stmt  | 
     5 abstract class Stmt  | 
     6 abstract class AExp  | 
     6 abstract class AExp  | 
     7 abstract class BExp   | 
     7 abstract class BExp   | 
    10 // statements  | 
    10 // statements  | 
    11 case object Skip extends Stmt  | 
    11 case object Skip extends Stmt  | 
    12 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt  | 
    12 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt  | 
    13 case class While(b: BExp, bl: Block) extends Stmt  | 
    13 case class While(b: BExp, bl: Block) extends Stmt  | 
    14 case class Assign(s: String, a: AExp) extends Stmt  | 
    14 case class Assign(s: String, a: AExp) extends Stmt  | 
    15 case class Write(s: String) extends Stmt  | 
    15 case class Write(s: String) extends Stmt  // writes out a variable  | 
    16 case class Read(s: String) extends Stmt  | 
         | 
    17   | 
    16   | 
    18 // arithmetic expressions  | 
    17 // arithmetic expressions  | 
    19 case class Var(s: String) extends AExp  | 
    18 case class Var(s: String) extends AExp  | 
    20 case class Num(i: Int) extends AExp  | 
    19 case class Num(i: Int) extends AExp  | 
    21 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp  | 
    20 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp  | 
    43     .limit stack 2   | 
    42     .limit stack 2   | 
    44     getstatic java/lang/System/out Ljava/io/PrintStream;   | 
    43     getstatic java/lang/System/out Ljava/io/PrintStream;   | 
    45     iload 0  | 
    44     iload 0  | 
    46     invokevirtual java/io/PrintStream/println(I)V   | 
    45     invokevirtual java/io/PrintStream/println(I)V   | 
    47     return   | 
    46     return   | 
    48 .end method  | 
         | 
    49   | 
         | 
    50 .method public static read()I   | 
         | 
    51     .limit locals 10   | 
         | 
    52     .limit stack 10  | 
         | 
    53   | 
         | 
    54     ldc 0   | 
         | 
    55     istore 1  ; this will hold our final integer   | 
         | 
    56 Label1:   | 
         | 
    57     getstatic java/lang/System/in Ljava/io/InputStream;   | 
         | 
    58     invokevirtual java/io/InputStream/read()I   | 
         | 
    59     istore 2   | 
         | 
    60     iload 2   | 
         | 
    61     ldc 10   ; the newline delimiter   | 
         | 
    62     isub   | 
         | 
    63     ifeq Label2   | 
         | 
    64     iload 2   | 
         | 
    65     ldc 32   ; the space delimiter   | 
         | 
    66     isub   | 
         | 
    67     ifeq Label2  | 
         | 
    68   | 
         | 
    69     iload 2   | 
         | 
    70     ldc 48   ; we have our digit in ASCII, have to subtract it from 48   | 
         | 
    71     isub   | 
         | 
    72     ldc 10   | 
         | 
    73     iload 1   | 
         | 
    74     imul   | 
         | 
    75     iadd   | 
         | 
    76     istore 1   | 
         | 
    77     goto Label1   | 
         | 
    78 Label2:   | 
         | 
    79     ;when we come here we have our integer computed in local variable 1   | 
         | 
    80     iload 1   | 
         | 
    81     ireturn   | 
         | 
    82 .end method  | 
    47 .end method  | 
    83   | 
    48   | 
    84 .method public static main([Ljava/lang/String;)V  | 
    49 .method public static main([Ljava/lang/String;)V  | 
    85    .limit locals 200  | 
    50    .limit locals 200  | 
    86    .limit stack 200  | 
    51    .limit stack 200  | 
   169      List("\n" + loop_end + ":\n\n"), env1) | 
   134      List("\n" + loop_end + ":\n\n"), env1) | 
   170   }  | 
   135   }  | 
   171   case Write(x) =>   | 
   136   case Write(x) =>   | 
   172     (List("iload " + env(x) + "\n" +  | 
   137     (List("iload " + env(x) + "\n" +  | 
   173            "invokestatic XXX/XXX/write(I)V\n"), env)  | 
   138            "invokestatic XXX/XXX/write(I)V\n"), env)  | 
   174   case Read(x) => { | 
         | 
   175     val index = if (env.isDefinedAt(x)) env(x) else   | 
         | 
   176                     env.keys.size.toString  | 
         | 
   177     (List("invokestatic XXX/XXX/read()I\n" +  | 
         | 
   178           "istore " + index + "\n"), env + (x -> index))  | 
         | 
   179   }  | 
         | 
   180 }  | 
   139 }  | 
   181   | 
   140   | 
   182 // compilation of a block (i.e. list of instructions)  | 
   141 // compilation of a block (i.e. list of instructions)  | 
   183 def compile_block(bl: Block, env: Env) : (Instrs, Env) = bl match { | 
   142 def compile_block(bl: Block, env: Env) : (Instrs, Env) = bl match { | 
   184   case Nil => (Nil, env)  | 
   143   case Nil => (Nil, env)  | 
   257   | 
   216   | 
   258   | 
   217   | 
   259 compile_run(fib_test, "fib")  | 
   218 compile_run(fib_test, "fib")  | 
   260   | 
   219   | 
   261   | 
   220   | 
         | 
   221   | 
         | 
   222 val arr_test =   | 
         | 
   223   List(Array("a", 10), | 
         | 
   224        Array("b", 2), | 
         | 
   225        AssignA("a", Num(0), Num(10)), | 
         | 
   226        Assign("x", Ref("a", Num(0))), | 
         | 
   227        Write("x"), | 
         | 
   228        AssignA("b", Num(1), Num(5)), | 
         | 
   229        Assign("x", Ref("b", Num(1))), | 
         | 
   230        Write("x"))        | 
         | 
   231   | 
         | 
   232 //compile_run(arr_test, "a")  |