progs/bfc0.scala
changeset 736 d3e477fe6c66
parent 735 fc2e3609d5e5
child 737 14a348d050b3
equal deleted inserted replaced
735:fc2e3609d5e5 736:d3e477fe6c66
     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 // running the c-compiler over the transpiled
       
    50 // BF program and running the result
       
    51 import sys.process._
       
    52 
       
    53 def compile_run(prog: String) = {
       
    54   compile("tmp", prog)
       
    55   "gcc -O3 -o tmp tmp.c".!
       
    56   "./tmp".!
       
    57   ()
       
    58 }
       
    59 
       
    60 def time_needed[T](n: Int, code: => T) = {
       
    61   val start = System.nanoTime()
       
    62   for (i <- 0 until n) code
       
    63   val end = System.nanoTime()
       
    64   (end - start)/(n * 1.0e9)
       
    65 }
       
    66 
       
    67 // the mandelbrot program
       
    68 val b0 = load_bff("mandelbrot.bf")
       
    69 
       
    70 println(s"${time_needed(1, compile_run(b0))} secs")
       
    71 
       
    72 
       
    73 
       
    74 // a benchmark program (counts down from 'Z' to 'A')
       
    75 val b1 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
       
    76             [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
       
    77             ++++++++[>++++++++++[>++++++++++[>++++++++++[>+
       
    78             +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++."""
       
    79 
       
    80 println(s"${time_needed(1, compile_run(b1))} secs")
       
    81 
       
    82 
       
    83 
       
    84