ScalaでBrainf*ckのインタプリタを書いてみたよ
Scalaで書いた作品その3です。まぁ、今までハロワと妙なEclipse Pluginしか書いてないので、全くScalaらしからぬコードだと思うけど。
とりあえずコードを貼ると、モヒモヒした人達がScalaっぽくしてくれるんじゃないかなぁ…。
とりあえずブログ上のテキストだとモヒりにくいと思ったから、githubに上げた…ら、案の定モヒられています。
- before(Java脳で書いたbf) : https://github.com/dai0304/brainfuck-scala
- after(ガチなScala脳で書いたbf) : https://github.com/yuroyoro/brainfuck-scala
object Brainfuck { var commands = Map( '>' -> incrementPointer, '<' -> decrementPointer, '+' -> incrementMemoryAtPointer, '-' -> decrementMemoryAtPointer, '.' -> outputMemoryAtPointer, ',' -> inputMemoryAtPointer, '[' -> openLoop, ']' -> closeLoop ) def main(args:Array[String]) { val program = readSource val env = new Environment(program) while (env.isEof == false) { commands.get(env.programChar) match { case Some(command) => command.execute(env) case _ => ; } env.progress } } def readSource = { // output "Hello, world!" """ +++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-. ------------.<++++++++.--------.+++.------.--------.>+. """ } }
class Environment(val program: String) { val memory = new Array[Int](3000) var pointer = 0 var counter = 0 def isEof = { counter >= program.length } def programChar = { program(counter) } def progress:Unit = { counter += 1 } def memoryAtPointer = { memory(pointer) } }
abstract class Command { def execute(env: Environment) }
object incrementPointer extends Command { def execute(env: Environment) = { require(env != null) env.pointer += 1 } }
object decrementPointer extends Command { def execute(env: Environment) = { require(env != null) env.pointer -= 1 } }
object incrementMemoryAtPointer extends Command { def execute(env: Environment) = { require(env != null) env.memory(env.pointer) += 1 } }
object decrementMemoryAtPointer extends Command { def execute(env: Environment) = { require(env != null) env.memory(env.pointer) -= 1 } }
object inputMemoryAtPointer extends Command { def execute(env: Environment) { require(env != null) env.memory(env.pointer) = Console.in.read } }
object outputMemoryAtPointer extends Command { def execute(env: Environment) { require(env != null) print(env.memoryAtPointer.toChar) } }
object openLoop extends Command { def execute(env: Environment) = { require(env != null) if (env.memoryAtPointer == 0) { var depth = 0 while (env.programChar != ']' || depth != 1) { if (env.programChar == '[') { depth += 1 } else if (env.programChar == ']') { depth -= 1 } env.counter += 1 } } } }
object closeLoop extends Command { def execute(env: Environment) = { require(env != null) if (env.memoryAtPointer != 0) { var depth = 0 while (env.programChar != '[' || depth != 1) { if (env.programChar == ']') { depth += 1 } else if (env.programChar == '[') { depth -= 1 } env.counter -= 1 } } } }