diff -r c112a6cb5e52 -r 183663740fb7 progs/compile_arr.scala --- a/progs/compile_arr.scala Tue Jan 28 12:23:53 2020 +0000 +++ b/progs/compile_arr.scala Mon Feb 03 01:10:16 2020 +0000 @@ -8,9 +8,13 @@ // // Call with // -// scala compiler_arr.scala +// scala compile_arr.scala +// Mandelbrot +// mand.j size 236241 +// mand.class size 33296 +// running time 21 secs // the abstract syntax trees abstract class Stmt @@ -101,49 +105,34 @@ case "*" => i"imul" } -def compile_num(i: Int) = - if (0 <= i && i <= 5) i"iconst_$i" else i"ldc $i" - -def compile_aload(i: Int) = - if (0 <= i && i <= 3) i"aload_$i" else i"aload $i" - -def compile_iload(i: Int) = - if (0 <= i && i <= 3) i"iload_$i" else i"iload $i" - -def compile_istore(i: Int) = - if (0 <= i && i <= 3) i"istore_$i" else i"istore $i" - // arithmetic expression compilation def compile_aexp(a: AExp, env : Env) : String = a match { - case Num(i) => compile_num(i) - case Var(s) => compile_iload(env(s)) + case Num(i) => i"ldc $i" + case Var(s) => i"iload ${env(s)}" case Aop(op, a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_op(op) - case Ref(s, a) => - compile_aload(env(s)) ++ compile_aexp(a, env) ++ i"iaload" + case Ref(s, a) => + i"aload ${env(s)}" ++ compile_aexp(a, env) ++ i"iaload" } -def compile_bop(op: String, jmp: String) = op match { - case "==" => i"if_icmpne $jmp" - case "!=" => i"if_icmpeq $jmp" - case "<" => i"if_icmpge $jmp" -} - - // boolean expression compilation def compile_bexp(b: BExp, env : Env, jmp: String) : String = b match { case True => "" case False => i"goto $jmp" - case Bop(op, a1, a2) => - compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_bop(op, jmp) + case Bop("==", a1, a2) => + compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpne $jmp" + case Bop("!=", a1, a2) => + compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpeq $jmp" + case Bop("<", a1, a2) => + compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpge $jmp" } // statement compilation def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match { case Skip => ("", env) case Assign(x, a) => { - val index = env.getOrElse(x, env.keys.size) // - (compile_aexp(a, env) ++ compile_istore(index), env + (x -> index)) + val index = env.getOrElse(x, env.keys.size) + (compile_aexp(a, env) ++ i"istore $index \t\t; $x", env + (x -> index)) } case If(b, bl1, bl2) => { val if_else = Fresh("If_else") @@ -168,12 +157,12 @@ l"$loop_end", env1) } case Write(x) => - (compile_iload(env(x)) ++ + (i"iload ${env(x)} \t\t; $x" ++ i"invokestatic XXX/XXX/write(I)V", env) case Read(x) => { val index = env.getOrElse(x, env.keys.size) - (i"invokestatic XXX/XXX/read()I" ++ - compile_istore(index), env + (x -> index)) + (i"invokestatic XXX/XXX/read()I" ++ + i"istore $index \t\t; $x", env + (x -> index)) } case ArrayDef(s: String, n: Int) => { val index = if (env.isDefinedAt(s)) throw new Exception("array def error") else @@ -185,7 +174,7 @@ case AssignA(s, a1, a2) => { val index = if (env.isDefinedAt(s)) env(s) else throw new Exception("array not defined") - (compile_aload(env(s)) ++ + (i"aload ${env(s)}" ++ compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"iastore", env) @@ -378,7 +367,7 @@ ("while" ~ BExp ~ "do" ~ Block) ==> { case _ ~ y ~ _ ~ w => While(y, w) } | ("new(" ~ IdParser ~ "[" ~ NumParser ~ "])") ==> { case _ ~ y ~ _ ~ u ~ _ => ArrayDef(y, u) } | - ("write" ~ IdParser) ==> { case _ ~ y => Write(y) } + ("write(" ~ IdParser ~ ")") ==> { case _ ~ y ~ _ => Write(y) } lazy val Stmts: Parser[String, Block] = (Stmt ~ ";" ~ Stmts) ==> { case x ~ _ ~ z => x :: z : Block } | @@ -408,7 +397,7 @@ minus1 := temp; n := n - 1}; result := minus2; - write result + write(result) """.replaceAll("\\s+", "") val fib_prog = Stmts.parse_all(fib).toList @@ -525,9 +514,10 @@ // Mandelbrot Set //---------------- // -// Note: Parsing of the generated WHILE program (around 56K in size) -// takes approximately 10 minutes. The final class file runs -// for around 23 seconds. +// Note: Parsing of the generated WHILE program (around 60K in size) +// takes approximately 10 minutes + + bf_run("""A mandelbrot set fractal viewer in brainf*** written by Erik Bosman +++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[ @@ -676,3 +666,28 @@ <<<<<]]>>>]""", "mand") + + +//=============== +// For peephole profiling +// +/* +val loops = """ + start := 180000; + x1 := start; + x2 := start; + x3 := start; + while (0 < x1) do { + while (0 < x2) do { + while (0 < x3) do { x3 := x3 - 1 }; + x3 := start; + x2 := x2 - 1 + }; + x2 := start; + x1 := x1 - 1 + }""".replaceAll("\\s+", "") + +val loops_prog = Stmts.parse_all(loops).toList +compile_to_file(loops_prog.head, "loops") +compile_and_run(loops_prog.head, "loops") +*/