Scala勉強中
D言語で書いた Brainf*ckの処理系をそのまま Scalaで再実装。
両方もっと面白く書けるとは思うのだけど、それはそれ今後の課題と致します。(逃
import std.stdio; import std.string : indexOf; import std.algorithm; import std.conv; import std.range; import std.array; struct Source { string code = ""; uint position = 0; uint[] jmps; char get() { return code[ position++ ]; } bool empty() { return code.length == position; } void push() { jmps ~= position; } void jamp() { position = jmps[$-1]; } void pop() { jmps = jmps[0..$-1]; } } unittest { Source src = Source( "+-[><].," ); assert( src.get == '+' ); assert( src.get == '-' ); assert( src.get == '[' ); src.push; assert( src.position == 3 ); assert( src.jmps == [3] ); assert( src.get == '>' ); assert( src.get == '<' ); assert( src.position == 5 ); assert( src.get == ']' ); src.jamp(); assert( src.position == 3 ); assert( src.jmps == [3] ); assert( src.get == '>' ); assert( src.get == '<' ); assert( src.position == 5 ); src.pop; assert( src.jmps == [] ); } struct Record { uint[] tape = [0]; uint position = 0; void inc() { tape[ position ]++; } void dec() { if(tape[position]==0) throw new Exception("おこだよ!"); tape[position]--; } void next() { position++; if(tape.length <= position) tape ~= 0; } void prev() { if(position==0) throw new Exception("ダメなの!"); position--; } uint current() { return tape[ position ]; } } string exec( Source src, Record rec ) { string result = ""; while( !src.empty ) { char c = src.get; switch( c ) //switch( src.get ) { case '+' : { rec.inc; } break; case '-' : { rec.dec; } break; case '>' : { rec.next; } break; case '<' : { rec.prev; } break; case '[' : { src.push; } break; case ']' : { rec.current == 0 ? src.pop : src.jamp; } break; case '.' : { result ~= rec.current.to!char; } break; default : {} break; } } return result; } unittest { static Source src = Source( "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+." ); static Record rec = Record(); assert( exec( src, rec ) == "Hello, world!" ); assert( Source( ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+." ).exec( Record() ) == "Hello World!" ); assert( Source( ">+++[>+++[<<++++++++>>-]<-]<.++>+++[>+++[<<+++>>-]<-]<.+++++++..+++.--->++[>++[>++[>++[>++[<<<<<-->>>>>-]<-]<-]<-]<-]<.+>+++[<---->-]<." ).exec( Record() ) == "Hello,!" ); } void main( string[] args ) { Source( args[1] ).exec( Record() ).writeln; return; }
import java.lang.String import scala.collection.mutable._ class Source( code: String ) { var position = 0; var jmps:Stack[Int] = Stack() def get:Char = { val result = code( position ); position += 1; result } def empty:Boolean = { code.length == position } def push = { jmps = jmps.push( position ) } def jamp = { position = jmps.last } def pop = { jmps.pop } } class Record() { var position = 0 var tape:ListBuffer[Int] = ListBuffer(0) def inc = { tape( position ) += 1 } def dec = { tape( position ) -= 1 } def next = { position += 1; if( tape.length <= position ) tape += 0 } def prev = { position -= 1 } def current:Int = { tape( position ) } } object bf2 { def exec( src: Source, rec: Record ): String = { var result = "" while( !src.empty ) { src.get match { case '+' => rec.inc case '-' => rec.dec case '>' => rec.next case '<' => rec.prev case '[' => src.push case ']' => if( rec.current == 0 ) src.pop else src.jamp case '.' => result += rec.current.toChar case _ => println("not match") } } result } def main( args: Array[ String ] ): Unit = { val src = new Source("+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.") val rec = new Record println( exec( src, rec ) ) } }