Last active
August 29, 2015 14:15
-
-
Save kamiyaowl/315acaec8171306dba51 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
/** | |
* 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