progs/bf/bfc0.scala
changeset 740 923b946347e6
parent 739 220aea0e5517
child 741 e66bd5c563eb
equal deleted inserted replaced
739:220aea0e5517 740:923b946347e6
     1 // A Transpiler for the Brainf*** language to C
       
     2 //===============================================
       
     3 //
       
     4 // Call with
       
     5 //
       
     6 //  amm bfc0.sc <<bf_program.bf>>
       
     7 //
       
     8 
       
     9 
       
    10 import scala.util._
       
    11 
       
    12 
       
    13 // loding a bf-file 
       
    14 def load_bff(name: String) : String = 
       
    15   Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
       
    16 
       
    17 
       
    18 // simple instructions
       
    19 def instr(c: Char) : String = c match {
       
    20   case '>' => "ptr++;"
       
    21   case '<' => "ptr--;"
       
    22   case '+' => "(*ptr)++;"
       
    23   case '-' => "(*ptr)--;"
       
    24   case '.' => "putchar(*ptr);"
       
    25   case ',' => "*ptr = getchar();\n"
       
    26   case '['  => "while(*ptr){"
       
    27   case ']'  => "}"
       
    28   case _ => ""
       
    29 }
       
    30 
       
    31 def instrs(prog: String) : String =
       
    32   prog.toList.map(instr(_)).mkString
       
    33 
       
    34 
       
    35 def compile_str(prog: String) : String = {
       
    36   "#include <string.h>\n" ++
       
    37   "#include <stdio.h>\n" ++
       
    38   "char field[30000];\n" ++
       
    39   "char *ptr = &field[15000];" ++
       
    40   "int main()\n{\n" ++
       
    41   "memset(field, '\\0', 30000);\n" ++
       
    42   instrs(prog) ++
       
    43   "\n return 0;\n}"
       
    44 }
       
    45 
       
    46 def compile(name: String, prog: String) = {
       
    47   val fw = new java.io.FileWriter(name + ".c") 
       
    48   val is = compile_str(prog)
       
    49   //println(is)
       
    50   fw.write(is) 
       
    51   fw.close()
       
    52 }
       
    53 
       
    54 // running the c-compiler over the transpiled
       
    55 // BF program and running the result
       
    56 import sys.process._
       
    57 
       
    58 def compile_run(prog: String) = {
       
    59   compile("tmp", prog)
       
    60   "gcc -O3 -o tmp tmp.c".!
       
    61   "./tmp".!
       
    62   ()
       
    63 }
       
    64 
       
    65 def time_needed[T](n: Int, code: => T) = {
       
    66   val start = System.nanoTime()
       
    67   for (i <- 0 until n) code
       
    68   val end = System.nanoTime()
       
    69   (end - start)/(n * 1.0e9)
       
    70 }
       
    71 
       
    72 // Running Testcases
       
    73 //===================
       
    74 
       
    75 @doc(" the argument should be a BF program ")
       
    76 @main
       
    77 def main(fname: String) = {
       
    78   val bf_str = os.read(os.pwd / fname)
       
    79   println(s"${time_needed(1, run(bf_str))} secs")
       
    80 }  
       
    81 
       
    82 
       
    83