diff -r 220aea0e5517 -r 923b946347e6 progs/bf/bfc0.sc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/progs/bf/bfc0.sc Mon Jul 27 01:55:05 2020 +0100 @@ -0,0 +1,71 @@ +// A Transpiler for the Brainf*** language to C +//=============================================== +// +// Call with +// +// amm bfc0.sc <> +// +// +// Note: An interesting exercise is to call +// gcc with -O3 instead of -O0 + +// simple instructions +def 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 the boilerplate +def compile(prog: String) : String = + s"""#include + #include + char field[30000]; + char *ptr = &field[15000]; + int main() { + memset(field, '\\0', 30000); + ${instrs(prog)} + return 0;}""" + +def compile_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 binary + +def compile_run(prog: String) = { + val tn = "tmp" + compile_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 ") +@main +def main(fname: String) = { + val bf_str = os.read(os.pwd / fname) + println(s"${time_needed(1, compile_run(bf_str))} secs") +} + + +