I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Execute Brain****/Elena

From Rosetta Code

ELENA 5.0:

import system'collections;
import system'routines;
import system'dynamic'expressions;
 
import extensions;
import extensions'scripting;
 
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
 
class TapeAssembler
{
Stack theBrackets;
List<Expression> theTape;
 
constructor()
{
theBrackets := new Stack();
theTape := new List<Expression>();
 
theTape.append(Expression.DeclareAndAssigning(
new ScopeVariable("ptr"),
Expression.Constant(0)));
}
 
constructor load(assembly_program)
{
assembly_program(self)
}
 
open()
{
theBrackets.push(theTape);
theTape := new List<Expression>();
}
 
close()
{
var loop := Expression.Loop(
Expression.MessageCall(
new Message("notequal[2]"),
Expression.MessageCall(
new Message("at[2]"),
Expression.Variable("tape"),
Expression.Variable("ptr")
),
Expression.Constant($0)
),
Expression.CodeBlock(theTape.Value));
 
theTape := theBrackets.pop();
theTape.append(loop)
}
 
input()
{
theTape.append(
Expression.MessageCall(
new Message("setAt[3]"),
Expression.Variable(new ScopeVariable("tape")),
Expression.Variable(new ScopeVariable("ptr")),
Expression.MessageCall(
new Message("readChar[1]"),
Expression.Constant(console)
)
)
)
}
 
output()
{
theTape.append(
Expression.MessageCall(
new Message("write[2]"),
Expression.Constant(console),
Expression.MessageCall(
new Message("at[2]"),
Expression.Variable(new ScopeVariable("tape")),
Expression.Variable(new ScopeVariable("ptr"))
)
)
)
}
 
next()
{
theTape.append(
Expression.Assigning(
new ScopeVariable("ptr"),
Expression.MessageCall(
new Message("add[2]"),
Expression.Variable(new ScopeVariable("ptr")),
Expression.Constant(1))))
}
 
previous()
{
theTape.append(
Expression.Assigning(
new ScopeVariable("ptr"),
Expression.MessageCall(
new Message("subtract[2]"),
Expression.Variable(new ScopeVariable("ptr")),
Expression.Constant(1))))
}
 
increase()
{
theTape.append(
Expression.MessageCall(
new Message("setAt[3]"),
Expression.Variable("tape"),
Expression.Variable("ptr"),
Expression.MessageCall(
new Message("load[2]"),
Expression.Constant(CharValue),
Expression.MessageCall(
new Message("add[2]"),
Expression.MessageCall(
new Message("toInt[2]"),
Expression.Constant(convertor),
Expression.MessageCall(
new Message("at[2]"),
Expression.Variable("tape"),
Expression.Variable("ptr")
)
),
Expression.Constant(1)
)
)
));
}
 
decrease()
{
theTape.append(
Expression.MessageCall(
new Message("setAt[3]"),
Expression.Variable("tape"),
Expression.Variable("ptr"),
Expression.MessageCall(
new Message("load[2]"),
Expression.Constant(CharValue),
Expression.MessageCall(
new Message("subtract[2]"),
Expression.MessageCall(
new Message("toInt[2]"),
Expression.Constant(convertor),
Expression.MessageCall(
new Message("at[2]"),
Expression.Variable("tape"),
Expression.Variable("ptr")
)
),
Expression.Constant(1)
)
)
));
}
 
compiled()
{
var program := DynamicSingleton.new(
Expression.Method(
"eval",
new ScopeVariable("tape"),
Expression.CodeBlock(theTape.Value))).compiled();
 
^(tape){ program.eval(tape) }
}
}
 
public program()
{
var bfAssemblyProgram := new ScriptEngine()
.loadPath("asmrules.es")
.buildScript(bf_program);
 
var bfProgram := TapeAssembler.load(bfAssemblyProgram).compiled();
 
var bfTape := Array.allocate(1024).populate:(n => $0);
 
bfProgram(bfTape)
}

The grammar:

[[
#grammar build
#grammar cf
 
#define start  ::= <= system'dynamic'ClosureTape ( => command commands <= ) =>;
#define start  ::= $eof;
 
#define commands  ::= command commands;
#define commands  ::= comment commands;
#define commands  ::= $eof;
 
#define command  ::= <= system'dynamic'MessageClosure ( "output[1]" ) => ".";
#define command  ::= <= system'dynamic'MessageClosure ( "input[1]" ) => ",";
#define command  ::= <= system'dynamic'MessageClosure ( "previous[1]" ) => "<";
#define command  ::= <= system'dynamic'MessageClosure ( "next[1]" ) => ">";
#define command  ::= <= system'dynamic'MessageClosure ( "increase[1]" ) => "+";
#define command  ::= <= system'dynamic'MessageClosure ( "decrease[1]" ) => "-";
#define command  ::= <= system'dynamic'MessageClosure ( "open[1]" ) => "[";
#define command  ::= <= system'dynamic'MessageClosure ( "close[1]" ) => "]";
 
#define comment  ::= " " comments;
#define comment  ::= "'" comments;
#define comment  ::= "!" comments;
#define comment  ::= $eol;
 
#define comments  ::= $chr comments;
#define comments  ::= $eps;
 
#mode symbolic;
]]
Output:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Hello World!