Requisitos

  1. Use el repo de GitHub dado por la asignación de esta tarea partiendo de la práctica anterior
  2. 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!
    
  3. Modifique la versión actual del lenguaje egg para que acepte como entrada este programa en examples/reto.egg en la rama reto 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])))
    }
    
  4. Introduzca una prueba en test/test.js que demuestre que una entrada como la de examples/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.js

  5. Introduzca una prueba en test/test.js que demuestre que una entrada como la de examples/number-as-fun-err.egg:

    4(5) ; Calling a number as a function
    

    produce una excepción

  6. Introduzca una prueba en test/test.js que demuestre que una entrada como la de examples/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

  7. Añada índices negativos (a la Ruby) para los arrays
  8. Añada mapas/hashes al lenguaje
  9. Modifique el AST para dar una solución OOP con clases: una clase Value, una clase Word, una clase Apply, ... de manera que cada clase de objeto dispone de un método evaluate.

    [~/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 el switch que estaba en lib/eggvm.js desaparece en esta versión

  10. Parta de este repo

Recursos