corrected scala compiler from recs to abacus
authorChristian Urban <christian dot urban at kcl dot ac dot uk>
Fri, 01 Mar 2013 02:56:08 +0000
changeset 205 c7975ab7c52e
parent 204 e55c8e5da49f
child 206 17d80924af53
corrected scala compiler from recs to abacus
scala/README
scala/comp2.scala
scala/ex.scala
--- a/scala/README	Thu Feb 28 15:21:43 2013 +0000
+++ b/scala/README	Fri Mar 01 02:56:08 2013 +0000
@@ -1,7 +1,7 @@
 
 The packages can be compiled with
 
-  scalac lib.scala turing.scala abacus.scala recs.scala comp1.scala
+  scalac lib.scala turing.scala abacus.scala recs.scala comp1.scala comp2.scala
 
 If you get an error, it is advisable to clean 
 out the existing class-files
--- a/scala/comp2.scala	Thu Feb 28 15:21:43 2013 +0000
+++ b/scala/comp2.scala	Fri Mar 01 02:56:08 2013 +0000
@@ -6,13 +6,60 @@
 import abacus._
 import recs._
 
-def arity(f: Rec) = f match {
-  case Z => 1
-  case S => 1
-  case Id(n, _) => n
-  case Cn(n, _, _) => n
-  case Pr(n, _, _) => n
-  case Mn(n, _) => n 
+def AbacusAdd(m: Int, n: Int, p: Int) = 
+  Abacus(Dec(m, 4), Inc(n), Inc(p), Goto(0), Dec(p, 7), Inc(m), Goto(4))
+
+def MVReg(m: Int, n: Int) = Abacus(Dec(m, 3), Inc(n), Goto(0))
+
+//move the registers ranging from i to i + n to range j to j + n
+def MVRegs(i: Int, j: Int, n: Int) : Abacus = n match { 
+  case 0 => Abacus() 
+  case n => MVRegs(i, j, n - 1) :+ MVReg(i + n - 1, j + n - 1)
+}
+
+// clears the first n registers
+def ClearRegs(n: Int) : Abacus = n match {
+  case 0 => Abacus()
+  case n => ClearRegs(n - 1) :+ Abacus(Dec(n - 1, 2), Goto(0))
+}
+
+def cn_merge_gs(x: List[(Abacus, Int, Int)], p: Int) : Abacus = x match {
+  case Nil => Abacus(Nil)
+  case (gprog, gpara, gn)::gs => gprog :+ MVReg(gpara, p) :+ cn_merge_gs(gs, p + 1)
+}
+
+// translation: 
+// second component is the arity of the recursive function, 
+// third componen is the maximum of registers used
+def compile_rec(f: Rec) : (Abacus, Int, Int) = f match {
+  case Z => (Abacus(Goto(1)), 1, 2)
+  case S => (AbacusAdd(0, 1, 2) :+ Abacus(Inc(1)), 1, 3)
+  case Id(i, j) => (AbacusAdd(j, i, i + 1), i, i + 2) 
+  case Cn(n, f, gs) => {
+    val cied_gs = gs.map(compile_rec)
+    val (fprog, fpara, fn) = compile_rec(f) 
+    val pstr = (1 + n :: fn :: (cied_gs.map(_._3))).max
+    val qstr = pstr + gs.length + 1 
+    (cn_merge_gs(cied_gs, pstr) :+ MVRegs(0, qstr, n) :+
+     MVRegs(pstr, 0, gs.length) :+ fprog :+ 
+     MVReg(fpara, pstr) :+ ClearRegs(gs.length) :+
+     MVReg(pstr, n) :+ MVRegs(qstr, 0, n), n,  qstr + n)
+  }
+  case Pr(n, f, g) => { 
+    val (fprog, fpara, fn) = compile_rec(f) 
+    val (gprog, gpara, gn) = compile_rec(g) 
+    val p = List(n + 3, fn, gn).max 
+    val e = gprog.p.length + 7 
+    (MVReg(n, p) :+ fprog :+ MVReg(n, n + 1) :+ 
+     ((Abacus(Dec(p, e)) :+ gprog :+ Abacus(Inc(n), Dec(n + 1, 3), Goto(1))) ++
+      Abacus(Dec(n + 2, 0), Inc (n + 1), Goto (gprog.p.length + 4))), n + 1, p + 1)
+  }
+  case Mn(n, f) => {
+    val (fprog, fpara, fn) = compile_rec(f)
+    val len = fprog.p.length
+    (fprog ++ Abacus(Dec(n + 1, len + 5), Dec(n + 1, len + 3), Goto(len + 1), Inc(n), Goto(0)), 
+     n, List(n + 1, fn).max)
+  }
 }
 
 }
--- a/scala/ex.scala	Thu Feb 28 15:21:43 2013 +0000
+++ b/scala/ex.scala	Fri Mar 01 02:56:08 2013 +0000
@@ -3,7 +3,7 @@
 import abacus._
 import recs._
 import comp1._
-//import comp2._
+import comp2._
 
 // Turing machine examples
 val TMCopy = TM((WBk, 5), (R, 2), (R, 3), (R, 2), (WOc, 3), 
@@ -81,10 +81,17 @@
 println("NextPrime 3: " + NextPrime.eval(3))
 println("NthPrime 1:  " + NthPrime.eval(1))
 println("Listsum [2, 3, 4 , 5, 6]: " + Listsum(5, 4).eval(2, 3, 4, 5, 6))
-// Ask Jian
 println("Strt:  " + Strt(2).eval(2, 3))
 
 
-val ABCZero = Abacus(Goto(1))
-val ABCSucc = Plus(0, 1, 2, 7) ++ Abacus(Inc(1)).shift(Plus(0, 1, 2, 7).p.length, -1)
-def ABCId(n: Int, m: Int) = Plus(m, n, n + 1, 7)
+
+
+println(Const(1))
+println(compile_rec(Const(1))._1)
+println(compile_rec(Const(1)))
+println(compile_rec(Const(1))._1.run(Map(0 -> 1, 1 -> 1, 2 -> 0)))
+println(Add)
+println(compile_rec(Add)._1)
+println(compile_rec(Add))
+println(compile_rec(Add)._1.run(Map(0 -> 3, 1 -> 8, 2 -> 0)))
+//compile_rec(Add)._1.run(Map(0 -> 3, 1 -> 4, 2 -> 0))