|         |      1 // A Transpiler for the Brainf*** language | 
|         |      2 //========================================= | 
|         |      3  | 
|         |      4 import io.Source | 
|         |      5 import scala.util._ | 
|         |      6  | 
|         |      7  | 
|         |      8 // loding a bf-file  | 
|         |      9 def load_bff(name: String) : String =  | 
|         |     10   Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("") | 
|         |     11  | 
|         |     12  | 
|         |     13 // simple instructions | 
|         |     14 def instr(c: Char) : String = c match { | 
|         |     15   case '>' => "ptr++;" | 
|         |     16   case '<' => "ptr--;" | 
|         |     17   case '+' => "(*ptr)++;" | 
|         |     18   case '-' => "(*ptr)--;" | 
|         |     19   case '.' => "putchar(*ptr);" | 
|         |     20   case ',' => "*ptr = getchar();\n" | 
|         |     21   case '['  => "while(*ptr){" | 
|         |     22   case ']'  => "}" | 
|         |     23   case _ => "" | 
|         |     24 } | 
|         |     25  | 
|         |     26 def instrs(prog: String) : String = | 
|         |     27   prog.toList.map(instr(_)).mkString | 
|         |     28  | 
|         |     29  | 
|         |     30 def compile_str(prog: String) : String = { | 
|         |     31   "#include <string.h>\n" ++ | 
|         |     32   "#include <stdio.h>\n" ++ | 
|         |     33   "char field[30000];\n" ++ | 
|         |     34   "char *ptr = &field[15000];" ++ | 
|         |     35   "int main()\n{\n" ++ | 
|         |     36   "memset(field, '\\0', 30000);\n" ++ | 
|         |     37   instrs(prog) ++ | 
|         |     38   "\n return 0;\n}" | 
|         |     39 } | 
|         |     40  | 
|         |     41 def compile(name: String, prog: String) = { | 
|         |     42   val fw = new java.io.FileWriter(name + ".c")  | 
|         |     43   val is = compile_str(prog) | 
|         |     44   //println(is) | 
|         |     45   fw.write(is)  | 
|         |     46   fw.close() | 
|         |     47 } | 
|         |     48  | 
|         |     49 import sys.process._ | 
|         |     50  | 
|         |     51 def compile_run(prog: String) = { | 
|         |     52   compile("tmp", prog) | 
|         |     53   "gcc -O0 -o tmp tmp.c".! | 
|         |     54   "./tmp".! | 
|         |     55   () | 
|         |     56 } | 
|         |     57  | 
|         |     58 def time_needed[T](n: Int, code: => T) = { | 
|         |     59   val start = System.nanoTime() | 
|         |     60   for (i <- 0 until n) code | 
|         |     61   val end = System.nanoTime() | 
|         |     62   (end - start)/(n * 1.0e9) | 
|         |     63 } | 
|         |     64  | 
|         |     65  | 
|         |     66 println(s"${time_needed(1, compile_run(load_bff("mandelbrot.bf")))} secs") | 
|         |     67  | 
|         |     68  | 
|         |     69  | 
|         |     70 // a benchmark program (counts down from 'Z' to 'A') | 
|         |     71 val b1 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++ | 
|         |     72             [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++ | 
|         |     73             ++++++++[>++++++++++[>++++++++++[>++++++++++[>+ | 
|         |     74             +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++.""" | 
|         |     75  | 
|         |     76 println(s"${time_needed(1, compile_run(b1))} secs") |