Requisitos
- Use el repo de GitHub dado por la asignación de esta tarea partiendo de la práctica anterior
- Haga que el ejecutable
egg
funcione como un bucle REPL cuando no se le proporciona un fichero de entrada[~/ull-pl1718-campus-virtual/tema3-analisis-sintactico/src/egg/crguezl-egg(private)]$ bin/egg.js > def(x, array(1,2,array(3,4))) # x = [1,2,[3,4]] [ 1, 2, [ 3, 4 ] ] > <-(x,2) # 3d element [ 3, 4 ] > <-(x,0) # 1st element 1 > # Pulsamos CTRL-D > goodbye!
- En este Vídeo Programando un bucle REPL para el lenguaje Egg explicamos como hacerlo
- Modifique la versión actual del lenguaje egg para que acepte como entrada este programa en
examples/reto.egg
en la ramareto
del repo:do { def(sum, ; function -> { nums, do { := (i, 0), # Creates a local variable i and sets to 0 := (s, 0), # Creates local var s and sets to 0 while { <(i, length(nums)), do { =(s, +(s, <-(nums, i))), =(i, +(i, 1)) } }, s } ) }, print(+("sum(array[1, 2, 3]) := ", sum(array[1, 2, 3]))) }
Introduzca una prueba en
test/test.js
que demuestre que una entrada como la deexamples/scope-err.egg
:do( set(x,9), print(x) # ReferenceError: Tried setting an undefined variable: x )
produce una excepción de este estilo:
SyntaxError: Unexpected input after reached the end of parsing 1: 5) ;
Estudie la API de Should.jsIntroduzca una prueba en
test/test.js
que demuestre que una entrada como la deexamples/number-as-fun-err.egg
:4(5) ; Calling a number as a function
produce una excepción
Introduzca una prueba en
test/test.js
que demuestre que una entrada como la deexamples/one.egg
:do( define(x, 4), define(setx, fun(val, set(x, val) ) ), setx(50), print(x) )
produce una salida en
stdout
de 50.- Utilice la técnica de stubbing. Test stubs are software components that simulate the behaviors of other software components that a module undergoing tests depends on. Haga stubbing sobre
console.log
- Algo como esto le puede ayudar con el stubbing:
describe("run", function() { let originalLog; beforeEach(function() { originalLog = console.log; console.log = function (...args) { ... }; }); // test code here afterEach(function() { ... }); it("testing one.egg with mocking of console.log", function() { ... } }
Si quiere saber mas sobre stubbing estudie la librería sinon
- Utilice la técnica de stubbing. Test stubs are software components that simulate the behaviors of other software components that a module undergoing tests depends on. Haga stubbing sobre
- Añada índices negativos (a la Ruby) para los arrays
- Añada mapas/hashes al lenguaje
Modifique el AST para dar una solución OOP con clases: una clase
Value
, una claseWord
, una claseApply
, ... de manera que cada clase de objeto dispone de un métodoevaluate
.[~/ull-pl1718-campus-virtual/tema3-analisis-sintactico/src/egg/crguezl-egg(private)]$ cat lib/ast.js // The AST classes const {specialForms} = require("./registry.js"); class Value { constructor(token) { ... } evaluate() { ... } } class Word { constructor(token) { ... } evaluate(env) { ... } } class Apply { constructor(tree) { ... } evaluate(env) { ... } } module.exports = {Value, Word, Apply};
Aisle estas clases en un fichero
lib/ast.js
:[~/ull-pl1718-campus-virtual/tema3-analisis-sintactico/src/egg/crguezl-egg(private)]$ tree -I 'node_modules|examples|egg-*' . ├── README.md ├── bin │ ├── egg.js │ ├── eggc.js │ └── evm.js ├── gulpfile.js ├── lib │ ├── ast.js # Clases para los nodos del AST │ ├── eggvm.js │ ├── environment.js # specialForms and topEnv initialization │ ├── parse.js │ └── registry.js # specialForms and topEnv maps ├── package-lock.json ├── package.json └── test └── test.js 3 directories, 14 files
La función
evaluate
con elswitch
que estaba enlib/eggvm.js
desaparece en esta versión- Parta de este repo
Recursos
- Eloquent JS: Chapter 11. Project: A Programming Language
- El lenguaje egg: repo en GitHub
- Repo interpreter-egg
- NodeJS Readline gist
- En el repo ULL-ESIT-PL-1617/interpreter-egg se muestra como hacer un bucle REPL
- XRegExp