|    184 def compile(bl: Block, class_name: String) : String = { |    184 def compile(bl: Block, class_name: String) : String = { | 
|    185   val instructions = compile_block(bl, Map.empty)._1 |    185   val instructions = compile_block(bl, Map.empty)._1 | 
|    186   (beginning ++ instructions.mkString ++ ending).replaceAllLiterally("XXX", class_name) |    186   (beginning ++ instructions.mkString ++ ending).replaceAllLiterally("XXX", class_name) | 
|    187 } |    187 } | 
|    188  |    188  | 
|    189 // compiling and running files |    189  | 
|    190 // |    190 // main compiler functions | 
|    191 // JVM files can be assembled with  |         | 
|    192 // |         | 
|    193 //    java -jar jvm/jasmin-2.4/jasmin.jar fib.j |         | 
|    194 // |         | 
|    195 // and started with |         | 
|    196 // |         | 
|    197 //    java fib/fib |         | 
|    198  |         | 
|    199  |         | 
|    200  |         | 
|    201 import scala.util._ |    191 import scala.util._ | 
|    202 import scala.sys.process._ |    192 import scala.sys.process._ | 
|    203 import scala.io |    193 import scala.io | 
|    204  |    194  | 
|    205 def compile_tofile(bl: Block, class_name: String) = { |    195 def compile_tofile(bl: Block, class_name: String) = { | 
|    206   val output = compile(bl, class_name) |    196   val output = compile(bl, class_name) | 
|    207   val fw = new java.io.FileWriter(class_name + ".j")  |    197   scala.tools.nsc.io.File(s"${class_name}.j").writeAll(output) | 
|    208   fw.write(output)  |         | 
|    209   fw.close() |         | 
|    210 } |    198 } | 
|    211  |    199  | 
|    212 def compile_all(bl: Block, class_name: String) : Unit = { |    200 def compile_all(bl: Block, class_name: String) : Unit = { | 
|    213   compile_tofile(bl, class_name) |    201   compile_tofile(bl, class_name) | 
|    214   println("compiled ") |    202   println("compiled ") | 
|    215   val test = ("java -jar jvm/jasmin-2.4/jasmin.jar " + class_name + ".j").!! |    203   (s"java -jar jvm/jasmin-2.4/jasmin.jar ${class_name}.j").!! | 
|    216   println("assembled ") |    204   println("assembled ") | 
|    217 } |    205 } | 
|    218  |    206  | 
|    219 def time_needed[T](i: Int, code: => T) = { |    207 def time_needed[T](i: Int, code: => T) = { | 
|    220   val start = System.nanoTime() |    208   val start = System.nanoTime() | 
|    225  |    213  | 
|    226  |    214  | 
|    227 def compile_run(bl: Block, class_name: String) : Unit = { |    215 def compile_run(bl: Block, class_name: String) : Unit = { | 
|    228   println("Start compilation") |    216   println("Start compilation") | 
|    229   compile_all(bl, class_name) |    217   compile_all(bl, class_name) | 
|    230   println("running") |    218   println("Start running") | 
|    231   println("Time: " + time_needed(1, ("java " + class_name + "/" + class_name).!)) |    219   println("Time: " + time_needed(1, (s"java ${class_name}/${class_name}").!)) | 
|    232 } |    220 } | 
|    233  |    221  | 
|    234  |    222 // a simple test case | 
|    235 // BF Part |    223 val arr_test =  | 
|    236  |    224   List(Array("a", 10),                 // a[10] | 
|    237 // simple instructions |    225        Array("b", 2),                  // b[2] | 
|    238 def instr(c: Char) : String = c match { |    226        AssignA("a", Num(0), Num(10)),  // a[0] := 10 | 
|    239   case '>' => "ptr := ptr + 1;" |    227        Assign("x", Ref("a", Num(0))),  // x := a[0] | 
|    240   case '<' => "ptr := ptr - 1;" |    228        Write("x"),                     // write x | 
|    241   case '+' => "field[ptr] := field[ptr] + 1;" |    229        AssignA("b", Num(1), Num(5)),   // b[1] := 5 | 
|    242   case '-' => "field[ptr] := field[ptr] - 1;" |    230        Assign("x", Ref("b", Num(1))),  // x := b[1] | 
|    243   case '.' => "x := field[ptr]; write x;" |    231        Write("x"))                     // write x | 
|    244   case '['  => "while (field[ptr] != 0) do {" |    232  | 
|    245   case ']'  => "skip};" |    233 compile_run(arr_test, "a") | 
|    246   case _ => "" |    234  | 
|    247 } |         | 
|    248  |         | 
|    249 def instrs(prog: String) : String = |         | 
|    250   prog.toList.map(instr).mkString |         | 
|    251  |         | 
|    252  |         | 
|    253 // compound instructions |         | 
|    254 def splice(cs: List[Char], acc: List[(Char, Int)]) : List[(Char, Int)] = (cs, acc) match { |         | 
|    255   case (Nil, acc) => acc |         | 
|    256   case (c :: cs, Nil) => splice(cs, List((c, 1))) |         | 
|    257   case (c :: cs, (d, n) :: acc) =>  |         | 
|    258     if (c == d) splice(cs, (c, n + 1) :: acc) |         | 
|    259     else splice(cs, (c, 1) :: (d, n) :: acc) |         | 
|    260 } |         | 
|    261  |         | 
|    262 def spl(s: String) = splice(s.toList, Nil).reverse |         | 
|    263  |         | 
|    264 def instr2(c: Char, n: Int) : String = c match { |         | 
|    265   case '>' => s"ptr := ptr + $n;" |         | 
|    266   case '<' => s"ptr := ptr - $n;" |         | 
|    267   case '+' => s"field[ptr] := field[ptr] + $n;" |         | 
|    268   case '-' => s"field[ptr] := field[ptr] - $n;" |         | 
|    269   case '.' => s"x := field[ptr]; write x;"  |         | 
|    270   case '['  => s"while (field[ptr] != 0) do {" * n  |         | 
|    271   case ']'  => s"skip};" * n |         | 
|    272   case _ => "" |         | 
|    273 } |         | 
|    274  |         | 
|    275 def instrs2(prog: String) : String = |         | 
|    276   spl(prog).map{ case (c, n) => instr2(c, n) }.mkString |         | 
|    277  |         | 
|    278  |         | 
|    279 def bf_str(prog: String) : String = { |         | 
|    280   "\n" ++ |         | 
|    281   //"new field[30000];\n" ++ |         | 
|    282   "ptr := 15000;" ++ |         | 
|    283   instrs2(prog) ++ |         | 
|    284   "skip" |         | 
|    285 } |         | 
|    286  |         | 
|    287 def bf_run(bfprog: String, name: String) = { |         | 
|    288   println("BF processing start") |         | 
|    289   val bf_string = bf_str(bfprog).replaceAll("\\s", "") |         | 
|    290   println(s"BF parsing start (string length ${bf_string.length})") |         | 
|    291   val bf_prog = Stmts.parse_all(bf_string).toList.head |         | 
|    292   println("BF Compile start") |         | 
|    293   compile_run(Array("field", 30000) :: bf_prog, name) |         | 
|    294 } |         | 
|    295  |         | 
|    296  |         | 
|    297  |         | 
|    298 val bf1 = """++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[ |         | 
|    299       ->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<< |         | 
|    300       ]>.>+[>>]>+]""" |         | 
|    301  |         | 
|    302 bf_run(bf1, "sier") |         | 
|    303  |         | 
|    304 bf_run("""++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++ |         | 
|    305        ..+++.>>.<-.<.+++.------.--------.>>+.>++.""", "hello") |         | 
|    306  |         | 
|    307 bf_run("""+++++++++++ |         | 
|    308       >+>>>>++++++++++++++++++++++++++++++++++++++++++++ |         | 
|    309       >++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+> |         | 
|    310       +<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[- |         | 
|    311       <-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<< |         | 
|    312       -]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]] |         | 
|    313       >[<<+>>[-]]<<<<<<<]>>>>>[+++++++++++++++++++++++++ |         | 
|    314       +++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++ |         | 
|    315       ++++++++++++++++++++++++++++++++++++++++++++.[-]<< |         | 
|    316       <<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<< |         | 
|    317       [-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-]""", "fibs") |         |