progs/bfc.scala
changeset 634 2c46407af618
parent 633 e4889da2fe29
child 635 7c2c0f10c424
equal deleted inserted replaced
633:e4889da2fe29 634:2c46407af618
     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")