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")  | 
         |