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

From Rosetta Code
Content added Content deleted
No edit summary
imported>Arakov
mNo edit summary
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
ELENA 6.x:
<lang elena>import system'collections.
import system'routines.
<syntaxhighlight lang="elena">import system'collections;
import system'dynamic.
import system'routines;
import system'dynamic'expressions;

import extensions.
import extensions'scripting.
import extensions;
import extensions'dynamic'expressions.
import extensions'scripting;

const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";


class TapeAssembler
class TapeAssembler
{
{
stack theBrackets.
Stack _brackets;
list<TapeExpression> theTape.
List<Expression> _tape;
constructor new
constructor()
[
{
theBrackets := Stack new.
_brackets := new Stack();
theTape := list<TapeExpression>().
_tape := new List<Expression>();
theTape append(TapeExpression Declaring("ptr")).
_tape.append(Expression.DeclareAndAssigning(
"ptr",
theTape append(TapeExpression Assigning("ptr", TapeExpression Constant(0))).
Expression.Constant(0)));
]
}
constructor new : assembly_program
constructor load(assembly_program)
<= new;
{
assembly_program(self)
[
assembly_program($self).
}
]
open
open()
[
{
theBrackets push(theTape).
_brackets.push(_tape);
theTape := list<TapeExpression>().
_tape := 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(
"getAt",
new Message("at[2]"),
TapeExpression Variable("ptr")
Expression.Variable("tape"),
Expression.Variable("ptr")
),
),
"notequal",
Expression.Constant($0)
TapeExpression Constant($0)),
),
TapeExpression Code(theTape array)).
CodeblockExpression.new(_tape.Value));
theTape := theBrackets pop.
_tape := _brackets.pop();
theTape append(loop).
_tape.append(loop)
]
}
input
input()
[
{
theTape append(TapeExpression MessageCall(
_tape.append(
Expression.MessageCall(
TapeExpression Variable("tape"),
"setAt",
new Message("setAt[3]"),
TapeExpression Variable("ptr"),
Expression.Variable("tape"),
TapeExpression MessageCall(
Expression.Variable("ptr"),
TapeExpression Constant(console),
Expression.MessageCall(
"readChar"
new Message("readChar[1]"),
))).
Expression.Constant(console)
]
)
)
)
}
output
output()
[
{
theTape append(TapeExpression MessageCall(
_tape.append(
Expression.MessageCall(
TapeExpression Constant(console),
"write",
new Message("write[2]"),
TapeExpression MessageCall(
Expression.Constant(console),
TapeExpression Variable("tape"),
Expression.MessageCall(
"getAt",
new Message("at[2]"),
TapeExpression Variable("ptr")
Expression.Variable("tape"),
))).
Expression.Variable("ptr")
]
)
)
)
}
next
next()
[
{
theTape append(TapeExpression Assigning(
_tape.append(
"ptr",
Expression.Assigning(
TapeExpression MessageCall(
"ptr",
TapeExpression Variable("ptr"),
Expression.MessageCall(
"add",
new Message("add[2]"),
TapeExpression Constant(1)))).
Expression.Variable("ptr"),
Expression.Constant(1))))
]
}
previous
previous()
[
{
theTape append(TapeExpression Assigning(
_tape.append(
"ptr",
Expression.Assigning(
TapeExpression MessageCall(
"ptr",
TapeExpression Variable("ptr"),
Expression.MessageCall(
"subtract",
new Message("subtract[2]"),
TapeExpression Constant(1)))).
Expression.Variable("ptr"),
Expression.Constant(1))))
]
}
increase
increase()
[
{
theTape append(TapeExpression MessageCall(
_tape.append(
TapeExpression Variable("tape"),
Expression.MessageCall(
"setAt",
new Message("setAt[3]"),
TapeExpression Variable("ptr"),
Expression.Variable("tape"),
Expression.Variable("ptr"),
TapeExpression MessageCall(
TapeExpression Constant(CharValue),
Expression.MessageCall(
"new",
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(intConvertExt),
"getAt",
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(
_tape.append(
TapeExpression Variable("tape"),
Expression.MessageCall(
"setAt",
new Message("setAt[3]"),
TapeExpression Variable("ptr"),
Expression.Variable("tape"),
Expression.Variable("ptr"),
TapeExpression MessageCall(
TapeExpression Constant(CharValue),
Expression.MessageCall(
"new",
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(intConvertExt),
"getAt",
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.load(
TapeExpression Method(
Expression.Method(
"eval",
"eval",
TapeExpression Code(theTape array),
CodeblockExpression.new(_tape.Value),
TapeExpression Parameter("tape"))).
ScopeIdentifier.Variable("tape"))
).compile();
var o := (program compiled)().
^(tape){ program.eval(tape) }
}
^(:tape) [ o eval(tape) ]
]
}
}


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


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


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


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


bfProgram(bfTape).
bfProgram(bfTape)
}</syntaxhighlight>
].</lang>
The grammar:
The grammar:
<lang elena>[[
<syntaxhighlight lang="elena">[[
#grammar transform
#grammar build
#grammar cf
#grammar cf


#define start ::= <= ( > => commands <= " * system'dynamic'ClosureTape= " # ) =>;
#define start ::=
<=
system'dynamic'DynamicTape (
system'dynamic'AllocFunction ( "1" )
system'dynamic'LocalFunction ( "2" ) => command commands
<= ) =>;

#define start ::= $eof;


#define commands ::= command commands;
#define commands ::= command commands;
Line 181: Line 204:
#define commands ::= $eof;
#define commands ::= $eof;


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


#define comment ::= " " comments;
#define comment ::= " " comments;
Line 199: Line 222:


#mode symbolic;
#mode symbolic;
]]</lang>
]]</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
ELENA VM 3.2.15 (C)2005-2017 by Alex Rakov
Initializing...
Debug mode...
Done...
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Hello World!
Hello World!

Latest revision as of 10:41, 25 January 2024

ELENA 6.x:

import system'collections;
import system'routines;
import system'dynamic'expressions;

import extensions;
import extensions'scripting;

const bf_program = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";

class TapeAssembler
{    
    Stack            _brackets;
    List<Expression> _tape;
    
    constructor()
    {
        _brackets := new Stack();
        _tape := new List<Expression>();
        
        _tape.append(Expression.DeclareAndAssigning(
            "ptr",
            Expression.Constant(0)));
    }
    
    constructor load(assembly_program)
    {
        assembly_program(self)
    }    
    
    open()
    {
        _brackets.push(_tape);
        _tape := 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)
                          ),
                          CodeblockExpression.new(_tape.Value));
                          
        _tape := _brackets.pop();
        _tape.append(loop)                 
    }
    
    input()
    {
       _tape.append(
          Expression.MessageCall(
             new Message("setAt[3]"),
             Expression.Variable("tape"),
             Expression.Variable("ptr"),
             Expression.MessageCall(
                new Message("readChar[1]"),
                Expression.Constant(console)
             )
            )
        )
    }
    
    output()
    {
        _tape.append(
            Expression.MessageCall(
                 new Message("write[2]"),
                 Expression.Constant(console), 
                 Expression.MessageCall(
                   new Message("at[2]"),
                   Expression.Variable("tape"),
                   Expression.Variable("ptr")
                 )
            )
        )
    }
    
    next()
    {
        _tape.append(
            Expression.Assigning(
                "ptr",
                Expression.MessageCall(
                    new Message("add[2]"),
                    Expression.Variable("ptr"),
                    Expression.Constant(1))))
    }
    
    previous()
    {
        _tape.append(
            Expression.Assigning(
                "ptr",
                Expression.MessageCall(
                    new Message("subtract[2]"),
                    Expression.Variable("ptr"),
                    Expression.Constant(1))))
    }
    
    increase()
    {
        _tape.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(intConvertExt),
                            Expression.MessageCall(
                                new Message("at[2]"),
                                Expression.Variable("tape"),
                                Expression.Variable("ptr")
                            )
                        ),
                        Expression.Constant(1)
                    )
                )
            ));
    }
    
    decrease()
    {
        _tape.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(intConvertExt),
                            Expression.MessageCall(
                                new Message("at[2]"),
                                Expression.Variable("tape"),
                                Expression.Variable("ptr")
                            )
                        ),
                        Expression.Constant(1)
                    )
                )
            ));
    }
    
    compiled()
    {
        var program := DynamicSingleton.load(
                    Expression.Method(
                       "eval",
                       CodeblockExpression.new(_tape.Value),
                       ScopeIdentifier.Variable("tape"))
                    ).compile();           
                   
        ^(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);

    console.writeLine(bf_program);

    bfProgram(bfTape)
}

The grammar:

[[
   #grammar build
   #grammar cf

   #define start      ::= 
<= 
	system'dynamic'DynamicTape ( 
		system'dynamic'AllocFunction ( "1" ) 
		system'dynamic'LocalFunction ( "2" ) => command commands 
<=      ) =>;

   #define start      ::= $eof;

   #define commands   ::= command commands;
   #define commands   ::= comment commands;
   #define commands   ::= $eof;

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

   #define comment    ::= " " comments;
   #define comment    ::= "'" comments;
   #define comment    ::= "!" comments;
   #define comment    ::= $eol;

   #define comments   ::= $chr comments;
   #define comments   ::= $eps;

   #mode symbolic;
]]
Output:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Hello World!