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

From Rosetta Code
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.;
import extensions.
import extensions'scripting.
import extensions'dynamic'expressions.
 
class TapeAssembler
{
stackStack theBrackets.;
listList<TapeExpression> theTape.;
constructor new()
[{
theBrackets := Stack new. Stack();
theTape := listnew List<TapeExpression>().;
theTape .append(TapeExpression .Declaring("ptr")).;
theTape .append(TapeExpression .Assigning("ptr", TapeExpression .Constant(0))).
]}
constructor new : (assembly_program)
<= new;()
[{
assembly_program($self).
]}
open()
[{
theBrackets .push(theTape).;
theTape := listnew List<TapeExpression>().
]}
close()
[{
var loop := TapeExpression .Loop(
TapeExpression .MessageCall(
TapeExpression .MessageCall(
TapeExpression .Variable("tape"),
"getAtat",
TapeExpression .Variable("ptr")
),
"notequal",
TapeExpression .Constant($0)),
TapeExpression .Code(theTape array.Value)).;
theTape := theBrackets pop.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"),
"getAtat",
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),
"newload",
TapeExpression .MessageCall(
TapeExpression .MessageCall(
TapeExpression .Constant(convertor),
"toInt",
TapeExpression .MessageCall(
TapeExpression .Variable("tape"),
"getAtat",
TapeExpression .Variable("ptr"))
),
"add",
TapeExpression .Constant(1))))).
]}
decrease()
[{
theTape .append(TapeExpression .MessageCall(
TapeExpression .Variable("tape"),
"setAt",
TapeExpression .Variable("ptr"),
TapeExpression .MessageCall(
TapeExpression .Constant(CharValue),
"newload",
TapeExpression .MessageCall(
TapeExpression .MessageCall(
TapeExpression .Constant(convertor),
"toInt",
TapeExpression .MessageCall(
TapeExpression .Variable("tape"),
"getAtat",
TapeExpression .Variable("ptr"))
),
"subtract",
TapeExpression .Constant(1))))).
 
]}
get()
[{
var program := TapeExpression .Singleton(
TapeExpression .Method(
"eval",
TapeExpression .Code(theTape array.Value),
TapeExpression .Parameter("tape"))).;
var o := (program .compiled())().;
^(:tape) [{ o .eval(tape) ]}
]}
}
 
const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.".;
programpublic =program()
{
[
console .writeLine:bf_program;
writeLine:bf_program.
var bfAssemblyProgram := scriptEnginenew ScriptEngine()
 
.loadPath:"asmrules.es"
var bfAssemblyProgram := scriptEngine
load path:"asmrules.es"eval(bf_program);
eval(bf_program).
var bfProgram := TapeAssembler new TapeAssembler(bfAssemblyProgram); get.get();
 
var bfProgram := TapeAssembler new(bfAssemblyProgram); get.
var bfTape := Array new:.allocate(1024; ).populate(:n)<(int n =>( $0).;
 
var bfTape := Array new:1024; populate(:n)<int>($0).
bfProgram(bfTape).
 
].}</lang>
bfProgram(bfTape).
].</lang>
The grammar:
<lang elena>[[
Line 202 ⟶ 201:
{{out}}
<pre>
ELENA VM 34.20.1514 (C)2005-20172019 by Alex Rakov
Initializing...
Debug mode...
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!