Execute Brain****/Elena: Difference between revisions
Content added Content deleted
No edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
<lang elena>import system'collections |
<lang elena>import system'collections; |
||
import system'routines |
import system'routines; |
||
import system'dynamic |
import system'dynamic; |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
class TapeAssembler |
class TapeAssembler |
||
{ |
{ |
||
Stack theBrackets; |
|||
List<TapeExpression> theTape; |
|||
constructor |
constructor() |
||
{ |
|||
theBrackets := |
theBrackets := new Stack(); |
||
theTape := |
theTape := new List<TapeExpression>(); |
||
theTape |
theTape.append(TapeExpression.Declaring("ptr")); |
||
theTape |
theTape.append(TapeExpression.Assigning("ptr", TapeExpression.Constant(0))) |
||
} |
|||
constructor |
constructor(assembly_program) |
||
<= |
<= () |
||
{ |
|||
assembly_program( |
assembly_program(self) |
||
} |
|||
open |
open() |
||
{ |
|||
theBrackets |
theBrackets.push(theTape); |
||
theTape := |
theTape := new List<TapeExpression>() |
||
} |
|||
close |
close() |
||
{ |
|||
var loop := TapeExpression |
var loop := TapeExpression.Loop( |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
" |
"at", |
||
TapeExpression |
TapeExpression.Variable("ptr") |
||
), |
), |
||
"notequal", |
"notequal", |
||
TapeExpression |
TapeExpression.Constant($0)), |
||
TapeExpression |
TapeExpression.Code(theTape.Value)); |
||
theTape := theBrackets |
theTape := theBrackets.pop(); |
||
theTape |
theTape.append(loop) |
||
} |
|||
input |
input() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
"setAt", |
"setAt", |
||
TapeExpression |
TapeExpression.Variable("ptr"), |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(console), |
||
"readChar" |
"readChar" |
||
))) |
))) |
||
} |
|||
output |
output() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(console), |
||
"write", |
"write", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
" |
"at", |
||
TapeExpression |
TapeExpression.Variable("ptr") |
||
))) |
))) |
||
} |
|||
next |
next() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.Assigning( |
||
"ptr", |
"ptr", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("ptr"), |
||
"add", |
"add", |
||
TapeExpression |
TapeExpression.Constant(1)))) |
||
} |
|||
previous |
previous() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.Assigning( |
||
"ptr", |
"ptr", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("ptr"), |
||
"subtract", |
"subtract", |
||
TapeExpression |
TapeExpression.Constant(1)))) |
||
} |
|||
increase |
increase() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
"setAt", |
"setAt", |
||
TapeExpression |
TapeExpression.Variable("ptr"), |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(CharValue), |
||
" |
"load", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(convertor), |
||
"toInt", |
"toInt", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
" |
"at", |
||
TapeExpression |
TapeExpression.Variable("ptr")) |
||
), |
), |
||
"add", |
"add", |
||
TapeExpression |
TapeExpression.Constant(1))))) |
||
} |
|||
decrease |
decrease() |
||
{ |
|||
theTape |
theTape.append(TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
"setAt", |
"setAt", |
||
TapeExpression |
TapeExpression.Variable("ptr"), |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(CharValue), |
||
" |
"load", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Constant(convertor), |
||
"toInt", |
"toInt", |
||
TapeExpression |
TapeExpression.MessageCall( |
||
TapeExpression |
TapeExpression.Variable("tape"), |
||
" |
"at", |
||
TapeExpression |
TapeExpression.Variable("ptr")) |
||
), |
), |
||
"subtract", |
"subtract", |
||
TapeExpression |
TapeExpression.Constant(1))))) |
||
} |
|||
get |
get() |
||
{ |
|||
var program := TapeExpression |
var program := TapeExpression.Singleton( |
||
TapeExpression |
TapeExpression.Method( |
||
"eval", |
"eval", |
||
TapeExpression |
TapeExpression.Code(theTape.Value), |
||
TapeExpression |
TapeExpression.Parameter("tape"))); |
||
var o := (program |
var o := (program.compiled())(); |
||
^( |
^(tape){ o.eval(tape) } |
||
} |
|||
} |
} |
||
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." |
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."; |
||
public program() |
|||
{ |
|||
[ |
|||
console |
console.writeLine:bf_program; |
||
writeLine:bf_program. |
|||
⚫ | |||
.loadPath:"asmrules.es" |
|||
⚫ | |||
.eval(bf_program); |
|||
eval(bf_program). |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
The grammar: |
The grammar: |
||
<lang elena>[[ |
<lang elena>[[ |
||
Line 202: | Line 201: | ||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
ELENA VM |
ELENA VM 4.0.14 (C)2005-2019 by Alex Rakov |
||
Initializing... |
Initializing... |
||
Debug mode... |
|||
Done... |
Done... |
||
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. |
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. |
Revision as of 10:02, 15 March 2019
<lang elena>import system'collections; import system'routines; import system'dynamic;
import extensions; import extensions'scripting; import extensions'dynamic'expressions;
class TapeAssembler {
Stack theBrackets; List<TapeExpression> theTape; constructor() { theBrackets := new Stack(); theTape := new List<TapeExpression>(); theTape.append(TapeExpression.Declaring("ptr")); theTape.append(TapeExpression.Assigning("ptr", TapeExpression.Constant(0))) } constructor(assembly_program) <= () { assembly_program(self) } open() { theBrackets.push(theTape); theTape := new List<TapeExpression>() } close() { var loop := TapeExpression.Loop( TapeExpression.MessageCall( TapeExpression.MessageCall( TapeExpression.Variable("tape"), "at", TapeExpression.Variable("ptr") ), "notequal", TapeExpression.Constant($0)), TapeExpression.Code(theTape.Value)); theTape := theBrackets.pop(); theTape.append(loop) } input() { theTape.append(TapeExpression.MessageCall( TapeExpression.Variable("tape"), "setAt", TapeExpression.Variable("ptr"), TapeExpression.MessageCall( TapeExpression.Constant(console), "readChar" ))) } output() { theTape.append(TapeExpression.MessageCall( TapeExpression.Constant(console), "write", TapeExpression.MessageCall( TapeExpression.Variable("tape"), "at", TapeExpression.Variable("ptr") ))) } next() { theTape.append(TapeExpression.Assigning( "ptr", TapeExpression.MessageCall( TapeExpression.Variable("ptr"), "add", TapeExpression.Constant(1)))) } previous() { theTape.append(TapeExpression.Assigning( "ptr", TapeExpression.MessageCall( TapeExpression.Variable("ptr"), "subtract", TapeExpression.Constant(1)))) } increase() { theTape.append(TapeExpression.MessageCall( TapeExpression.Variable("tape"), "setAt", TapeExpression.Variable("ptr"), TapeExpression.MessageCall( TapeExpression.Constant(CharValue), "load", TapeExpression.MessageCall( TapeExpression.MessageCall( TapeExpression.Constant(convertor), "toInt", TapeExpression.MessageCall( TapeExpression.Variable("tape"), "at", TapeExpression.Variable("ptr")) ), "add", TapeExpression.Constant(1))))) } decrease() { theTape.append(TapeExpression.MessageCall( TapeExpression.Variable("tape"), "setAt", TapeExpression.Variable("ptr"), TapeExpression.MessageCall( TapeExpression.Constant(CharValue), "load", TapeExpression.MessageCall( TapeExpression.MessageCall( TapeExpression.Constant(convertor), "toInt", TapeExpression.MessageCall( TapeExpression.Variable("tape"), "at", TapeExpression.Variable("ptr")) ), "subtract", TapeExpression.Constant(1))))) } get() { var program := TapeExpression.Singleton( TapeExpression.Method( "eval", TapeExpression.Code(theTape.Value), TapeExpression.Parameter("tape"))); var o := (program.compiled())(); ^(tape){ o.eval(tape) } }
}
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
public program() {
console.writeLine:bf_program; var bfAssemblyProgram := new ScriptEngine() .loadPath:"asmrules.es" .eval(bf_program); var bfProgram := new TapeAssembler(bfAssemblyProgram).get(); var bfTape := Array.allocate(1024).populate:(int n => $0); bfProgram(bfTape)
}</lang> The grammar: <lang elena>[[
#grammar transform #grammar cf
#define start ::= <= ( > => commands <= " * system'dynamic'ClosureTape= " # ) =>;
#define commands ::= command commands; #define commands ::= comment commands; #define commands ::= $eof;
#define command ::= <= += " %""output[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "."; #define command ::= <= += " %""input[0]"" system'dynamic'MessageClosure ^""new[1]"" " => ","; #define command ::= <= += " %""previous[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "<"; #define command ::= <= += " %""next[0]"" system'dynamic'MessageClosure ^""new[1]"" " => ">"; #define command ::= <= += " %""increase[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "+"; #define command ::= <= += " %""decrease[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "-"; #define command ::= <= += " %""open[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "["; #define command ::= <= += " %""close[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "]";
#define comment ::= " " comments; #define comment ::= "'" comments; #define comment ::= "!" comments; #define comment ::= $eol;
#define comments ::= $chr comments; #define comments ::= $eps;
#mode symbolic;
]]</lang>
- Output:
ELENA VM 4.0.14 (C)2005-2019 by Alex Rakov Initializing... Done... ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. Hello World!