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

From Rosetta Code
Content added Content deleted
No edit summary
No edit summary
Line 1: Line 1:
<lang elena>#define system.
<lang elena>#import system.
#define system'routines.
#import system'collections.
#import system'routines.
#define extensions'text.
#import system'dynamic.

#import extensions.
#import extensions'scripting.


// --- Tape ---
// --- Tape ---
Line 9: Line 13:
#field theArray.
#field theArray.
#field thePointer.
#field thePointer.
#field theBrackets.


#constructor new &length:aLength
#constructor new:aLength
[
[
theArray := Array new:aLength set &every: (&int:n) [ Integer new:0 ].
thePointer := Integer new:0.
thePointer := Integer new:0.

theArray := arrayControl new &length:aLength &each: n [ Integer new:0 ].
theBrackets := Stack new.
]
]

#method bf_tape = $self.


#method append
#method append
Line 39: Line 44:
]
]
#method input
#method push : bookmark
[
[
theBrackets push:bookmark.
(theArray@thePointer) write &int:(console readChar).
]
]
#method output
#method pop
=> theBrackets.
[
console write:(CharValue new:(theArray@thePointer)).
]

#method run : aLoop
[
control while:[ 0 < (theArray@thePointer) ] &do: [ aLoop eval:self ].
]
#method get = theArray@thePointer.
}

// --- LoopInterpreter ---

#class LoopInterpreter
{
#field theLoopBody.
#field theTape.
#constructor new &tape:aTape
[
theTape := aTape.
theLoopBody := String new.
]
#method bf_tape = theTape bf_tape.

#method append
[
theLoopBody += "+".
]
#method reduce
[
theLoopBody += "-".
]
#method next
[
theLoopBody += ">".
]

#method previous
[
theLoopBody += "<".
]
#method input
#method input
[
[
theArray@thePointer := console readChar toInt.
theLoopBody += ",".
]
]
#method output
#method output
[
[
theLoopBody += ".".
console write:((theArray@thePointer) toChar).
]
#method repeatUntil
[
theTape run: aTape [ interpreter'Interpreter new:aTape eval:theLoopBody ].
^ theTape.
]
]

#method check = theArray@thePointer != 0.
}
}


#symbol program =
// --- Interpreter ---
[
console
writeLine:"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.".
#var program := scriptEngine
load &path:"rules.es"
eval:"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.".


program eval:(BFTape new:1024).
#class Interpreter
].</lang>
{
The grammar:
#field theTape.
<lang elena>[[
#grammar cf


#define start ::= <= [ 2 %"system'dynamic'tapeOp.var&args$[]" => commands <= * system'dynamic'Tape ] =>;
#constructor new : aTape
[
theTape := aTape.
]


#define commands ::= command commands;
#method eval : anObject
#define commands ::= comment commands;
[
#define commands ::= $eof;
$self eval::anObject.
]
#method eval &literal:aLiteral
[
control foreach:aLiteral &do:$self.
]


#define command ::= <= %"output[0]" => ".";
#method eval &char:aChar
#define command ::= <= %"input[0]" => ",";
[
aChar =>
#define command ::= <= %"previous[0]" => "<";
">" ? [ theTape next ]
#define command ::= <= %"next[0]" => ">";
#define command ::= <= %"append[0]" => "+";
"<" ? [ theTape previous ]
"+" ? [ theTape append ]
#define command ::= <= %"reduce[0]" => "-";
#define command ::= <= -2 %"system'dynamic'tapeOp.ptr&args$[]" 1 %"system'dynamic'tapeOp.stack&args$[]" %"push[1]" => "[";
"-" ? [ theTape reduce ]
#define command ::= <= 0 %"system'dynamic'tapeOp.stack&args$[]" %"check[0]" 1 %"system'dynamic'tapeOp.stack&args$[]" %"pop[0]" %"system'dynamic'tapeOp.jumpif&args$[13]" => "]";
"." ? [ theTape output. ]
"," ? [ theTape input. ]
"[" ? [ theTape := LoopInterpreter new &tape:theTape. ]
"]" ? [ theTape := theTape repeatUntil. ].
]
}


#define comment ::= " " comments;
// --- Program ---
#define comment ::= "'" comments;
#define comment ::= "!" comments;
#define comment ::= $eol;


#define comments ::= $chr comments;
#symbol program =
#define comments ::= $eps;
[

('program'arguments length == 1)?
#mode symbolic;
[ console write:"Please provide the path to the file to interpret". #throw BreakException new. ].
]]</lang>
textFileControl forEachLine:('program'arguments@1) &do:(Interpreter new:(BFTape new &length:1024)).
].</lang>

Revision as of 13:22, 20 December 2016

<lang elena>#import system.

  1. import system'collections.
  2. import system'routines.
  3. import system'dynamic.
  1. import extensions.
  2. import extensions'scripting.

// --- Tape ---

  1. class BFTape

{

   #field theArray.
   #field thePointer.
   #field theBrackets.
   #constructor new:aLength
   [
       theArray := Array new:aLength set &every: (&int:n) [ Integer new:0 ].
       
       thePointer := Integer new:0.
       
       theBrackets := Stack new.
   ]
   #method append
   [
        (theArray@thePointer) += 1.
   ]
   
   #method reduce
   [
        (theArray@thePointer) -= 1.
   ]
   
   #method next
   [
       thePointer += 1.
   ]
   #method previous
   [
       thePointer -= 1.
   ]
   
   #method push : bookmark
   [
       theBrackets push:bookmark.
   ]
   
   #method pop
       => theBrackets.
   
   #method input
   [
       theArray@thePointer := console readChar toInt.
   ]
   
   #method output
   [
       console write:((theArray@thePointer) toChar).
   ]
   #method check = theArray@thePointer != 0.

}

  1. symbol program =

[

   console 
      writeLine:"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.".
                             
   #var program := scriptEngine 
       load &path:"rules.es"
       eval:"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.".
   program eval:(BFTape new:1024).

].</lang> The grammar: <lang elena>[[

  #grammar cf
  #define start      ::= <= [ 2 %"system'dynamic'tapeOp.var&args$[]" => commands <= * system'dynamic'Tape ] =>;
  #define commands   ::= command commands;
  #define commands   ::= comment commands;
  #define commands   ::= $eof;
  #define command    ::= <= %"output[0]" => ".";
  #define command    ::= <= %"input[0]" => ",";
  #define command    ::= <= %"previous[0]" => "<";
  #define command    ::= <= %"next[0]" => ">";
  #define command    ::= <= %"append[0]" => "+";
  #define command    ::= <= %"reduce[0]" => "-";
  #define command    ::= <= -2 %"system'dynamic'tapeOp.ptr&args$[]" 1 %"system'dynamic'tapeOp.stack&args$[]" %"push[1]" => "[";
  #define command    ::= <= 0 %"system'dynamic'tapeOp.stack&args$[]" %"check[0]" 1 %"system'dynamic'tapeOp.stack&args$[]" %"pop[0]" %"system'dynamic'tapeOp.jumpif&args$[13]" => "]";
  #define comment    ::= " " comments;
  #define comment    ::= "'" comments;
  #define comment    ::= "!" comments;
  #define comment    ::= $eol;
  #define comments   ::= $chr comments;
  #define comments   ::= $eps;
  #mode symbolic;

]]</lang>