scala/comp1.scala
changeset 271 4457185b22ef
parent 207 b93ec66cf4bb
--- a/scala/comp1.scala	Wed Jun 26 14:42:42 2013 +0100
+++ b/scala/comp1.scala	Wed Jul 17 10:33:19 2013 +0100
@@ -5,6 +5,7 @@
 import lib._
 import turing._
 import abacus._
+import scala.annotation.tailrec
 
 // TMs used in the translation
 
@@ -38,14 +39,18 @@
 }
 
 
-// start address of the nth instruction
-def address(p: AProg, n: Int) = {
-  def layout(p: AProg) = p.map(_ match {
-    case Inc(n) => 2 * n + 9 
-    case Dec(n, _) => 2 * n + 16 
-    case Goto(n) => 1
-  })
-  layout(p).take(n).sum + 1
+// start address of the instructions
+@tailrec
+def layout(p: AProg, sum: Int, out: List[Int]) : List[Int] = p match {
+    case Nil => out.reverse
+    case Inc(n)::p => layout(p, 2 * n + 9 + sum, 2 * n + 9 + sum::out) 
+    case Dec(n, _)::p => layout(p, 2 * n + 16 + sum, 2 * n + 16 + sum::out)  
+    case Goto(n)::p => layout(p, 1 + sum, 1 + sum::out) 
+ }
+
+def address(layout: List[Int], n: Int) = {
+  //println("calculating layout of " + n)
+  layout(n) + 1
 }
 
 def compile_Inc(s: Int, n: Int) = 
@@ -56,17 +61,29 @@
 
 def compile_Goto(s: Int) = TMGoto.shift(s - 1)
 
-def compile_abc(p: AProg, s: Int, i: AInst) = i match {
-  case Inc(n) => compile_Inc(s, n)
-  case Dec(n, e) => compile_Dec(s, n, address(p, e))
-  case Goto(e) => compile_Goto(address(p, e))
+@tailrec
+def compile_abc(lay: List[Int], p: AProg, cnt: Int, out: List[TM]): List[TM] = {
+  if (cnt % 1000 == 0) println("compile counter of instructions " + cnt);
+p match {
+  case Nil => out.reverse
+  case Inc(n)::p => compile_abc(lay, p, cnt + 1, compile_Inc(address(lay, cnt), n)::out)
+  case Dec(n, e)::p => compile_abc(lay, p, cnt + 1, compile_Dec(address(lay, cnt), n, address(lay, e))::out)
+  case Goto(e)::p => compile_abc(lay, p, cnt + 1, compile_Goto(address(lay, e))::out)
+}
 }
 
 // component TMs for each instruction
-def TMs(p: AProg) = 
-  p.zipWithIndex.map{case (i, n) => compile_abc(p, address(p, n), i)}
+def TMs(p: AProg) = {
+  val lay = layout(p, 0, Nil) 
+  println("layout calculated")
+  println("number of states (38667456): " + lay.last)
+  compile_abc(lay, p, 0, Nil)
+}
 
-def toTM(p: AProg) = TMs(p).reduceLeft(_ ++ _)
+def toTM(p: AProg) = {
+  println("start TM compilation")
+  TMs(p).reduceLeft(_ ++ _)
+}
     
 }