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

From Rosetta Code
Content added Content deleted
mNo edit summary
mNo edit summary
Line 1:
<lang elena>import system'collections;
import system'routines;
import system'dynamic'expressions;
 
import extensions;
import extensions'scripting;
 
import extensions'dynamic'expressions;
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
 
class TapeAssembler
{
Stack theBrackets;
List<TapeExpressionExpression> theTape;
constructor()
{
theBrackets := new Stack();
theTape := new List<TapeExpressionExpression>();
<= ()
theTape.append(TapeExpressionExpression.DeclaringDeclareAndAssigning("ptr"));
new ScopeVariable("ptr"),
theTape.append(TapeExpression.Assigning("ptr", TapeExpression.Constant(0)))
Expression.Constant(0)));
}
constructor load(assembly_program)
<= ()
{
assembly_program(self)
}
open()
{
theBrackets.push(theTape);
theTape := new List<TapeExpressionExpression>();
}
close()
{
var loop := TapeExpressionExpression.Loop(
TapeExpressionExpression.MessageCall(
TapeExpression.MessageCallnew Message("notequal[2]"),
TapeExpressionExpression.VariableMessageCall("tape"),
new Message("at[2]"),
TapeExpressionExpression.Variable("ptrtape"),
TapeExpressionExpression.ConstantVariable(console"ptr"),
),
"notequal",Expression.Constant($0)
TapeExpression.Constant($0)),
TapeExpressionExpression.CodeCodeBlock(theTape.Value));
theTape := theBrackets.pop();
theTape.append(loop)
}
input()
{
theTape.append(TapeExpression.MessageCall(
TapeExpressionExpression.VariableMessageCall("tape"),
new Message("setAt[3]"),
TapeExpressionExpression.Variable(new ScopeVariable("ptrtape")),
Expression.Variable(new TapeExpression.MessageCallScopeVariable("ptr")),
TapeExpressionExpression.ConstantMessageCall(console),
new Message("readChar[1]"),
))Expression.Constant(console)
)
)
)
}
output()
{
theTape.append(TapeExpression.MessageCall(
Expression.MessageCall(
TapeExpression.Constant(console),
new Message("write[2]"),
TapeExpressionExpression.MessageCallConstant(console),
TapeExpressionExpression.VariableMessageCall("tape"),
new Message("at[2]"),
TapeExpressionExpression.Variable(new ScopeVariable("ptrtape")),
Expression.Variable(new )ScopeVariable("ptr"))
)
)
)
}
next()
{
theTape.append(TapeExpression.Assigning(
"ptr",Expression.Assigning(
TapeExpression.MessageCall new ScopeVariable("ptr"),
TapeExpressionExpression.VariableMessageCall("ptr"),
new Message("add[2]"),
TapeExpression Expression.ConstantVariable(1))new ScopeVariable("ptr")),
Expression.Constant(1))))
}
previous()
{
theTape.append(TapeExpression.Assigning(
"ptr",Expression.Assigning(
TapeExpression.MessageCall new ScopeVariable("ptr"),
TapeExpressionExpression.VariableMessageCall("ptr"),
new Message("subtract[2]"),
TapeExpression Expression.ConstantVariable(1))new ScopeVariable("ptr")),
Expression.Constant(1))))
}
increase()
{
theTape.append(TapeExpression.MessageCall(
TapeExpressionExpression.VariableMessageCall("tape"),
new Message("setAt[3]"), "setAt",
TapeExpressionExpression.Variable("ptrtape"),
TapeExpressionExpression.MessageCallVariable("ptr"),
TapeExpressionExpression.ConstantMessageCall(CharValue),
new Message("load[2]"), "load",
TapeExpressionExpression.MessageCallConstant(CharValue),
TapeExpressionExpression.MessageCall(
new TapeExpression.ConstantMessage(convertor"add[2]"),
Expression.MessageCall( "toInt",
new Message("toInt[2]"), TapeExpression.MessageCall(
TapeExpressionExpression.VariableConstant("tape"convertor),
"at",Expression.MessageCall(
new TapeExpression.VariableMessage("ptrat[2]")),
Expression.Variable("tape"),
Expression.Variable("addptr",)
TapeExpression.Constant(1)))))
),
Expression.Constant(1)
)
)
));
}
decrease()
{
theTape.append(TapeExpression.MessageCall(
TapeExpressionExpression.VariableMessageCall("tape"),
new Message("setAt[3]"), "setAt",
TapeExpressionExpression.Variable("ptrtape"),
TapeExpressionExpression.MessageCallVariable("ptr"),
TapeExpressionExpression.ConstantMessageCall(CharValue),
new Message("load[2]"), "load",
TapeExpressionExpression.MessageCallConstant(CharValue),
TapeExpressionExpression.MessageCall(
new TapeExpression.ConstantMessage(convertor"subtract[2]"),
Expression.MessageCall( "toInt",
new Message("toInt[2]"), TapeExpression.MessageCall(
TapeExpressionExpression.VariableConstant("tape"convertor),
"at",Expression.MessageCall(
new TapeExpression.VariableMessage("ptrat[2]")),
Expression.Variable("tape"),
Expression.Variable("subtractptr",)
TapeExpression.Constant(1)))))
),
Expression.Constant(1)
)
)
));
}
getcompiled()
{
var program := TapeExpressionDynamicSingleton.Singletonnew(
TapeExpression Expression.Method(
"eval",
TapeExpression.Code new ScopeVariable(theTape.Value"tape"),
TapeExpression Expression.ParameterCodeBlock("tape"theTape.Value))).compiled();
var^(tape){ o := (program.compiledeval(tape))(); }
^(tape){ o.eval(tape) }
}
}
 
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
public program()
{
var bfAssemblyProgram := new ScriptEngine()
console.writeLine:bf_program;
.loadPath:("asmrules.es")
console .writeLine:buildScript(bf_program);
var bfAssemblyProgram := new ScriptEngine()
 
.loadPath:"asmrules.es"
var bfProgram := TapeAssembler.load(bfAssemblyProgram).compiled();
.eval(bf_program);
 
var bfProgrambfTape := new TapeAssemblerArray.allocate(bfAssemblyProgram1024).getpopulate:(n => $0);
 
var bfTape := Array.allocate(1024).populate:(int n => $0);
bfProgram(bfTape)
}</lang>
The grammar:
<lang elena>[[
#grammar transformbuild
#grammar cf
 
#define start ::= <= system'dynamic'ClosureTape ( > => command commands <= " * system'dynamic'ClosureTape= " # ) =>;
#define start ::= $eof;
 
#define commands ::= command commands;
Line 180 ⟶ 194:
#define commands ::= $eof;
 
#define command ::= <= += " %""output[0]"" system'dynamic'MessageClosure ^( ""newoutput[1]"" " ) => ".";
#define command ::= <= += " %""input[0]"" system'dynamic'MessageClosure ^( ""newinput[1]"" " ) => ",";
#define command ::= <= += " %""previous[0]"" system'dynamic'MessageClosure ^( ""newprevious[1]"" ") => "<";
#define command ::= <= += " %""next[0]"" system'dynamic'MessageClosure ^( ""newnext[1]"" " ) => ">";
#define command ::= <= += " %""increase[0]"" system'dynamic'MessageClosure ^( ""newincrease[1]"" ") => "+";
#define command ::= <= += " %""decrease[0]"" system'dynamic'MessageClosure ^( ""newdecrease[1]"" ") => "-";
#define command ::= <= += " %""open[0]"" system'dynamic'MessageClosure ^( ""newopen[1]"" " ) => "[";
#define command ::= <= += " %""close[0]"" system'dynamic'MessageClosure ^( ""newclose[1]"" " ) => "]";
 
#define comment ::= " " comments;
Line 201 ⟶ 215:
{{out}}
<pre>
ELENA VM 4.0.14 (C)2005-2019 by Alex Rakov
Initializing...
Done...
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
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!