Execute Brain****/D
Execute Brain****/D is an implementation of Brainf***.
Other implementations of Brainf***.
Execute Brain****/D is part of RCBF. You may find other members of RCBF at Category:RCBF.
An implementation of Rosetta Code BrainF*ck interpreter in D.
Implement notes:
- Need D version 2.007+, because closure support is required (it should compiled in D1, but run abnormally if brackets/loop-command is in the BF source);
- Memory is represented by associative array, so that negative address is allowed, not efficient though;
- Input and output are in character mode, rather than in numerical;
- Nesting level is checked during parsing, and if loops/brackets are not matched, error is threw before executing the codes.
<d>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(">+++++++++[<+++++++++>-]<+.>+++[<----->-]" "<.-.++++.>++++++[<------>-]<--.>++++++++[" "<+++++++++>-]<+.>++[<++>-]<+.>++++++++[<-" "-------->-]<------.>++++++[<++++++>-]<.>+" "++++[<------->-]<.") ;
}</d>