@alu0100966589/egg v2.1.3
EggLang
This is a project made for the subject "Procesadores de Lenguajes" at Universidad de La Laguna. The purpose is to get familiar with compiler design by extending the EGG language from Eloquent JS.
Student
- Carlos Domínguez García (alu0100966589@ull.edu.es)
Assignment part 2
- Add a REPL loop
- Allow curly and square brackets as function delimiters
- Test that setting an undefined variable is not allowed
- Test that using a number as a function is not allowed
- Test that the egg print function works as expected using sinon
- Allow negative indexes to arrays
- Add maps/hashes/dictionaries to egg
- Add AST node classes
Assignment part 3
- Allow
set
to accept multiple parameters treated as map/array indexes - Allow
element
to accept indexes/keys for nested arrays/maps - Allow binaries operators (+, -, *, /, &&, ||) to accept any number of operands
- Allow comparison operator (<=, <, > >=, ==) to accept any number of operands
- Allow map and array index by bracket operator (mapkey, arrayindex)
- Allow map and array index by dot operator (map.key, array.index)
- Add extended regular expressions to the language.
- Add a
require
function that accepts a file path and returns the result of executing that egg program - Use circleci
Assignment part 4
- Add objects to egg (with methods)
- Allow object properties to be written without ""
- Add spread operator to egg
- Add rest operator to egg
- Add a for loop like
for(counter, stop-expresion, increment-expresion, body)
- Add a map loop like
map(element, array, body)
Notes
- For the operators we are relying on JavaScript. So there is a lot of undefined behavior,
for example you can add arrays and the result will depend on how JavaScript handles that.
Also, the less than (
<
) operator, for example, returnstrue
on<(2, "3")
.
Grammar
expression: STRING
| NUMBER
| REGEX
| WORD (apply)*
apply: '(' (expression ',')* expression? ')'
WHITES = (
\\s # A Space
| [#;].* # A single line comment that starts with # or ;
| \\/\\* # A multiline comment that Starts with /*
(.|\\n)*? # There is anything in between
\\*\\/ # Ends with */
)*
STRING = "( # Must start with "
(?: # Simple parenthesis, not a capture group
[^"\\\\] # In between can appear anything that is not " nor \\
| \\\\. # Or anything that is escaped
)*
)" # Must end with "
NUMBER = (
[-+]? # Numbers can have sign
\\d* # Can have integer digits
\\.? # Can have decimal point
\\d+ # Can have decimal digits
(
[eE] # Can have exponents
[-+]?\\d+ # Exponents numbers can have sign
)?
)
REGEX = \\/ # Has to start with a slash
(
(?:
[^\\/\\\\] # In between can appear anything that is not an slash nor a backward slash
| \\\\. # or anything that is escaped (backward slash followed by a character)
)*
)
\\/ # Has to end with a slash
(
\\w*? # After the regex there can be options
\\b
)?
WORD = ( # A word is anything that is not
[^/\\s(),:"{}[\\]]+ # a slash a space, nor parenthesis,
) # nor a comma nor a double quote,
# nor square brackets nor curly brackets
AST
Expressions of type "VALUE" represent literal strings or numbers or regular expressions. Their
value
property contains the string or number or regex 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 | Regex}
| WORD{name: String}
| APPLY{operator: ast, args: [ ast ...]}
The AST of >(x, 5)
would be represented like this:
{
"type": "apply",
"operator": {
"type": "word",
"name": ">"
},
"args": [
{
"type": "word",
"name": "x"
},
{
"type": "value",
"value": 5
}
]
}
Examples
You can find program examples at the directory "examples"
Instalation
$ npm i -g @alu0100966589/egg
Eggecutable
See eggecutable help
egg -h
Compile egg source code to evm
egg -c egg_program.egg
Interpret evm
egg -i egg_ast.egg.evm
Compile and run egg source code
egg -r egg_program.egg
Enter the egg REPL (Read-Evaluate-Print-Loop)
egg
Run with plugins
The -p --plugins
option is used to specify a list of egg plugins separated by :
. These JavaScript
files are run before the egg parser and virtual machine.
Example of how to run the REPL with the require
and object
plugins
egg -p ../plugins/object.js:../plugins/require.js
# Note the ':' separating the paths
Example of how to run the example in examples/require.egg
with the require
and object
plugins
egg -p ../plugins/object.js:../plugins/require.js -r examples/require.egg