progs/bf/bfc0.sc
changeset 742 b5b5583a3a08
parent 740 923b946347e6
child 746 6916229b817b
equal deleted inserted replaced
741:e66bd5c563eb 742:b5b5583a3a08
     5 //
     5 //
     6 //  amm bfc0.sc <<bf_program.bf>>
     6 //  amm bfc0.sc <<bf_program.bf>>
     7 //
     7 //
     8 //
     8 //
     9 // Note: An interesting exercise is to call
     9 // Note: An interesting exercise is to call
    10 // gcc with -O3 instead of -O0 
    10 // gcc with -O3 instead of -O0 (see invocation
       
    11 // below).
       
    12 
    11 
    13 
    12 // simple instructions
    14 // simple instructions
    13 def instr(c: Char) : String = c match {
    15 def instr(c: Char) : String = c match {
    14   case '>' => "ptr++;"
    16   case '>' => "ptr++;"
    15   case '<' => "ptr--;"
    17   case '<' => "ptr--;"
    23 }
    25 }
    24 
    26 
    25 def instrs(prog: String) : String =
    27 def instrs(prog: String) : String =
    26   prog.toList.map(instr(_)).mkString
    28   prog.toList.map(instr(_)).mkString
    27 
    29 
    28 // adding the boilerplate
    30 // adding boilerplate
    29 def compile(prog: String) : String = 
    31 def compile(prog: String) : String = 
    30   s"""#include <string.h> 
    32   s"""#include <string.h> 
    31       #include <stdio.h> 
    33       #include <stdio.h> 
    32       char field[30000]; 
    34       char field[30000]; 
    33       char *ptr = &field[15000]; 
    35       char *ptr = &field[15000]; 
    34       int main() { 
    36       int main() { 
    35       memset(field, '\\0', 30000); 
    37       memset(field, '\\0', 30000); 
    36       ${instrs(prog)} 
    38       ${instrs(prog)} 
    37       return 0;}"""
    39       return 0;}"""
    38 
    40 
    39 def compile_file(name: String, prog: String) = 
    41 
       
    42 def compile_to_file(name: String, prog: String) = 
    40   os.write.over(os.pwd / name, compile(prog))
    43   os.write.over(os.pwd / name, compile(prog))
    41 
    44 
    42 
    45 
    43 // running the c-compiler over the transpiled
    46 // running the c-compiler over the transpiled
    44 // BF program and running the resulting binary
    47 // BF program and running the resulting binary
    45 
    48 
    46 def compile_run(prog: String) = {
    49 def compile_and_run(prog: String) = {
    47   val tn = "tmp"
    50   val tn = "tmp"
    48   compile_file(s"${tn}.c", prog)
    51   compile_to_file(s"${tn}.c", prog)
    49   os.proc("gcc", "-O0", "-o", tn, s"${tn}.c").call() // call gcc
    52   os.proc("gcc", "-O0", "-o", tn, s"${tn}.c").call() // call gcc
    50   os.proc("./tmp").call(stdout = os.Inherit)         // run binary
    53   os.proc("./tmp").call(stdout = os.Inherit)         // run binary
    51 }
    54 }
    52 
    55 
    53 // Running Testcases
    56 // Running Testcases
    62 
    65 
    63 @doc(" the argument should be a BF program ")
    66 @doc(" the argument should be a BF program ")
    64 @main
    67 @main
    65 def main(fname: String) = {
    68 def main(fname: String) = {
    66   val bf_str = os.read(os.pwd / fname)
    69   val bf_str = os.read(os.pwd / fname)
    67   println(s"${time_needed(1, compile_run(bf_str))} secs")
    70   println(s"${time_needed(1, compile_and_run(bf_str))} secs")
    68 }  
    71 }  
    69 
    72 
    70 
    73 
    71 
    74