Execute Brain****/D: Difference between revisions

Version 1 updated
(Move 2 alternate implementations from Execute Brain****. http://rosettacode.org/mw/index.php?title=Execute_Brain****&action=history)
(Version 1 updated)
Line 1:
{{implementation|Brainf***}}{{collection|RCBF}}
 
== Implementation=Version 1 ===
{{works with|D|2.007+}}
An implementation of Rosetta Code [[Brainfuck|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.
<lang d>import core.stdc.stdio, core.stdc.stdlib, std.file;
<lang d>module rcbf ;
import std.file, std.c.stdio ;
 
alias void delegate() Act ;
 
__gshared char[int] mem ; // memory
__gshared int ptr ; // mem pointer
__gshared 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['.'] = { printfputchar("%c", mem[ptr]) ; } ;
cmd[','] = { printf("%c", mem[ptr] = getch()) ; flushall ; } ;
int c = getc(stdin);
if if(ccc in== cmdEOF)
break exit(1);
mem[ptr] = cast(char)c;
} ;
}
 
void bf(in 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 ; 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") ;
}
 
while (cp < code.length) {
void main(string[] args) { // if no argument, demo code will be run, else
if(args.length > 1) // thecc get argumentsnext arecommand treatedand ascode filenamespointer ofcp bfis sourceadvanced
foreach(f ; args[1..$]) // andcc executed= one by one.code[cp];
try bf(cast(string)read(f)) cp++;
catch (Exception e) printf switch ("%*s",e.msgcc) ;{
case '[':
else
nested++ ;
bf(">+++++++++[<+++++++++>-]<+.>+++[<----->-]"
acts ~= bfAct() ; // begin inner loop
"<.-.++++.>++++++[<------>-]<--.>++++++++["
break;
"<+++++++++>-]<+.>++[<++>-]<+.>++++++++[<-"
 
"-------->-]<------.>++++++[<++++++>-]<.>+"
"++++[<------->-]<.") ; case ']':
nested--;
if (nested < 0)
if(nested != 0) throw new Exception("Unmatched Loops") ;
return {
while (mem[ptr]) {
foreach (x; acts)
x();
case ']': }
};
 
default:
if (cc in cmd)
acts ~= cmd[cc] ;
// else ignore other non-command char
}
}
 
return {
return { foreach (x ; acts){x();} } ;
x();
};
}
 
// reset memory
mem = null;
mem[0] = 0;
ptr = 0;
 
Act run = bfAct() ;
if (nested != 0)
if(--nested < 0) throw new Exception("Unmatched Loops") ;
run() ; // execute the whole bf program
printf("\n") ;
}
 
</lang>
 
void main(in string[] args) {
void main(string[] args) { // if no argument, demo code will be run, else the first
// argument is treated as filename of bf source and executed.
if (args.length > 1) {
bf(readText(args[1]));
} else {
bf(">+++++++++[<+++++++++>-]<+.>+++[<----->-]"
" <.-.++++.>++++++[<------>-]<--.>++++++++["
" <+++++++++>-]<+.>++[<++>-]<+.>++++++++[<-"
" -------->-]<------.>++++++[<++++++>-]<.>+"
++++[<------->-]<.");
}
}</lang>
 
== Implementation 2 ==