progs/compile-lexer.scala
changeset 227 93bd75031ced
parent 219 599e6a6ab6c6
child 323 4ce07c4abdb4
equal deleted inserted replaced
226:e3c454e31224 227:93bd75031ced
   122 val WHITESPACE = PLUS(" " | "\n" | "\t")
   122 val WHITESPACE = PLUS(" " | "\n" | "\t")
   123 val RPAREN: Rexp = ")"
   123 val RPAREN: Rexp = ")"
   124 val LPAREN: Rexp = "("
   124 val LPAREN: Rexp = "("
   125 val BEGIN: Rexp = "{"
   125 val BEGIN: Rexp = "{"
   126 val END: Rexp = "}"
   126 val END: Rexp = "}"
   127 val ALL = SYM | DIGIT | " " | ":" | ";" | "\"" | "="
   127 val ALL = SYM | DIGIT | OP | " " | ":" | ";" | "\"" | "(" | ")" | "{" | "}" 
   128 val ALL2 = ALL | "\n"
   128 val ALL2 = ALL | "\n"
   129 val COMMENT2 = ("/*" ~ NOT(ALL.% ~ "*/" ~ ALL.%) ~ "*/")
   129 val COMMENT2 = ("/*" ~ NOT(ALL.% ~ "*/" ~ ALL.%) ~ "*/")
   130 val COMMENT = ("/*" ~ ALL2.% ~ "*/") | ("//" ~ ALL.% ~ "\n")
   130 val COMMENT = ("/*" ~ ALL2.% ~ "*/") | ("//" ~ ALL.% ~ "\n")
   131 val STRING = "\"" ~ ALL.% ~ "\""
   131 val STRING = "\"" ~ ALL.% ~ "\""
   132 
   132 
   565   case Num(i) => List("ldc " + i.toString + "\n")
   565   case Num(i) => List("ldc " + i.toString + "\n")
   566   case Var(s) => List("iload " + env(s) + "\n")
   566   case Var(s) => List("iload " + env(s) + "\n")
   567   case Aop("+", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("iadd\n")
   567   case Aop("+", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("iadd\n")
   568   case Aop("-", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n")
   568   case Aop("-", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n")
   569   case Aop("*", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n")
   569   case Aop("*", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n")
       
   570   case Aop("/", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("idiv\n")
       
   571   case Aop("%", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("irem\n") 
   570 }
   572 }
   571 
   573 
   572 def compile_bexp(b: BExp, env : Mem, jmp: String) : Instrs = b match {
   574 def compile_bexp(b: BExp, env : Mem, jmp: String) : Instrs = b match {
   573   case True => Nil
   575   case True => Nil
   574   case False => List("goto " + jmp + "\n")
   576   case False => List("goto " + jmp + "\n")
   575   case Bop("=", a1, a2) => 
   577   case Bop("==", a1, a2) => 
   576     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpne " + jmp + "\n")
   578     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpne " + jmp + "\n")
   577   case Bop("!=", a1, a2) => 
   579   case Bop("!=", a1, a2) => 
   578     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpeq " + jmp + "\n")
   580     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpeq " + jmp + "\n")
   579   case Bop("<", a1, a2) => 
   581   case Bop("<", a1, a2) => 
   580     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpge " + jmp + "\n")
   582     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpge " + jmp + "\n")
   633   }
   635   }
   634 }
   636 }
   635 
   637 
   636 def compile(class_name: String, input: String) : String = {
   638 def compile(class_name: String, input: String) : String = {
   637   val tks = tokenizer(input)
   639   val tks = tokenizer(input)
       
   640   println("Output\n" + Stmts.parse(tks))
   638   val ast = Stmts.parse_single(tks)
   641   val ast = Stmts.parse_single(tks)
   639   val instructions = compile_bl(ast, Map.empty)._1
   642   val instructions = compile_bl(ast, Map.empty)._1
   640   (beginning ++ instructions.mkString ++ ending).replaceAllLiterally("XXX", class_name)
   643   (beginning ++ instructions.mkString ++ ending).replaceAllLiterally("XXX", class_name)
   641 }
   644 }
   642 
   645 
   659 
   662 
   660 def compile_run(file_name: String) : Unit = {
   663 def compile_run(file_name: String) : Unit = {
   661   val class_name = file_name.split('.')(0)
   664   val class_name = file_name.split('.')(0)
   662   compile_file(file_name)
   665   compile_file(file_name)
   663   val test = ("java -jar jvm/jasmin-2.4/jasmin.jar " + class_name + ".j").!!
   666   val test = ("java -jar jvm/jasmin-2.4/jasmin.jar " + class_name + ".j").!!
   664   //("java " + class_name + "/" + class_name).!
   667   ("java " + class_name + "/" + class_name).!
   665 }
   668 }
   666 
   669 
   667 
   670 
   668 //examples
   671 //examples
   669 //println(compile("test", p9))
   672 //println(compile("test", p9))
   670 //compile_run("loops.while")
   673 //compile_run("loops.while")
   671 compile_run("fib.while")
   674 compile_run("p.while")
   672 //compile_run("test.while")
   675 //compile_run("test.while")