RCBF/D
From Rosetta Code
Implementation
This is an implementation of Brainf***.
You may find other implementations of this language at Category:Brainf*** Implementations.
RCBF member
This is part of RCBF.
You may find other members of RCBF at Category:RCBF.
Works with: D version 2.007+
An implementation of Rosetta Code BrainF*ck interpreter in D.
Implement notes:
- Needs D version 2.007+, because closure support is required (it should compile in D1, but will run abnormally if brackets/loop-commands are in the BF source).
- Memory is represented by an associative array, so that negative addresses are allowed, though it is not efficient.
- Input and output are in character mode, rather than in numerical.
- Nesting level is checked during parsing, and if loops/brackets are not matched, an error is thrown before executing the code.
module rcbf ; import std.file, std.c.stdio ; alias void delegate() Act ; char[int] mem ; // memory Act[char] cmd ; // bf command except loop-control int ptr ; // mem pointer static this() { cmd['>'] = { if(!(++ptr in mem)) mem[ptr] = 0 ; } ; cmd['<'] = { if(!(--ptr in mem)) mem[ptr] = 0 ; } ; cmd['+'] = { mem[ptr] += 1 ; } ; cmd['-'] = { mem[ptr] -= 1 ; } ; cmd['.'] = { printf("%c", mem[ptr]) ; } ; cmd[','] = { printf("%c", mem[ptr] = getch()) ; flushall ; } ; } void bf(string code) { int cp = 0 ; // code pointer int nested = 0 ; // nested loop level Act bfAct() { Act[] acts ; // store commands of current nesting level char cc ; while(cp < code.length) switch(cc = code[cp++]) { // cc get next command and code pointer cp is advanced case '[': nested++ ; acts ~= bfAct() ; // begin inner loop break ; case ']': if(--nested < 0) throw new Exception("Unmatched Loops") ; return { while(mem[ptr]) { foreach(x ; acts){x();} } } ; default: if(cc in cmd) acts ~= cmd[cc] ; //else ignore other non-command char } return { foreach(x ; acts){x();} } ; } mem = null ; mem[0] = 0 ; ptr = 0 ; // reset memory Act run = bfAct() ; if(nested != 0) throw new Exception("Unmatched Loops") ; run() ; // execute the whole bf program printf("\n") ; } void main(string[] args) { // if no argument, demo code will be run, else if(args.length > 1) // the arguments are treated as filenames of bf source foreach(f ; args[1..$]) // and executed one by one. try bf(cast(string)read(f)) ; catch (Exception e) printf("%*s",e.msg) ; else bf(">+++++++++[<+++++++++>-]<+.>+++[<----->-]" "<.-.++++.>++++++[<------>-]<--.>++++++++[" "<+++++++++>-]<+.>++[<++>-]<+.>++++++++[<-" "-------->-]<------.>++++++[<++++++>-]<.>+" "++++[<------->-]<.") ; }

