updated
authorChristian Urban <urbanc@in.tum.de>
Thu, 26 Sep 2019 11:00:17 +0100
changeset 633 e4889da2fe29
parent 632 b7b91158eded
child 634 2c46407af618
updated
progs/bfc.scala
progs/bfc1.scala
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/progs/bfc.scala	Thu Sep 26 11:00:17 2019 +0100
@@ -0,0 +1,76 @@
+// A Transpiler for the Brainf*** language
+//=========================================
+
+import io.Source
+import scala.util._
+
+
+// loding a bf-file 
+def load_bff(name: String) : String = 
+  Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
+
+
+// simple instructions
+def instr(c: Char) : String = c match {
+  case '>' => "ptr++;"
+  case '<' => "ptr--;"
+  case '+' => "(*ptr)++;"
+  case '-' => "(*ptr)--;"
+  case '.' => "putchar(*ptr);"
+  case ',' => "*ptr = getchar();\n"
+  case '['  => "while(*ptr){"
+  case ']'  => "}"
+  case _ => ""
+}
+
+def instrs(prog: String) : String =
+  prog.toList.map(instr(_)).mkString
+
+
+def compile_str(prog: String) : String = {
+  "#include <string.h>\n" ++
+  "#include <stdio.h>\n" ++
+  "char field[30000];\n" ++
+  "char *ptr = &field[15000];" ++
+  "int main()\n{\n" ++
+  "memset(field, '\\0', 30000);\n" ++
+  instrs(prog) ++
+  "\n return 0;\n}"
+}
+
+def compile(name: String, prog: String) = {
+  val fw = new java.io.FileWriter(name + ".c") 
+  val is = compile_str(prog)
+  //println(is)
+  fw.write(is) 
+  fw.close()
+}
+
+import sys.process._
+
+def compile_run(prog: String) = {
+  compile("tmp", prog)
+  "gcc -O0 -o tmp tmp.c".!
+  "./tmp".!
+  ()
+}
+
+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)
+}
+
+
+println(s"${time_needed(1, compile_run(load_bff("mandelbrot.bf")))} secs")
+
+
+
+// a benchmark program (counts down from 'Z' to 'A')
+val b1 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
+            [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
+            ++++++++[>++++++++++[>++++++++++[>++++++++++[>+
+            +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++."""
+
+println(s"${time_needed(1, compile_run(b1))} secs")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/progs/bfc1.scala	Thu Sep 26 11:00:17 2019 +0100
@@ -0,0 +1,85 @@
+// A Transpiler for the Brainf*** language
+//=========================================
+
+import io.Source
+import scala.util._
+
+
+// loding a bf-file 
+def load_bff(name: String) : String = 
+  Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
+
+def splice(cs: List[Char], acc: List[(Char, Int)]) : List[(Char, Int)] = (cs, acc) match {
+  case (Nil, acc) => acc
+  case (c :: cs, Nil) => splice(cs, List((c, 1)))
+  case (c :: cs, (d, n) :: acc) => 
+    if (c == d) splice(cs, (c, n + 1) :: acc)
+    else splice(cs, (c, 1) :: (d, n) :: acc)
+}
+
+def spl(s: String) = splice(s.toList, Nil).reverse
+
+def instr2(c: Char, n: Int) : String = c match {
+  case '>' => "ptr += " + n.toString + ";"
+  case '<' => "ptr -= " + n.toString + ";"
+  case '+' => "(*ptr) += " + n.toString + ";"
+  case '-' => "(*ptr) -= " + n.toString + ";"
+  case '.' => "putchar(*ptr);" * n
+  case ',' => "*ptr = getchar();\n" * n
+  case '['  => "while(*ptr){" * n
+  case ']'  => "}" * n
+  case _ => ""
+}
+
+
+def instrs2(prog: String) : String =
+  spl(prog).map{ case (c, n) => instr2(c, n) }.mkString
+
+
+def compile_str(prog: String) : String = {
+  "#include <string.h>\n" ++
+  "#include <stdio.h>\n" ++
+  "char field[30000];\n" ++
+  "char *ptr = &field[15000];" ++
+  "int main()\n{\n" ++
+  "memset(field, '\\0', 30000);\n" ++
+  instrs2(prog) ++
+  "\n return 0;\n}"
+}
+
+def compile(name: String, prog: String) = {
+  val fw = new java.io.FileWriter(name + ".c") 
+  val is = compile_str(prog)
+  //println(is)
+  fw.write(is) 
+  fw.close()
+}
+
+import sys.process._
+
+def compile_run(prog: String) = {
+  compile("tmp", prog)
+  "gcc -O3 -o tmp tmp.c".!
+  "./tmp".!
+  ()
+}
+
+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)
+}
+
+
+println(s"${time_needed(1, compile_run(load_bff("mandelbrot.bf")))} secs")
+
+
+
+// a benchmark program (counts down from 'Z' to 'A')
+val b1 = """>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
+            [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
+            ++++++++[>++++++++++[>++++++++++[>++++++++++[>+
+            +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++."""
+
+println(s"${time_needed(1, compile_run(b1))} secs")