progs/compile_arr.scala
changeset 708 4980f421b3b0
parent 707 2fcd7c2da729
child 709 c112a6cb5e52
equal deleted inserted replaced
707:2fcd7c2da729 708:4980f421b3b0
    58 
    58 
    59 .method public static main([Ljava/lang/String;)V
    59 .method public static main([Ljava/lang/String;)V
    60    .limit locals 200
    60    .limit locals 200
    61    .limit stack 200
    61    .limit stack 200
    62 
    62 
       
    63 ; COMPILED CODE STARTS   
       
    64 
    63 """
    65 """
    64 
    66 
    65 val ending = """
    67 val ending = """
    66 
    68 ; COMPILED CODE ENDS
    67    return
    69    return
    68 
    70 
    69 .end method
    71 .end method
    70 """
    72 """
    71 
    73 
   357    (IdParser ~ "[" ~ AExp ~ "]" ~ ":=" ~ AExp) ==> { 
   359    (IdParser ~ "[" ~ AExp ~ "]" ~ ":=" ~ AExp) ==> { 
   358      case x ~ _ ~ z ~ _ ~ _ ~ u => AssignA(x, z, u): Stmt } |
   360      case x ~ _ ~ z ~ _ ~ _ ~ u => AssignA(x, z, u): Stmt } |
   359    ("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block) ==>
   361    ("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block) ==>
   360     { case _ ~ y ~ _ ~ u ~ _ ~w => If(y, u, w): Stmt } |
   362     { case _ ~ y ~ _ ~ u ~ _ ~w => If(y, u, w): Stmt } |
   361    ("while" ~ BExp ~ "do" ~ Block) ==> { case _ ~ y ~ _ ~ w => While(y, w) } |
   363    ("while" ~ BExp ~ "do" ~ Block) ==> { case _ ~ y ~ _ ~ w => While(y, w) } |
   362    ("new" ~ IdParser ~ "[" ~ NumParser ~ "]") ==> { 
   364    ("new(" ~ IdParser ~ "[" ~ NumParser ~ "])") ==> { 
   363     case _ ~ y ~ _ ~ u ~ _ => ArrayDef(y, u) } |
   365     case _ ~ y ~ _ ~ u ~ _ => ArrayDef(y, u) } |
   364    ("write" ~ IdParser) ==> { case _ ~ y => Write(y) } 
   366    ("write" ~ IdParser) ==> { case _ ~ y => Write(y) } 
   365  
   367  
   366 lazy val Stmts: Parser[String, Block] =
   368 lazy val Stmts: Parser[String, Block] =
   367   (Stmt ~ ";" ~ Stmts) ==> { case x ~ _ ~ z => x :: z : Block } |
   369   (Stmt ~ ";" ~ Stmts) ==> { case x ~ _ ~ z => x :: z : Block } |
   403 
   405 
   404 // simple BF instructions translation
   406 // simple BF instructions translation
   405 def instr(c: Char) : String = c match {
   407 def instr(c: Char) : String = c match {
   406   case '>' => "ptr := ptr + 1;"
   408   case '>' => "ptr := ptr + 1;"
   407   case '<' => "ptr := ptr - 1;"
   409   case '<' => "ptr := ptr - 1;"
   408   case '+' => "field[ptr] := field[ptr] + 1;"
   410   case '+' => "mem[ptr] := mem[ptr] + 1;"
   409   case '-' => "field[ptr] := field[ptr] - 1;"
   411   case '-' => "mem[ptr] := mem[ptr] - 1;"
   410   case '.' => "x := field[ptr]; write x;"
   412   case '.' => "x := mem[ptr]; write x;"
   411   //case ',' => "XXX" // "ptr = getchar();\n"
   413   //case ',' => "XXX" // "ptr = getchar();\n"
   412   case '['  => "while (field[ptr] != 0) do {"
   414   case '['  => "while (mem[ptr] != 0) do {"
   413   case ']'  => "skip};"
   415   case ']'  => "skip};"
   414   case _ => ""
   416   case _ => ""
   415 }
   417 }
   416 
   418 
   417 def instrs(prog: String) : String =
   419 def instrs(prog: String) : String =
   441 def spl(s: String) = splice(s.toList, Nil).reverse
   443 def spl(s: String) = splice(s.toList, Nil).reverse
   442 
   444 
   443 def instr2(c: Char, n: Int) : String = c match {
   445 def instr2(c: Char, n: Int) : String = c match {
   444   case '>' => s"ptr := ptr + $n;"
   446   case '>' => s"ptr := ptr + $n;"
   445   case '<' => s"ptr := ptr - $n;"
   447   case '<' => s"ptr := ptr - $n;"
   446   case '0' => s"field[ptr] := 0;"
   448   case '0' => s"mem[ptr] := 0;"
   447   case '+' => s"field[ptr] := field[ptr] + $n;"
   449   case '+' => s"mem[ptr] := mem[ptr] + $n;"
   448   case '-' => s"field[ptr] := field[ptr] - $n;"
   450   case '-' => s"mem[ptr] := mem[ptr] - $n;"
   449   case '.' => s"x := field[ptr]; write x;" 
   451   case '.' => s"x := mem[ptr]; write x;" 
   450   case '['  => "while (field[ptr] != 0) do {" * n 
   452   case '['  => "while (mem[ptr] != 0) do {" * n 
   451   case ']'  => "skip};" * n
   453   case ']'  => "skip};" * n
   452   case _ => ""
   454   case _ => ""
   453 }
   455 }
   454 
   456 
   455 def instrs2(prog: String) : String =
   457 def instrs2(prog: String) : String =
   456   spl(prog.replaceAll("""\[-\]""", "0")).map{ case (c, n) => instr2(c, n) }.mkString
   458   spl(prog.replaceAll("""\[-\]""", "0")).map{ case (c, n) => instr2(c, n) }.mkString
   457 
   459 
   458 def bf_str(prog: String) : String = {
   460 def bf_str(prog: String) : String = {
   459   "\n" ++
   461   "new(mem[30000]);" ++
   460   "ptr := 15000;" ++
   462   "ptr := 15000;" ++
   461   instrs2(prog) ++
   463   instrs2(prog) ++
   462   "skip"
   464   "skip"
   463 }
   465 }
   464 
   466 
   466   println(s"BF pre-processing of $name")
   468   println(s"BF pre-processing of $name")
   467   val bf_string = bf_str(prog).replaceAll("\\s", "")
   469   val bf_string = bf_str(prog).replaceAll("\\s", "")
   468   println(s"BF parsing (program length ${bf_string.length} characters)")
   470   println(s"BF parsing (program length ${bf_string.length} characters)")
   469   val (time, bf_prog) = time_needed(1, Stmts.parse_all(bf_string).toList.head)
   471   val (time, bf_prog) = time_needed(1, Stmts.parse_all(bf_string).toList.head)
   470   println(s"BF generated WHILE program (needed $time for parsing)")
   472   println(s"BF generated WHILE program (needed $time for parsing)")
   471   compile_and_run(ArrayDef("field", 30000) :: bf_prog, name)
   473   compile_and_run(bf_prog, name)
   472 }
   474 }
   473 
   475 
   474 // a benchmark program (counts down from 'Z' to 'A')
   476 // a benchmark program (counts down from 'Z' to 'A')
   475 val bf0 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
   477 val bf0 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
   476             [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
   478             [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++