@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
setto accept multiple parameters treated as map/array indexes - Allow
elementto 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
requirefunction 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, returnstrueon<(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 bracketsAST
Expressions of type "VALUE" represent literal strings or numbers or regular expressions. Their
valueproperty contains the string or number or regex value that they represent.Expressions of type "WORD" are used for identifiers (names). Such objects have a
nameproperty that holds the identifier’s name as a string.Finally, "APPLY" expressions represent applications. They have an
operatorproperty that refers to the expression that is being applied, and anargsproperty 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/eggEggecutable
See eggecutable help
egg -hCompile egg source code to evm
egg -c egg_program.eggInterpret evm
egg -i egg_ast.egg.evmCompile and run egg source code
egg -r egg_program.eggEnter the egg REPL (Read-Evaluate-Print-Loop)
eggRun 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 pathsExample 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