<< Volver

Los lenguajes SL y CL

Muchos lenguajes de programación se implementan mediante transformación (o compilación) a lenguajes intermedios de más bajo nivel. Así mismo, en esta tarea, hay dos lenguajes: SL (Surface Language) y CL (Core Language).

  • SL es un lenguaje tipado con funciones de primera clase, números y expresiones sobre éstos (suma e if0), impresión de caracteres y with.
  • CL es un lenguaje no tipado, como los vistos en clase, que cuenta con lo mismo que SL, excepto por with.

Un programa SL se ejecuta mediante una transformación a CL. En el código entregado, esta transformación es bastante trivial: convierte los nodos del AST del programa SL en nodos del AST de un programa CL. Su único rol es borrar la información de tipado, y convertir el with en una aplicación de lambda (CL no incluye with).

Los archivos que les entregamos incluyen: core-base.rkt, surface-base.rkt y env.rkt.

  • para CL: definición de la sintaxis, AST, parser, e intérprete
  • para SL: definición de la sintaxis, AST, parser, typechecker y transformación a CL

Note que el typechecker de SL opera de manera distinta a lo que vimos en la tarea anterior: la información de tipo se hace persistente en cada nodo del AST. Es decir, cada expresión (nodo del AST) lleva consigo información de su tipo, la cual se inicializa al valor #f tras realizar el parseo, y se rellena con el tipo correcto tras llamar a la función type-ast. A continuación les ilustramos el resultado de cada paso, desde el parseo hasta la ejecución final.

> (parse-sl '{+ 1 2})
(sadd #f (snum 1) (snum 2))
 
> (type-ast (parse-sl '{+ 1 2}))
(sadd (TNum) (snum 1) (snum 2))
 
> (transform (type-ast (parse-sl '{+ 1 2})))
(add (num 1) (num 2))
 
> (interp-top (transform (type-ast (parse-sl '{+ 1 2}))))
3

Antes de empezar la tarea, prueben ambos lenguajes y las distintas funciones provistas para parsear, typecheckear, tranformar, ejecutar, etc. En particular, miren el tipado y la transformación de programas con with y funciones. Por último, noten que la impresión de caracteres retorna el mismo valor que está siendo impreso, de manera que puede ser utilizada dentro de otras expresiones sin problema.

> (run-cl '{+ 10 {printn {+ 2 3}}})
5     ; valor impreso -- ¿cómo testear esto? vea la parte 1!
15    ; valor final del programa