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:
- 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(">+++++++++[<+++++++++>-]<+.>+++[<----->-]"
"<.-.++++.>++++++[<------>-]<--.>++++++++["
"<+++++++++>-]<+.>++[<++>-]<+.>++++++++[<-"
"-------->-]<------.>++++++[<++++++>-]<.>+"
"++++[<------->-]<.") ;
}