====== Tarea 5 ======
Esta tarea se distribuye con dos ficheros start.rkt y tests.rkt (mediante U-Cursos). Considere las definiciones del archivo start.rkt y escriba sus funciones en él. Escriba sus tests en el archivo tests.rkt adjunto. Ambos ficheros deben ser entregados vía U-Cursos. Los tests forman parte de su evaluación!
Consulte las normas de entrega de tareas en http://pleiad.cl/teaching/cc4101.
En esta tarea extenderemos un lenguaje base para soportar clases y objetos. El lenguaje base tiene números, booleanos y operaciones sobre ellos. Además contiene expressiones ''if'', ''seqn'', ''local'' y ''define'', pero no tiene soporte para funciones. Tome un tiempo de experimentar con el lenguaje base antes de comenzar a implementar las siguientes extensiones.
===== (3.0) Clases y objetos como valores =====
A continuación se presenta la sintáxis del lenguaje extendido:
::= ... (expresiones del lenguage entregado) ...
| (class *)
| (new )
| (get )
| (set )
| (send *)
| this
::= (field )
| (method (*) )
Donde:
* ''class'' se usa para crear una nueva clase (anónima), con definiciones de campos y metodos
* ''new'' permite instanciar una clase dada
* ''get'' y ''set'' permiten acceder a, o cambiar, el campo de un objeto dado
* ''send'' permite invocar un método de un objeto dado, con 0 o más argumentos
* ''this'' permite acceder al objeto actual—solamente es válido usar ''this'' dentro del cuerpo de un método
* una definición de campo incluye una expresión de inicialización, la cual se tiene que ejecutar nuevamente para cada instancia creada
* una definición de método especifica 0 a más parámetros, y su cuerpo
Tanto clases como objetos son valores. Usted deber decidir los attributos que tendrán sus respectivos nodos en el AST. Modifique el parser y el interprete para soportar el lenguaje extendido.
Nota:
* El acceso a un campo inexistente de un objeto debe arrojar el error "field not found".
* La invocación de un método inexistente debe lanzar el error "method not found".
Veamos algunos ejemplos de clases y objetos en accción:
> (run-val (local
[(define c (class
(field x 1)
(field y 2)
(method sum (z) (+ (get this x) (+ (get this y) z)))
(method set-x (val) (set this x val))))
(define o (new c))]
(seqn
(send o set-x (+ 1 3))
(+ (send o sum 3) (get o y)))))
11
;clases son valores
> (run-val '(local
[(define A
(class
(method apply (c)
(send (new c) m))))
(define ins (new A))]
(send ins apply (class
(field x 2)
(method m () (get this x))))))
2
===== (3.0) Herencia Simple =====
Extienda su lenguaje con herencia simple, incluyendo field shadowing y llamados con super. Estudie la sección de herencia del OOPLAI(([[http://users.dcc.uchile.cl/~etanter/ooplai/Inheritance.html|Inheritance]])) para aclarar la semántica deseada.
La extensión de la sintáxis es:
::= ... (todo lo anterior) ...
| ( class <: * )
| ( super * )
Se agrega una forma para crear clases, especificando su superclase. Sigue válido crear una clase sin especificar su superclase. En este caso extenderá de la clase raíz ''Object'', que tendrá que definir.
- (1.0) Implemente la búsqueda de métodos (([[http://users.dcc.uchile.cl/~etanter/ooplai/Inheritance.html#%28part._.Method_.Lookup%29|Method Lookup]])) correspondiente a la herencia
> (run-val '(local
[(define c1 (class
(method f (z) (< z 7))))
(define c (class <: c1))
(define o (new c))]
(send o f 20)))
#f
- (1.0) Implemente el soporte para llamados con super (([[http://users.dcc.uchile.cl/~etanter/ooplai/Inheritance.html#%28part._.Super_.Sends%29| Super sends]])).
;; llamada a super de metodo no definido en el padre directo
(run-val '(local
[(define c2 (class
(method h (x) (+ x 1))))
(define c1 (class <: c2
(method f () #f)))
(define c (class <: c1
(method g () (super h 10))))
(define o (new c))]
(send o g)))
11
- (1.0) Implemente la semántica de field shadowing (([[http://users.dcc.uchile.cl/~etanter/ooplai/Inheritance.html#%28part._.Field_.Shadowing%29| Field Shadowing]]))para sobreescritura de campos.
> (run-val '(local
[(define A (class
[field x 1]
[field y 0]
[method ax () (get this x)]))
(define B (class <: A
[field x 2]
[method bx () (get this x)]))
(define b (new B))]
(send b ax)))
1
Nota:
* Los llamados con ''super'' solo pueden ocurrir desde los métodos.
* No se olvide incluir a la clase ''Object'' en el ambiente inicial de ejecución
===== (0.5)[Opcional] Codificando lambdas con objetos =====
En esta extensión incorporamos lambdas a nuestro lenguaje. A diferencia de lo visto durante el curso, en esta ocasión no daremos una interpretaremos directamente las funciones. Usted deber ingeniar una manera de codificar una lambda como un objeto. Esto significa que no puede modificar el interprete para soportar funciones, ni aplicaciones de funciones. Las modificaciones que debe hacer son en el parser.
::= ...
| (fun (*) )
| ( *)
Ejemplo de uso:
> (run-val '(local
[(define f (fun (x)
(+ x x)))]
(f 5)))
10