429 compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpge " + jmp + "\n") |
421 compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpge " + jmp + "\n") |
430 case Bop("<=", a1, a2) => |
422 case Bop("<=", a1, a2) => |
431 compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpgt " + jmp + "\n") |
423 compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpgt " + jmp + "\n") |
432 } |
424 } |
433 |
425 |
434 |
|
435 def compile_expT(a: Exp, env : Mem, name: String) : Instrs = a match { |
|
436 case Num(i) => List("ldc " + i.toString + "\n") |
|
437 case Var(s) => List("iload " + env(s).toString + "\n") |
|
438 case Aop("+", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("iadd\n") |
|
439 case Aop("-", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("isub\n") |
|
440 case Aop("*", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("imul\n") |
|
441 case Aop("/", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("idiv\n") |
|
442 case Aop("%", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("irem\n") |
|
443 case If(b, a1, a2) => { |
|
444 val if_else = Fresh("If_else") |
|
445 val if_end = Fresh("If_end") |
|
446 compile_bexp(b, env, if_else) ++ |
|
447 compile_expT(a1, env, name) ++ |
|
448 List("goto " + if_end + "\n") ++ |
|
449 List("\n" + if_else + ":\n\n") ++ |
|
450 compile_expT(a2, env, name) ++ |
|
451 List("\n" + if_end + ":\n\n") |
|
452 } |
|
453 case Call(n, args) => if (name == n) { |
|
454 val stores = args.zipWithIndex.map { case (x, y) => "istore " + y.toString + "\n" } |
|
455 args.flatMap(a => compile_expT(a, env, "")) ++ |
|
456 stores.reverse ++ |
|
457 List ("goto " + n + "_Start\n") |
|
458 } else { |
|
459 val is = "I" * args.length |
|
460 args.flatMap(a => compile_expT(a, env, "")) ++ |
|
461 List ("invokestatic XXX/XXX/" + n + "(" + is + ")I\n") |
|
462 } |
|
463 case Sequ(a1, a2) => { |
|
464 compile_expT(a1, env, "") ++ List("pop\n") ++ compile_expT(a2, env, name) |
|
465 } |
|
466 case Write(a1) => { |
|
467 compile_expT(a1, env, "") ++ |
|
468 List("dup\n", |
|
469 "invokestatic XXX/XXX/write(I)V\n") |
|
470 } |
|
471 } |
|
472 |
|
473 def compile_bexpT(b: BExp, env : Mem, jmp: String) : Instrs = b match { |
|
474 case Bop("==", a1, a2) => |
|
475 compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpne " + jmp + "\n") |
|
476 case Bop("!=", a1, a2) => |
|
477 compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpeq " + jmp + "\n") |
|
478 case Bop("<", a1, a2) => |
|
479 compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpge " + jmp + "\n") |
|
480 case Bop("<=", a1, a2) => |
|
481 compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpgt " + jmp + "\n") |
|
482 } |
|
483 |
|
484 |
|
485 def compile_decl(d: Decl) : Instrs = d match { |
426 def compile_decl(d: Decl) : Instrs = d match { |
486 case Def(name, args, a) => { |
427 case Def(name, args, a) => { |
487 val env = args.zipWithIndex.toMap |
428 val env = args.zipWithIndex.toMap |
488 val is = "I" * args.length |
429 val is = "I" * args.length |
489 List(".method public static " + name + "(" + is + ")I \n", |
430 List(".method public static " + name + "(" + is + ")I \n", |
490 ".limit locals " + args.length.toString + "\n", |
431 ".limit locals " + args.length.toString + "\n", |
491 ".limit stack " + (1 + max_stack_exp(a)).toString + "\n", |
432 ".limit stack " + (1 + max_stack_exp(a)).toString + "\n", |
492 name + "_Start:\n") ++ |
433 name + "_Start:\n") ++ |
493 //compile_exp(a, env) ++ |
434 compile_exp(a, env) ++ |
494 compile_expT(a, env, name) ++ |
|
495 List("ireturn\n", |
435 List("ireturn\n", |
496 ".end method \n\n") |
436 ".end method \n\n") |
497 } |
437 } |
498 case Main(a) => { |
438 case Main(a) => { |
499 val main_begin = |
439 List(".method public static main([Ljava/lang/String;)V\n", |
500 List(".method public static main([Ljava/lang/String;)V\n", |
440 ".limit locals 200\n", |
501 ".limit locals 200\n", |
441 ".limit stack 200\n") ++ |
502 ".limit stack 200\n") |
442 compile_exp(a, Map()) ++ |
503 val main_end = |
443 List("invokestatic XXX/XXX/write(I)V\n", |
504 List("invokestatic XXX/XXX/write(I)V\n", |
444 "return\n", |
505 "return\n", |
445 ".end method\n") |
506 ".end method\n") |
|
507 main_begin ++ compile_exp(a, Map()) ++ main_end |
|
508 } |
446 } |
509 } |
447 } |
510 |
448 |
511 def compile(class_name: String, input: String) : String = { |
449 def compile(class_name: String, input: String) : String = { |
512 val tks = tokenizer(input) |
450 val tks = tokenizer(input) |