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; |
|||
⚫ | |||
class TapeAssembler |
class TapeAssembler |
||
{ |
{ |
||
Stack |
Stack theBrackets; |
||
List< |
List<Expression> theTape; |
||
constructor() |
constructor() |
||
{ |
{ |
||
theBrackets := new Stack(); |
theBrackets := new Stack(); |
||
theTape := new List< |
theTape := new List<Expression>(); |
||
⚫ | |||
theTape.append( |
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< |
theTape := new List<Expression>(); |
||
} |
} |
||
close() |
close() |
||
{ |
{ |
||
var loop := |
var loop := Expression.Loop( |
||
Expression.MessageCall( |
|||
new Message("notequal[2]"), |
|||
Expression.MessageCall( |
|||
"at", |
new Message("at[2]"), |
||
Expression.Variable("tape"), |
|||
⚫ | |||
), |
), |
||
Expression.Constant($0) |
|||
), |
|||
Expression.CodeBlock(theTape.Value)); |
|||
theTape := theBrackets.pop(); |
theTape := theBrackets.pop(); |
||
theTape.append(loop) |
theTape.append(loop) |
||
} |
} |
||
input() |
input() |
||
{ |
{ |
||
theTape.append |
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() |
output() |
||
{ |
{ |
||
theTape.append |
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() |
next() |
||
{ |
{ |
||
theTape.append |
theTape.append( |
||
Expression.Assigning( |
|||
new ScopeVariable("ptr"), |
|||
Expression.MessageCall( |
|||
"add", |
new Message("add[2]"), |
||
Expression.Variable(new ScopeVariable("ptr")), |
|||
Expression.Constant(1)))) |
|||
} |
} |
||
previous() |
previous() |
||
{ |
{ |
||
theTape.append |
theTape.append( |
||
Expression.Assigning( |
|||
new ScopeVariable("ptr"), |
|||
Expression.MessageCall( |
|||
"subtract", |
new Message("subtract[2]"), |
||
Expression.Variable(new ScopeVariable("ptr")), |
|||
Expression.Constant(1)))) |
|||
} |
} |
||
increase() |
increase() |
||
{ |
{ |
||
theTape.append |
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() |
decrease() |
||
{ |
{ |
||
theTape.append |
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 := |
var program := DynamicSingleton.new( |
||
Expression.Method( |
|||
"eval", |
"eval", |
||
new ScopeVariable("tape"), |
|||
Expression.CodeBlock(theTape.Value))).compiled(); |
|||
^(tape){ program.eval(tape) } |
|||
^(tape){ o.eval(tape) } |
|||
} |
} |
||
} |
} |
||
⚫ | |||
public program() |
public program() |
||
{ |
{ |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
var bfProgram := TapeAssembler.load(bfAssemblyProgram).compiled(); |
|||
.eval(bf_program); |
|||
var |
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 |
#grammar build |
||
#grammar cf |
#grammar cf |
||
#define start ::= <= ( |
#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 ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "output[1]" ) => "."; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "input[1]" ) => ","; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "previous[1]" ) => "<"; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "next[1]" ) => ">"; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "increase[1]" ) => "+"; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "decrease[1]" ) => "-"; |
||
#define command ::= <= |
#define command ::= <= system'dynamic'MessageClosure ( "open[1]" ) => "["; |
||
#define command ::= <= |
#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! |
Revision as of 07:23, 27 March 2020
<lang elena>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)
}</lang> The grammar: <lang elena>[[
#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;
]]</lang>
- Output:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. Hello World!