Execute Brain****/D

From Rosetta Code
Revision as of 01:19, 18 March 2008 by rosettacode>Badmadevil (+D)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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.
Works with: D version 2.007+

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>