scala/abacus.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Thu, 21 Feb 2013 16:07:40 +0000
changeset 193 317a2532c567
child 194 fc2a5e9fbb97
permissions -rw-r--r--
split up scala-file into separate components
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
193
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
package object abacus {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
import lib._
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
// Abacus machines
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
sealed abstract class AInst 
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
case class Inc(n: Int) extends AInst
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
case class Dec(n: Int, l: Int) extends AInst
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
case class Goto(l: Int) extends AInst
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
type AProg = List[AInst]
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
type Regs = Map[Int, Int]
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
case class AConfig(s: Int, regs: Regs)  
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
case class Abacus(p: AProg) {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
  def ++ (that: Abacus) = Abacus(this.p ::: that.p)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
  def shift(offset: Int, jump: Int) = Abacus(p.map(_ match {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
    case Inc(n) => Inc(n)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
    case Dec(n, l) => if (l == jump) Dec(n, l) else Dec(n, l + offset)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
    case Goto(l) => if (l == jump) Goto(l) else Goto(l + offset)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
  }))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
      
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
  def adjust(old_jump: Int, jump: Int) = Abacus(p.map(_ match {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
    case Inc(n) => Inc(n)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
    case Dec(n, l) => if (l == old_jump) Dec(n, jump) else Dec(n, l)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
    case Goto(l) => if (l == old_jump) Goto(jump) else Goto(l)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
  }))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
  def step(cf: AConfig) : AConfig = (nth_of(p, cf.s), cf.s) match {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
    case (None, _) => cf
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
    case (Some(Inc(n)), s) => AConfig(s + 1, cf.regs + (n -> (dget(cf.regs, n) + 1)))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
    case (Some(Dec(n, l)), s) => {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
      if (dget(cf.regs, n) == 0) AConfig(l, cf.regs)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
      else AConfig(s + 1, cf.regs + (n -> (dget(cf.regs, n) - 1)))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
    }
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
    case (Some(Goto(l)), _) => AConfig(l, cf.regs)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
  }  
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    41
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
  def steps(cf: AConfig, n: Int) : AConfig = n match {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
    case 0 => cf
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
    case n => steps(step(cf), n - 1)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
  } 
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
  def steps(regs: Regs, n: Int) : AConfig = steps(AConfig(0, regs), n)
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
  def run(cf: AConfig) : AConfig = {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
    if (cf.s >= p.length || cf.s < 0) cf else run(step(cf))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
  }
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
 
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
  def run(regs: Regs): Regs = run(AConfig(0, regs)).regs
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
}
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
}
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57