Skip to content

Instantly share code, notes, and snippets.

@kamiyaowl
Last active August 29, 2015 14:15
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 kamiyaowl/315acaec8171306dba51 to your computer and use it in GitHub Desktop.
Save kamiyaowl/315acaec8171306dba51 to your computer and use it in GitHub Desktop.
/**
* Created by kamiya on 2015/02/16.
*/
package kamiya.parse.brainfuck
import scala.util.parsing.combinator.RegexParsers
class BrainfuckProcessor {
private var pt : Int = 0
private var buf : Array[Char] = Array.fill[Char](3000)(0)
def reset : Unit = { pt = 0; buf = Array.fill[Char](3000)(0) }
def memRead : Char = buf(pt)
def memWrite(c: Char) = buf(pt) = c
def memUpdate(f: Char => Char) = buf(pt) = f(buf(pt))
def ptUpdate(f: Int => Int) = pt = f(pt)
}
abstract class BrainfuckToken {
def run(bp: BrainfuckProcessor): Unit
implicit def toChar(src: Int): Char = src.asInstanceOf[Char]
}
case class Incr() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = bp.memUpdate(_ + 1)
}
case class Decr() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = bp.memUpdate(_ - 1)
}
case class Left() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = bp.ptUpdate(_ - 1)
}
case class Right() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = bp.ptUpdate(_ + 1)
}
case class In() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = bp.memWrite(readChar)
}
case class Out() extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = print(bp.memRead)
}
case class Loop(tokens: List[BrainfuckToken]) extends BrainfuckToken {
override def run(bp: BrainfuckProcessor): Unit = while (bp.memRead != 0) {
tokens.foreach(_.run(bp))
}
}
object BrainfuckParser extends RegexParsers {
implicit class BrainfuckTokens(val self: List[BrainfuckToken]) {
def run(bp: BrainfuckProcessor) = self.foreach(_.run(bp))
}
def apply(src:String) : ParseResult[List[BrainfuckToken]] = parseAll(bf,src)
def bf: Parser[List[BrainfuckToken]] = rep(loop | token)
def token: Parser[BrainfuckToken] = ("+" | "-" | ">" | "<" | "," | ".") ^^ {
case "+" => Incr()
case "-" => Decr()
case "<" => Left()
case ">" => Right()
case "," => In()
case "." => Out()
}
def loop: Parser[Loop] = ("[" ~> bf) <~ "]" ^^ { r => Loop(r)}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment