Skip to content

Instantly share code, notes, and snippets.

@kiritsuku
Created May 16, 2016 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiritsuku/8c5c3027edcad2a89ea08f72ca5dcea7 to your computer and use it in GitHub Desktop.
Save kiritsuku/8c5c3027edcad2a89ea08f72ca5dcea7 to your computer and use it in GitHub Desktop.
A brainfuck interpreter in Scala
object Test extends App {
new Interpreter("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.")
}
class Interpreter(str: String) {
val prog = """[^\+\-\<\>\.\,\[\]]""".r replaceAllIn (str, "")
val openBrackets = findBraces(0, Nil, Map.empty)
val closeBrackets = openBrackets map { _.swap }
exec()
def findBraces(pos: Int, braces: List[Int], m: Map[Int, Int]): Map[Int, Int] =
if (pos >= prog.length) m
else prog(pos) match {
case '[' => findBraces(pos+1, pos :: braces, m)
case ']' => findBraces(pos+1, braces.tail, m + (braces.head -> pos))
case _ => findBraces(pos+1, braces, m)
}
def exec(pos: Int = 0, tape: Tape = Tape(Nil, 0, Nil)): Unit = {
def nextPos: Char => Int = {
case '[' if tape.isZero => openBrackets(pos)
case ']' if !tape.isZero => closeBrackets(pos)
case _ => pos
}
if (pos < prog.length)
exec(nextPos(prog(pos))+1, tape exec prog(pos))
}
}
case class Tape(left: List[Int], cell: Int, right: List[Int]) {
def headOf(xs: List[Int]) = if (xs == Nil) 0 else xs.head
def tailOf(xs: List[Int]) = if (xs == Nil) Nil else xs.tail
def isZero = (cell == 0)
def exec: Char => Tape = {
case '+' => copy(cell = (cell+1) & 255)
case '-' => copy(cell = (cell-1) & 255)
case '<' => Tape(tailOf(left), headOf(left), cell :: right)
case '>' => Tape(cell :: left, headOf(right), tailOf(right))
case '.' => print(cell.toChar); this
case ',' => print(">"); copy(cell = io.StdIn.readInt & 255)
case '[' | ']' => this
case c => sys.error("Unexpected token: " + c)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment