progs/compile_arrays.scala
changeset 628 8067d0a8ba04
parent 627 f5214da1976e
child 906 2bf1516d730f
equal deleted inserted replaced
627:f5214da1976e 628:8067d0a8ba04
    67    return
    67    return
    68 
    68 
    69 .end method
    69 .end method
    70 """
    70 """
    71 
    71 
       
    72 
    72 // Compiler functions
    73 // Compiler functions
    73 
       
    74 
    74 
    75 // for generating new labels
    75 // for generating new labels
    76 var counter = -1
    76 var counter = -1
    77 
    77 
    78 def Fresh(x: String) = {
    78 def Fresh(x: String) = {
   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")