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 [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++ |