// A Transpiler for the Brainf*** language to C//===============================================//// Call with//// amm bfc0.sc <<bf_program.bf>>////// Note: An interesting exercise is to call// gcc with -O3 instead of -O0 (see invocation// below).// simple instructionsdef instr(c: Char) : String = c match { case '>' => "ptr++;" case '<' => "ptr--;" case '+' => "(*ptr)++;" case '-' => "(*ptr)--;" case '.' => "putchar(*ptr);" case ',' => "*ptr = getchar();" case '[' => "while(*ptr){" case ']' => "}" case _ => ""}def instrs(prog: String) : String = prog.toList.map(instr(_)).mkString// adding boilerplatedef compile(prog: String) : String = s"""#include <string.h> #include <stdio.h> int field[30000]; int *ptr = &field[15000]; int main() { memset(field, '\\0', 30000); ${instrs(prog)} return 0;}"""def compile_to_file(name: String, prog: String) = os.write.over(os.pwd / name, compile(prog))// running the c-compiler over the transpiled// BF program and running the resulting binarydef compile_and_run(prog: String) = { val tn = "tmp" compile_to_file(s"${tn}.c", prog) os.proc("gcc", "-O0", "-o", tn, s"${tn}.c").call() // call gcc os.proc("./tmp").call(stdout = os.Inherit) // run binary}// Running Testcases//===================def time_needed[T](n: Int, code: => T) = { val start = System.nanoTime() for (i <- 0 until n) code val end = System.nanoTime() (end - start)/(n * 1.0e9)}//@doc(" the argument should be a BF program ")@maindef main(fname: String) = { val bf_str = os.read(os.pwd / fname) println(s"${time_needed(1, compile_and_run(bf_str))} secs")}