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

Content added Content deleted
mNo 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'expressions;

import extensions;
import extensions;
import extensions'scripting;
import extensions'scripting;

import extensions'dynamic'expressions;
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";

class TapeAssembler
class TapeAssembler
{
{
Stack theBrackets;
Stack theBrackets;
List<TapeExpression> theTape;
List<Expression> theTape;
constructor()
constructor()
{
{
theBrackets := new Stack();
theBrackets := new Stack();
theTape := new List<TapeExpression>();
theTape := new List<Expression>();
theTape.append(TapeExpression.Declaring("ptr"));
theTape.append(Expression.DeclareAndAssigning(
new ScopeVariable("ptr"),
theTape.append(TapeExpression.Assigning("ptr", TapeExpression.Constant(0)))
Expression.Constant(0)));
}
}
constructor(assembly_program)
constructor load(assembly_program)
<= ()
{
{
assembly_program(self)
assembly_program(self)
}
}
open()
open()
{
{
theBrackets.push(theTape);
theBrackets.push(theTape);
theTape := new List<TapeExpression>()
theTape := new List<Expression>();
}
}
close()
close()
{
{
var loop := TapeExpression.Loop(
var loop := Expression.Loop(
TapeExpression.MessageCall(
Expression.MessageCall(
TapeExpression.MessageCall(
new Message("notequal[2]"),
TapeExpression.Variable("tape"),
Expression.MessageCall(
"at",
new Message("at[2]"),
TapeExpression.Variable("ptr")
Expression.Variable("tape"),
Expression.Variable("ptr")
),
),
"notequal",
Expression.Constant($0)
TapeExpression.Constant($0)),
),
TapeExpression.Code(theTape.Value));
Expression.CodeBlock(theTape.Value));
theTape := theBrackets.pop();
theTape := theBrackets.pop();
theTape.append(loop)
theTape.append(loop)
}
}
input()
input()
{
{
theTape.append(TapeExpression.MessageCall(
theTape.append(
TapeExpression.Variable("tape"),
Expression.MessageCall(
"setAt",
new Message("setAt[3]"),
TapeExpression.Variable("ptr"),
Expression.Variable(new ScopeVariable("tape")),
TapeExpression.MessageCall(
Expression.Variable(new ScopeVariable("ptr")),
TapeExpression.Constant(console),
Expression.MessageCall(
"readChar"
new Message("readChar[1]"),
)))
Expression.Constant(console)
)
)
)
}
}
output()
output()
{
{
theTape.append(TapeExpression.MessageCall(
theTape.append(
Expression.MessageCall(
TapeExpression.Constant(console),
"write",
new Message("write[2]"),
TapeExpression.MessageCall(
Expression.Constant(console),
TapeExpression.Variable("tape"),
Expression.MessageCall(
"at",
new Message("at[2]"),
TapeExpression.Variable("ptr")
Expression.Variable(new ScopeVariable("tape")),
)))
Expression.Variable(new ScopeVariable("ptr"))
)
)
)
}
}
next()
next()
{
{
theTape.append(TapeExpression.Assigning(
theTape.append(
"ptr",
Expression.Assigning(
TapeExpression.MessageCall(
new ScopeVariable("ptr"),
TapeExpression.Variable("ptr"),
Expression.MessageCall(
"add",
new Message("add[2]"),
TapeExpression.Constant(1))))
Expression.Variable(new ScopeVariable("ptr")),
Expression.Constant(1))))
}
}
previous()
previous()
{
{
theTape.append(TapeExpression.Assigning(
theTape.append(
"ptr",
Expression.Assigning(
TapeExpression.MessageCall(
new ScopeVariable("ptr"),
TapeExpression.Variable("ptr"),
Expression.MessageCall(
"subtract",
new Message("subtract[2]"),
TapeExpression.Constant(1))))
Expression.Variable(new ScopeVariable("ptr")),
Expression.Constant(1))))
}
}
increase()
increase()
{
{
theTape.append(TapeExpression.MessageCall(
theTape.append(
TapeExpression.Variable("tape"),
Expression.MessageCall(
"setAt",
new Message("setAt[3]"),
TapeExpression.Variable("ptr"),
Expression.Variable("tape"),
TapeExpression.MessageCall(
Expression.Variable("ptr"),
TapeExpression.Constant(CharValue),
Expression.MessageCall(
"load",
new Message("load[2]"),
TapeExpression.MessageCall(
Expression.Constant(CharValue),
TapeExpression.MessageCall(
Expression.MessageCall(
TapeExpression.Constant(convertor),
new Message("add[2]"),
"toInt",
Expression.MessageCall(
TapeExpression.MessageCall(
new Message("toInt[2]"),
TapeExpression.Variable("tape"),
Expression.Constant(convertor),
"at",
Expression.MessageCall(
TapeExpression.Variable("ptr"))
new Message("at[2]"),
),
Expression.Variable("tape"),
"add",
Expression.Variable("ptr")
TapeExpression.Constant(1)))))
)
),
Expression.Constant(1)
)
)
));
}
}
decrease()
decrease()
{
{
theTape.append(TapeExpression.MessageCall(
theTape.append(
TapeExpression.Variable("tape"),
Expression.MessageCall(
"setAt",
new Message("setAt[3]"),
TapeExpression.Variable("ptr"),
Expression.Variable("tape"),
TapeExpression.MessageCall(
Expression.Variable("ptr"),
TapeExpression.Constant(CharValue),
Expression.MessageCall(
"load",
new Message("load[2]"),
TapeExpression.MessageCall(
Expression.Constant(CharValue),
TapeExpression.MessageCall(
Expression.MessageCall(
TapeExpression.Constant(convertor),
new Message("subtract[2]"),
"toInt",
Expression.MessageCall(
TapeExpression.MessageCall(
new Message("toInt[2]"),
TapeExpression.Variable("tape"),
Expression.Constant(convertor),
"at",
Expression.MessageCall(
TapeExpression.Variable("ptr"))
new Message("at[2]"),
),
Expression.Variable("tape"),
"subtract",
Expression.Variable("ptr")
TapeExpression.Constant(1)))))
)
),
Expression.Constant(1)
)
)
));
}
}
get()
compiled()
{
{
var program := TapeExpression.Singleton(
var program := DynamicSingleton.new(
TapeExpression.Method(
Expression.Method(
"eval",
"eval",
TapeExpression.Code(theTape.Value),
new ScopeVariable("tape"),
TapeExpression.Parameter("tape")));
Expression.CodeBlock(theTape.Value))).compiled();
var o := (program.compiled())();
^(tape){ program.eval(tape) }
^(tape){ o.eval(tape) }
}
}
}
}

const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
public program()
public program()
{
{
var bfAssemblyProgram := new ScriptEngine()
console.writeLine:bf_program;
.loadPath("asmrules.es")
.buildScript(bf_program);
var bfAssemblyProgram := new ScriptEngine()

.loadPath:"asmrules.es"
var bfProgram := TapeAssembler.load(bfAssemblyProgram).compiled();
.eval(bf_program);

var bfProgram := new TapeAssembler(bfAssemblyProgram).get();
var bfTape := Array.allocate(1024).populate:(n => $0);

var bfTape := Array.allocate(1024).populate:(int n => $0);
bfProgram(bfTape)
bfProgram(bfTape)
}</lang>
}</lang>
The grammar:
The grammar:
<lang elena>[[
<lang elena>[[
#grammar transform
#grammar build
#grammar cf
#grammar cf


#define start ::= <= ( > => commands <= " * system'dynamic'ClosureTape= " # ) =>;
#define start ::= <= system'dynamic'ClosureTape ( => command commands <= ) =>;
#define start ::= $eof;


#define commands ::= command commands;
#define commands ::= command commands;
Line 180: Line 194:
#define commands ::= $eof;
#define commands ::= $eof;


#define command ::= <= += " %""output[0]"" system'dynamic'MessageClosure ^""new[1]"" " => ".";
#define command ::= <= system'dynamic'MessageClosure ( "output[1]" ) => ".";
#define command ::= <= += " %""input[0]"" system'dynamic'MessageClosure ^""new[1]"" " => ",";
#define command ::= <= system'dynamic'MessageClosure ( "input[1]" ) => ",";
#define command ::= <= += " %""previous[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "<";
#define command ::= <= system'dynamic'MessageClosure ( "previous[1]" ) => "<";
#define command ::= <= += " %""next[0]"" system'dynamic'MessageClosure ^""new[1]"" " => ">";
#define command ::= <= system'dynamic'MessageClosure ( "next[1]" ) => ">";
#define command ::= <= += " %""increase[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "+";
#define command ::= <= system'dynamic'MessageClosure ( "increase[1]" ) => "+";
#define command ::= <= += " %""decrease[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "-";
#define command ::= <= system'dynamic'MessageClosure ( "decrease[1]" ) => "-";
#define command ::= <= += " %""open[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "[";
#define command ::= <= system'dynamic'MessageClosure ( "open[1]" ) => "[";
#define command ::= <= += " %""close[0]"" system'dynamic'MessageClosure ^""new[1]"" " => "]";
#define command ::= <= system'dynamic'MessageClosure ( "close[1]" ) => "]";


#define comment ::= " " comments;
#define comment ::= " " comments;
Line 201: Line 215:
{{out}}
{{out}}
<pre>
<pre>
ELENA VM 4.0.14 (C)2005-2019 by Alex Rakov
Initializing...
Done...
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Hello World!
Hello World!