Created
February 3, 2015 14:48
-
-
Save Alefas/544346c7e809d5ac070c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package abstr.interpretation | |
import scala.annotation.tailrec | |
import scala.util.parsing.combinator.RegexParsers | |
/** | |
* @author Alefas | |
* @since 03/02/15. | |
*/ | |
object ThreeCounterInterpreter { | |
sealed trait Operation | |
case class Inc(v: Var) extends Operation | |
case class Dec(v: Var) extends Operation | |
case class Zero(test: Var, th: Int, el: Int) extends Operation | |
case object Stop extends Operation | |
sealed trait Var | |
case object X extends Var | |
case object Y extends Var | |
case object Z extends Var | |
object LineParser extends RegexParsers { | |
val VAR: Parser[Var] = "x" ^^ {_ => X} | "y" ^^ {_ => Y} | "z" ^^ {_ => Z} | |
val inc: Parser[Operation] = "inc" ~> VAR ^^ Inc | |
val dec: Parser[Operation] = "dec" ~> VAR ^^ Dec | |
val line: Parser[Int] = """\d+""".r ^^ {_.toInt} | |
val zero: Parser[Operation] = "zero" ~> VAR ~ line ~ ("else" ~> line) ^^ { | |
case v ~ th ~ e => Zero(v, th, e) | |
} | |
val stop: Parser[Operation] = "stop" ^^ {_ => Stop} | |
val expression: Parser[Operation] = inc | dec | zero | stop | |
def parse(s: String): Operation = { | |
try { | |
LineParser.parse(LineParser.expression, s).get | |
} | |
catch { | |
case _: Throwable => | |
println(s"error for $s") | |
Stop | |
} | |
} | |
} | |
def main(args: Array[String]) { | |
val program = | |
""" | |
|zero x 7 else 2 | |
|inc y | |
|inc y | |
|inc y | |
|dec x | |
|zero x 1 else 1 | |
|stop | |
""".stripMargin | |
val operationList = program.lines.filter(_.nonEmpty).map(LineParser.parse).toSeq | |
case class State(position: Int, x: Int, y: Int, z: Int) | |
@tailrec | |
def iterateProgram(state: State): State = { | |
println(state) | |
operationList(state.position - 1) match { | |
case Inc(X) => iterateProgram(State(state.position + 1, state.x + 1, state.y, state.z)) | |
case Inc(Y) => iterateProgram(State(state.position + 1, state.x, state.y + 1, state.z)) | |
case Inc(Z) => iterateProgram(State(state.position + 1, state.x, state.y, state.z + 1)) | |
case Dec(X) if state.x > 0 => iterateProgram(State(state.position + 1, state.x - 1, state.y, state.z)) | |
case Dec(Y) if state.y > 0 => iterateProgram(State(state.position + 1, state.x, state.y - 1, state.z)) | |
case Dec(Z) if state.z > 0 => iterateProgram(State(state.position + 1, state.x, state.y, state.z - 1)) | |
case Zero(X, i, j) if state.x == 0 => iterateProgram(State(i, state.x, state.y, state.z)) | |
case Zero(X, i, j) if state.x != 0 => iterateProgram(State(j, state.x, state.y, state.z)) | |
case Zero(Y, i, j) if state.y == 0 => iterateProgram(State(i, state.x, state.y, state.z)) | |
case Zero(Y, i, j) if state.y != 0 => iterateProgram(State(j, state.x, state.y, state.z)) | |
case Zero(Z, i, j) if state.z == 0 => iterateProgram(State(i, state.x, state.y, state.z)) | |
case Zero(Z, i, j) if state.z != 0 => iterateProgram(State(j, state.x, state.y, state.z)) | |
case _ => state | |
} | |
} | |
val initialValue = 5 | |
val result = iterateProgram(State(1, initialValue, 0, 0)) | |
println(result.y) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment