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

From Rosetta Code
Content added Content deleted
No 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;
import extensions;
import extensions'scripting;
import extensions'dynamic'expressions;
import extensions.
import extensions'scripting.
import extensions'dynamic'expressions.

class TapeAssembler
class TapeAssembler
{
{
stack theBrackets.
Stack theBrackets;
list<TapeExpression> theTape.
List<TapeExpression> theTape;
constructor new
constructor()
[
{
theBrackets := Stack new.
theBrackets := new Stack();
theTape := list<TapeExpression>().
theTape := new List<TapeExpression>();
theTape append(TapeExpression Declaring("ptr")).
theTape.append(TapeExpression.Declaring("ptr"));
theTape append(TapeExpression Assigning("ptr", TapeExpression Constant(0))).
theTape.append(TapeExpression.Assigning("ptr", TapeExpression.Constant(0)))
]
}
constructor new : assembly_program
constructor(assembly_program)
<= new;
<= ()
[
{
assembly_program($self).
assembly_program(self)
]
}
open
open()
[
{
theBrackets push(theTape).
theBrackets.push(theTape);
theTape := list<TapeExpression>().
theTape := new List<TapeExpression>()
]
}
close
close()
[
{
var loop := TapeExpression Loop(
var loop := TapeExpression.Loop(
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"getAt",
"at",
TapeExpression Variable("ptr")
TapeExpression.Variable("ptr")
),
),
"notequal",
"notequal",
TapeExpression Constant($0)),
TapeExpression.Constant($0)),
TapeExpression Code(theTape array)).
TapeExpression.Code(theTape.Value));
theTape := theBrackets pop.
theTape := theBrackets.pop();
theTape append(loop).
theTape.append(loop)
]
}
input
input()
[
{
theTape append(TapeExpression MessageCall(
theTape.append(TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"setAt",
"setAt",
TapeExpression Variable("ptr"),
TapeExpression.Variable("ptr"),
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Constant(console),
TapeExpression.Constant(console),
"readChar"
"readChar"
))).
)))
]
}
output
output()
[
{
theTape append(TapeExpression MessageCall(
theTape.append(TapeExpression.MessageCall(
TapeExpression Constant(console),
TapeExpression.Constant(console),
"write",
"write",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"getAt",
"at",
TapeExpression Variable("ptr")
TapeExpression.Variable("ptr")
))).
)))
]
}
next
next()
[
{
theTape append(TapeExpression Assigning(
theTape.append(TapeExpression.Assigning(
"ptr",
"ptr",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("ptr"),
TapeExpression.Variable("ptr"),
"add",
"add",
TapeExpression Constant(1)))).
TapeExpression.Constant(1))))
]
}
previous
previous()
[
{
theTape append(TapeExpression Assigning(
theTape.append(TapeExpression.Assigning(
"ptr",
"ptr",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("ptr"),
TapeExpression.Variable("ptr"),
"subtract",
"subtract",
TapeExpression Constant(1)))).
TapeExpression.Constant(1))))
]
}
increase
increase()
[
{
theTape append(TapeExpression MessageCall(
theTape.append(TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"setAt",
"setAt",
TapeExpression Variable("ptr"),
TapeExpression.Variable("ptr"),
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Constant(CharValue),
TapeExpression.Constant(CharValue),
"new",
"load",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Constant(convertor),
TapeExpression.Constant(convertor),
"toInt",
"toInt",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"getAt",
"at",
TapeExpression Variable("ptr"))
TapeExpression.Variable("ptr"))
),
),
"add",
"add",
TapeExpression Constant(1))))).
TapeExpression.Constant(1)))))
]
}
decrease
decrease()
[
{
theTape append(TapeExpression MessageCall(
theTape.append(TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"setAt",
"setAt",
TapeExpression Variable("ptr"),
TapeExpression.Variable("ptr"),
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Constant(CharValue),
TapeExpression.Constant(CharValue),
"new",
"load",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Constant(convertor),
TapeExpression.Constant(convertor),
"toInt",
"toInt",
TapeExpression MessageCall(
TapeExpression.MessageCall(
TapeExpression Variable("tape"),
TapeExpression.Variable("tape"),
"getAt",
"at",
TapeExpression Variable("ptr"))
TapeExpression.Variable("ptr"))
),
),
"subtract",
"subtract",
TapeExpression Constant(1))))).
TapeExpression.Constant(1)))))

]
}
get
get()
[
{
var program := TapeExpression Singleton(
var program := TapeExpression.Singleton(
TapeExpression Method(
TapeExpression.Method(
"eval",
"eval",
TapeExpression Code(theTape array),
TapeExpression.Code(theTape.Value),
TapeExpression Parameter("tape"))).
TapeExpression.Parameter("tape")));
var o := (program compiled)().
var o := (program.compiled())();
^(:tape) [ o eval(tape) ]
^(tape){ o.eval(tape) }
]
}
}
}

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

.loadPath:"asmrules.es"
var bfAssemblyProgram := scriptEngine
load path:"asmrules.es";
.eval(bf_program);
eval(bf_program).
var bfProgram := new TapeAssembler(bfAssemblyProgram).get();

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

var bfTape := Array new:1024; populate(:n)<int>($0).
bfProgram(bfTape)

}</lang>
bfProgram(bfTape).
].</lang>
The grammar:
The grammar:
<lang elena>[[
<lang elena>[[
Line 202: Line 201:
{{out}}
{{out}}
<pre>
<pre>
ELENA VM 3.2.15 (C)2005-2017 by Alex Rakov
ELENA VM 4.0.14 (C)2005-2019 by Alex Rakov
Initializing...
Initializing...
Debug mode...
Done...
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!