@crguezl/eloquentjsegg
v1.2.6
Published
http://eloquentjavascript.net/11_language.html and https://ULL-ESIT-PL-1617.github.io/egg
Downloads
50
Readme
Instalation
$ npm i -g @crguezl/eloquentjsegg
...
Executables
egg
- Runs an egg program:
egg examples/two.egg
compiles the source onto the AST and interprets the AST
- Runs an egg program:
$ cat one.egg
do(
define(x, 4),
define(setx, fun(val,
set(x, val)
)
),
setx(50),
print(x)
)
$ egg one.egg
50
eggc
- Compiles the input program to produce a JSON containing the tree:
eggc examples/two.egg
produces the JSON fileexamples/two.egg.evm
- Compiles the input program to produce a JSON containing the tree:
evm
- Egg Virtual Machine. Runs the tree:
evm examples/two.egg.evm
- Egg Virtual Machine. Runs the tree:
$ eggc one.egg
$ ls -ltr | tail -1
-rw-r--r-- 1 casiano wheel 1656 19 mar 08:05 one.egg.evm
$ evm one.egg.evm
50
Here is the tree in JSON format for the former one.egg
program:
$ cat one.egg.evm
{
"type": "apply",
"operator": {
"type": "word",
"name": "do"
},
"args": [
{
"type": "apply",
"operator": {
"type": "word",
"name": "define"
},
"args": [
{
"type": "word",
"name": "x"
},
{
"type": "value",
"value": 4
}
]
},
{
"type": "apply",
"operator": {
"type": "word",
"name": "define"
},
"args": [
{
"type": "word",
"name": "setx"
},
{
"type": "apply",
"operator": {
"type": "word",
"name": "fun"
},
"args": [
{
"type": "word",
"name": "val"
},
{
"type": "apply",
"operator": {
"type": "word",
"name": "set"
},
"args": [
{
"type": "word",
"name": "x"
},
{
"type": "word",
"name": "val"
}
]
}
]
}
]
},
{
"type": "apply",
"operator": {
"type": "word",
"name": "setx"
},
"args": [
{
"type": "value",
"value": 50
}
]
},
{
"type": "apply",
"operator": {
"type": "word",
"name": "print"
},
"args": [
{
"type": "word",
"name": "x"
}
]
}
]
}
Using it as a library
> egg = require('@crguezl/eloquentjsegg')
{ run: [Function: run],
runFromFile: [Function: runFromFile],
runFromEVM: [Function: runFromEVM],
parser:
{ getProgram: [Function: getProgram],
lex: [Function: lex],
parse: [Function: parse],
parseApply: [Function: parseApply],
parseExpression: [Function: parseExpression],
parseFromFile: [Function: parseFromFile],
setProgram: [Function: setProgram] } }
> parser = egg.parser
> parser.parse('def(x,4)')
{ type: 'apply',
operator: { type: 'word', name: 'def' },
args: [ { type: 'word', name: 'x' }, { type: 'value', value: 4 } ] }
Grammar
expression: STRING
| NUMBER
| WORD apply
apply: /* vacio */
| '(' (expression ',')* expression? ')' apply
WHITES = /^(\s|[#;].*|\/\*(.|\n)*?\*\/)*/;
STRING = /^"((?:[^"\\]|\\.)*)"/;
NUMBER = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)/;
WORD = /^([^\s(),"]+)/;
AST
Expressions of type "VALUE" represent literal strings or numbers. Their
value
property contains the string or number value that they represent.Expressions of type "WORD" are used for identifiers (names). Such objects have a
name
property that holds the identifier’s name as a string.Finally, "APPLY" expressions represent applications. They have an
operator
property that refers to the expression that is being applied, and anargs
property that holds an array of argument expressions.
ast: VALUE{value: String | Number}
| WORD{name: String}
| APPLY{operator: ast, args: [ ast ...]}
The >(x, 5)
would be represented like this:
$ cat greater-x-5.egg
>(x,5)
$ ./eggc.js greater-x-5.egg
$ cat greater-x-5.egg.evm
{
"type": "apply",
"operator": {
"type": "word",
"name": ">"
},
"args": [
{
"type": "word",
"name": "x"
},
{
"type": "value",
"value": 5
}
]
}