Execute Brain****/Elena: Difference between revisions
Content added Content deleted
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
<lang elena># |
<lang elena>#import system. |
||
# |
#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 |
#constructor new:aLength |
||
[ |
[ |
||
theArray := Array new:aLength set &every: (&int:n) [ Integer new:0 ]. |
|||
thePointer := Integer new:0. |
thePointer := Integer new:0. |
||
theBrackets := Stack new. |
|||
] |
] |
||
#method bf_tape = $self. |
|||
#method append |
#method append |
||
Line 39: | Line 44: | ||
] |
] |
||
#method |
#method push : bookmark |
||
[ |
[ |
||
theBrackets push:bookmark. |
|||
(theArray@thePointer) write &int:(console readChar). |
|||
] |
] |
||
#method |
#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 |
||
[ |
[ |
||
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]" => ","; |
|||
[ |
|||
#define command ::= <= %"previous[0]" => "<"; |
|||
">" |
#define command ::= <= %"next[0]" => ">"; |
||
#define command ::= <= %"append[0]" => "+"; |
|||
"<" ? [ theTape previous ] |
|||
" |
#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.
- import system'collections.
- import system'routines.
- import system'dynamic.
- import extensions.
- import extensions'scripting.
// --- Tape ---
- 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.
}
- 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>