Execute Brain****/Elena: Difference between revisions
Content added Content deleted
No edit summary |
mNo edit summary |
||
Line 1:
<lang elena>import system'collections
import system'routines
import system'dynamic
▲import extensions.
▲import extensions'scripting.
▲import extensions'dynamic'expressions.
class TapeAssembler
{
constructor
theBrackets :=
theTape :=
theTape
theTape
constructor
<=
assembly_program(
open()
theBrackets
theTape :=
close()
var loop := TapeExpression
TapeExpression
TapeExpression
TapeExpression
"
TapeExpression
),
"notequal",
TapeExpression
TapeExpression
theTape := theBrackets
theTape
input()
theTape
TapeExpression
"setAt",
TapeExpression
TapeExpression
TapeExpression
"readChar"
)))
output()
theTape
TapeExpression
"write",
TapeExpression
TapeExpression
"
TapeExpression
)))
next()
theTape
"ptr",
TapeExpression
TapeExpression
"add",
TapeExpression
previous()
theTape
"ptr",
TapeExpression
TapeExpression
"subtract",
TapeExpression
increase()
theTape
TapeExpression
"setAt",
TapeExpression
TapeExpression
TapeExpression
"
TapeExpression
TapeExpression
TapeExpression
"toInt",
TapeExpression
TapeExpression
"
TapeExpression
),
"add",
TapeExpression
decrease()
theTape
TapeExpression
"setAt",
TapeExpression
TapeExpression
TapeExpression
"
TapeExpression
TapeExpression
TapeExpression
"toInt",
TapeExpression
TapeExpression
"
TapeExpression
),
"subtract",
TapeExpression
get()
var program := TapeExpression
TapeExpression
"eval",
TapeExpression
TapeExpression
var o := (program
^(
}
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
{
console
.loadPath:"asmrules.es"
▲ var bfAssemblyProgram := scriptEngine
▲ var bfProgram := TapeAssembler new(bfAssemblyProgram); get.
▲ var bfTape := Array new:1024; populate(:n)<int>($0).
▲ bfProgram(bfTape).
▲].</lang>
The grammar:
<lang elena>[[
Line 202 ⟶ 201:
{{out}}
<pre>
ELENA VM
Initializing...
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!