Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Programación Orientada a Objetos (Clase 2) Eduardo Bonelli Departamento de Computación FCEyN UBA 12 de junio, 2006 Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta La clase pasada Introdujimos los conceptos fundamentales del paradigma Objetos, clases, modelo de cómputo, herencia Polimorfismo de subclase y dynamic method dispatch Super y static method dispatch Los ilustramos con ejemplos en el lenguaje SOOL Es una extensión de SFL con orientación a objetos Lenguaje con pocas construcciones pero representativo del paradigma Estamos completando la visión del paradigma usando Smalltalk (Práctica) Hoy: Vamos a implementar un intérprete para SOOL Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Intérprete para SOOL Seguimos el capı́tulo 5 del texto “Essentials of Programming Languages” (ver bibliografı́a de la materia en la web para más detalles sobre este texto) Con la diferencia de que usamos Haskell en lugar de Scheme La implementación es una extensión del intérprete ya visto para el lenguaje funcional con asignación SFL Priorizaremos claridad por sobre eficiencia Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Sintaxis concreta de SOOL Extendemos SFL con las siguientes producciones: <program> ::= <class-decl>∗ <expr> <class-decl> ::= class <ident> extends <ident> field <ident>∗ <method-decl>∗ <method-decl> ::= method <ident> (<ident>∗(,) ) <expr> <expr> ::= ... | new <ident> (<expr>∗(,) ) <expr> ::= send <expr> <ident> (<expr>∗(,) ) <expr> ::= super <ident> (<expr>∗(,) ) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Sintaxis concreta de SOOL Observar que la nueva gramática: Incluye una sentencia begin-end <expr> :: = begin <expr> {; <expr>}∗ end Las expresiones se evalúan en orden y se retorna el valor de la última de ellas Incluye primitiva de construcción de listas <primitive> ::= ... | list Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Ejemplo class point extends object field x field y method initialize (initx,inity) begin set x = initx; set y = inity end method move (dx,dy) begin set x = +(x,dx); set y = +(y,dy) end method get_location () list(x,y) let p = new point(3,4) in p Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Sintaxis abstracta Un programa consiste en una lista de declaraciones de clases y una expresión inicial data Program = Pgm [ClassDecl] Exp La expresión inicial es una expresión de SFL extendida con tres nuevas construcciones: NewExp, SendExp y SuperExp data Exp = ... | NewExp Symbol [Exp] | SendExp Exp Symbol [Exp] | SuperExp Symbol [Exp] type Symbol = String Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Repaso de la clase pasada Sintaxis concreta Sintaxis abstracta Sintaxis abstracta Las declaraciones de clase, campo y método son autoexplicativas data ClassDecl = Class {classDecl2name::Symbol, classDecl2super::Symbol, classDecl2fields::[FieldDecl], classDecl2methods::[MethodDecl]} data FieldDecl = Field {fieldDecl2name::Symbol} data MethodDecl = Method {methodDecl2name::Symbol, methodDecl2params::[Symbol], methodDecl2body::Exp} Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Valores expresados y denotados Recordar Valores expresados: valores que pueden resultar de la evaluación de las expresiones del lenguaje Valores denotados: valores que se pueden asignar a las variables En SOOL tenemos Valores Expr. = Number + ProcVal + Obj + List(Valores Expr.) Valores Den. = Ref(Valores Expr.) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Valores expresados y denotados Valores Expr. = Number + ProcVal + Obj + List(Valores Expr.) Valores Den. = Ref(Valores Expr.) data ExpressedValue = | | | Nro Int Closure [Symbol] Exp Env Object [Part] Lista [ExpressedValue] type Reference = Int -- referencias como enteros Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Intérprete de programas El intérprete de programas toma un programa como entrada y devuelve el resultado junto con el store (ie. la memoria) data Answer = AnAnswer {value::ExpressedValue, store::Store} evalProgram :: Program -> Answer evalProgram (Pgm classDecls body) = evalExpression body emptyEnv emptyStore classDecls La lista de declaraciones de clases se utilizará en su representación original (ie. como tipo algebraico) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Intérprete de expresiones El intérprete de expresiones se extiende con tres nuevos casos, uno por cada uno de los nuevos constructores NewExp: creación de un nuevo objeto SendExp: envı́o de mensaje SuperExp: llamado super Asimismo, además de la expresión a interpretar, el entorno y el store, ahora también toma la lista de declaraciones de clase como entrada (pues precisará consultarla) Esto se podrı́a evitar en Scheme almacenando las declaraciones de clases en una variable global, en Haskell se podrı́an usar mónadas Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Intérprete de expresiones evalExpression::Exp->Env->Store->[ClassDecl]->Answer evalExpression (LitExp n) env st cds = AnAnswer (Nro n) st evalExpression (VarExp id) env st cds = AnAnswer (applyEnv env st id) st ... evalExpression (NewExp className exps) env st cds = ... evalExpression (SendExp recip methodName rands) env st cds = ... evalExpression (SuperExp methodName rands) env st cds = ... El objetivo de la clase de hoy es completar esta definición Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Valores expresados y denotados Intérprete de programas Intérprete de expresiones Lookup de declaraciones Lookup de declaraciones de clase y método En ocasiones tendremos que ir a buscar la declaración de una clase o método conociendo el nombre de la misma (o del mismo) Para ello usaremos la siguiente función lookupDecl :: [a] -> (a->Symbol) -> Symbol -> Maybe a lookupDecl [] f nombre = Nothing lookupDecl (decl:decls) f nombre | (f decl) == nombre = Just decl | otherwise = lookupDecl decls f nombre Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Representación de objetos Los objetos se representan como una lista de partes donde cada parte se corresponde con una clase en la cadena de herencia consiste de un nombre de clase y un entorno (que, junto con el store, contiene el estado de la parte) la primera parte de la lista representa el punto más bajo de la cadena de clases a medida que avanzamos en la lista, nos acercamos más a la cima de la jerarquı́a data ExpressedValue = ... | Object [Part] data Part = APart {part2name::Symbol, part2env::Env} Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos La función newObject toma como entrada: un nombre de clase, un store y una lista de declaraciones de clases arroja como salida: un objeto Dado que la creación de un objeto puede exigir la alocación de espacio en la memoria (ie. el store), newObject precisa el store como entrada (también va a retornar, junto con el objeto creado, el store actualizado) Veamos un ejemplo antes de presentar el código de newObject Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Ejemplo class c1 extends object class c2 extends c1 field x,y field y method initialize () method initialize () begin begin set x = 11; super initialize (); set y = 12 set y = 22 end end class c3 extends c2 field x, z method initialize () begin super intialize (); set x = 31; set z = 32 end let o3 = new c3() in send o3 m1(7,8) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Ejemplo (cont.) La expresión new c3() va a retornar un nuevo objeto o3 representado por la lista de partes que se ilustra debajo: o3 APart "c3" APart 1 2 x z Referencia Expressed Value (sin "Nro") "c2" APart "c1" 3 4 y 1 2 3 4 5 31 32 22 11 12 Eduardo Bonelli APart 5 "object" EmptyEnv x Store Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - newObject La función newObject crea un objeto Dado que la creación de un objeto puede exigir la alocación de espacio en la memoria (ie. el store), newObject retorna junto con el objeto creado el store actualizado La función auxiliar constructParts construye las partes que conforman el nuevo objeto newObject :: Symbol -> Store -> [ClassDecl] -> Answer newObject className st cds = let (parts,s1) = constructParts className st cds in AnAnswer (Object parts) s1 Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - constructParts Esta función construye una lista de partes, donde cada parte se corresponde con una clase de la cadena de jerarquı́a El primer argumento indica la clase a partir de la cual se quiere crear las partes (se subirá por la jerarquı́a comenzando desde allı́) En el caso en que este argumento sea "object" tenemos constructParts::Symbol->Store->[ClassDecl]->([Part],Store) constructParts "object" st cds = ([APart "object" emptyEnv],st) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - constructParts En los demás casos tenemos constructParts className st cds = case (lookupDecl cds classDecl2name className) of Nothing -> error ("Clase inexistente"++ className) (Just cDecl) -> let campos = map fieldDecl2name (classDecl2fields cDecl) entorno = extendEnv campos (nextAvail st) emptyEnv s1 = extendStore st (replicate (length campos) (Nro 1)) (xs,s2)= constructParts (classDecl2super cDecl) s1 cds in ((APart (classDecl2name cDecl) entorno):xs,s2) Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones El intérprete de expresiones se extiende de la siguiente manera para la creación de objetos 1 2 3 4 Se evalúan los argumentos que se le pasarán al método intialize Se crea el objeto propiamente dicho usando newObject (tal como acabamos de ver) Se busca el método initialize y se lo ejecuta Se retorna el objeto actualizado y el store Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones evalExpression (NewExp className exps) env st cds = let (args,s1) = evalExpressions exps env st cds (AnAnswer obj s2) = newObject className s1 cds (AnAnswer _ s3) = findMethodAndApply "initialize" className obj (reverse args) s2 cds in AnAnswer obj s3 Se evalúan los argumentos que se le pasarán al método intialize Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones evalExpression (NewExp className exps) env st cds = let (args,s1) = evalExpressions exps env st cds (AnAnswer obj s2) = newObject className s1 cds (AnAnswer _ s3) = findMethodAndApply "initialize" className obj (reverse args) s2 cds in AnAnswer obj s3 Se crea el objeto propiamente dicho usando newObject Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones evalExpression (NewExp className exps) env st cds = let (args,s1) = evalExpressions exps env st cds (AnAnswer obj s2) = newObject className s1 cds (AnAnswer _ s3) = findMethodAndApply "initialize" className obj (reverse args) s2 cds in AnAnswer obj s3 Se busca el método initialize y se lo ejecuta Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones evalExpression (NewExp className exps) env st cds = let (args,s1) = evalExpressions exps env st cds (AnAnswer obj s2) = newObject className s1 cds (AnAnswer _ s3) = findMethodAndApply "initialize" className obj (reverse args) s2 cds in AnAnswer obj s3 Se retorna el objeto actualizado y el store Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Representación de objetos Creación de objetos Intérprete de expresiones Creación de objetos - intérprete de expresiones evalExpression (NewExp className exps) env st cds = let (args,s1) = evalExpressions exps env st cds (AnAnswer obj s2) = newObject className s1 cds (AnAnswer _ s3) = findMethodAndApply "initialize" className obj (reverse args) s2 cds in AnAnswer obj s3 En breve veremos la función findMethodAndApply Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super LLamados a métodos Para evaluar un send 1 evaluamos los operandos 2 evaluamos la expresión receptora 3 buscamos el método asociado con el nombre entre las declaraciones de método del objeto y aplicamos el método con los argumentos evalExpression (SendExp recip methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds (AnAnswer obj s2) = evalExpression recipient env s1 cd in findMethodAndApply methodName (object2className obj) obj (reverse args) s2 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super LLamados a métodos Para evaluar un send 1 evaluamos los operandos 2 evaluamos la expresión receptora 3 buscamos el método asociado con el nombre entre las declaraciones de método del objeto y aplicamos el método con los argumentos evalExpression (SendExp recip methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds (AnAnswer obj s2) = evalExpression recipient env s1 cd in findMethodAndApply methodName (object2className obj) obj (reverse args) s2 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super LLamados a métodos Para evaluar un send 1 evaluamos los operandos 2 evaluamos la expresión receptora 3 buscamos el método asociado con el nombre entre las declaraciones de método del objeto y aplicamos el método con los argumentos evalExpression (SendExp recip methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds (AnAnswer obj s2) = evalExpression recipient env s1 cd in findMethodAndApply methodName (object2className obj) obj (reverse args) s2 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply Esta función deberı́a buscar clases a través de la cadena de herencia hasta hallar la clase que declara el método que coincida con methodName al encontrarla, llamar a applyMethod con 1 2 3 4 5 6 la declaración de método que se halló la declaración de la clase (se usará solamente para acceder al nombre de la misma y al de su superclase) self (el objeto receptor) los argumentos el store la lista de declaraciones de clases NB: abreviamos findMethodAndApply como fMAA Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply Comenzamos con el caso sencillo: si, en su búsqueda, fMAA llega a la clase object el método no existe fMAA:: Symbol -> Symbol -> ExpressedValue -> [ExpressedValue] -> Store -> [ClassDecl] -> Answer fMAA methodName "object" (Object parts) args st cds = error ("metodo no hallado"++methodName) En caso contrario, debe fijarse en las declaraciones de métodos de la clase si encuentra una declaración para methodName Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply 1 obtener declaración de clase cDecl para hostName 2 buscar declaración de método para methodName en cDecl 3 Si no está, seguir buscando en superclase 4 Si está, aplicar el método fMAA methodName hostName self@(Object parts) args st cds = case (lookupDecl cds classDecl2name hostName) of Nothing -> error ("clase no hallada"++hostName) (Just cDecl) -> case (lookupDecl (classDecl2methods cDecl) methodDecl2name methodName) of Nothing -> fMAA methodName (classDecl2super cDecl) self args st cds (Just mDecl) -> applyMethod mDecl cDecl self args st Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply 1 obtener declaración de clase cDecl para hostName 2 buscar declaración de método para methodName en cDecl 3 Si no está, seguir buscando en superclase 4 Si está, aplicar el método fMAA methodName hostName self@(Object parts) args st cds = case (lookupDecl cds classDecl2name hostName) of Nothing -> error ("clase no hallada"++hostName) (Just cDecl) -> case (lookupDecl (classDecl2methods cDecl) methodDecl2name methodName) of Nothing -> fMAA methodName (classDecl2super cDecl) self args st cds (Just mDecl) -> applyMethod mDecl cDecl self args st Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply 1 obtener declaración de clase cDecl para hostName 2 buscar declaración de método para methodName en cDecl 3 Si no está, seguir buscando en superclase 4 Si está, aplicar el método fMAA methodName hostName self@(Object parts) args st cds = case (lookupDecl cds classDecl2name hostName) of Nothing -> error ("clase no hallada"++hostName) (Just cDecl) -> case (lookupDecl (classDecl2methods cDecl) methodDecl2name methodName) of Nothing -> fMAA methodName (classDecl2super cDecl) self args st cds (Just mDecl) -> applyMethod mDecl cDecl self args st Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Implementando findMethodAndApply 1 obtener declaración de clase cDecl para hostName 2 buscar declaración de método para methodName en cDecl 3 Si no está, seguir buscando en superclase 4 Si está, aplicar el método fMAA methodName hostName self@(Object parts) args st cds = case (lookupDecl cds classDecl2name hostName) of Nothing -> error ("clase no hallada"++hostName) (Just cDecl) -> case (lookupDecl (classDecl2methods cDecl) methodDecl2name methodName) of Nothing -> fMAA methodName (classDecl2super cDecl) self args st cds (Just mDecl) -> applyMethod mDecl cDecl self args st Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Aplicación de un método Aplicar un método es parecido a aplicar una clausura: el cuerpo del método debe ser ejecutado bajo un entorno en el que cada variable es ligada a su valor apropiado. El entorno debe contar con bindings para: %super: nombre de una clase (la clase padre de la clase anfitriona del método cuyo código se está por ejecutar) self: un objeto (el receptor del mensaje cuyo código se está por ejecutar) los parámetros formales todos los campos que son visibles desde el código del método actualmente por ejecutarse Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Aplicación de un método Los campos que son visibles del método por ejecutarse son aquellas partes del objeto receptor comenzando desde la clase anfitriona Volvamos al ejemplo que vimos antes Si ejecutamos send o3 m2(), los campos visibles desde m2 son aquellos de o3 que comienzan en ls clase anfitriona de m2 (c2) y todos los que hereda de sus ancestors Observar que m2 no puede ver el campo x de c3 Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Ejemplo class c1 extends object class c2 extends c1 field x,y field y method initialize () method initialize () begin begin set x = 11; super initialize (); set y = 12 set y = 22 end end class c3 extends c2 method m2() x field x, z method initialize () begin super intialize (); set x = 31; set z = 32 end let o3 = new c3() in send o3 m2() Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Aplicación de un método Por lo tanto, el nombre de una clase determina una vista de un objeto Los campos visibles desde c son todos aquellos declarados en c más aquellos que se heredan La función que calcula la vista de un objeto es viewObjectAs viewObjectAs :: [Part] -> Symbol -> [Part] viewObjectAs parts className = dropWhile (not . (==className) . part2name) parts Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Aplicación de un método A partir de la vista de un objeto podemos construir un entorno (environment) que consiste en un rib por cada parte. A modo de función auxiliar usamos composeEnv que permite componer entornos buildFieldEnv :: [Part] -> Env buildFieldEnv ps = foldr (\part-> composeEnv (part2env part)) emptyEnv ps Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Aplicación de un método Ahora estamos en condiciones de completar applyMethod applyMethod :: MethodDecl -> ClassDecl -> ExpressedValue -> [ExpressedValue] -> Store -> [ClassDecl] -> Answer applyMethod mDecl cDecl self@(Object parts) args st cds = let ids = methodDecl2params mDecl s1 = extendStore st ((Object [APart (classDecl2super cDecl) emptyEnv]):self:args) in evalExpression (methodDecl2body mDecl) (extendEnv ("%super":"self":ids) (nextAvail st) (buildFieldEnv (viewObjectAs parts (classDecl2name cDecl)) s1 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Llamada super Un llamado super es igual que un llamado a método salvo que el lookup comienza en la superclase de la clase anfitriona de la expresión evalExpression (SuperExp methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds obj = applyEnv env s1 "self" (Object [APart super _]) = applyEnv env s1 "%super" in fMAA methodName super obj (reverse args) s1 cds Vamos a analizar este caso, paso por paso Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Llamada super 1 Evaluar argumentos 2 Obtener objeto receptor (self) del entorno 3 Obtener nombre de superclase del entorno 4 Buscar método a ejecutar (methodName) comenzando búsqueda desde la superclase evalExpression (SuperExp methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds obj = applyEnv env s1 "self" (Object [APart super _]) = applyEnv env s1 "%super" in fMAA methodName super obj (reverse args) s1 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Llamada super 1 Evaluar argumentos 2 Obtener objeto receptor (self) del entorno 3 Obtener nombre de superclase del entorno 4 Buscar método a ejecutar (methodName) comenzando búsqueda desde la superclase evalExpression (SuperExp methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds obj = applyEnv env s1 "self" (Object [APart super _]) = applyEnv env s1 "%super" in fMAA methodName super obj (reverse args) s1 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Llamada super 1 Evaluar argumentos 2 Obtener objeto receptor (self) del entorno 3 Obtener nombre de superclase del entorno 4 Buscar método a ejecutar (methodName) comenzando búsqueda desde la superclase evalExpression (SuperExp methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds obj = applyEnv env s1 "self" (Object [APart super _]) = applyEnv env s1 "%super" in fMAA methodName super obj (reverse args) s1 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Llamada super 1 Evaluar argumentos 2 Obtener objeto receptor (self) del entorno 3 Obtener nombre de superclase del entorno 4 Buscar método a ejecutar (methodName) comenzando búsqueda desde la superclase evalExpression (SuperExp methodName rands) env st cds = let (args,s1) = evalExpressions rands env st cds obj = applyEnv env s1 "self" (Object [APart super _]) = applyEnv env s1 "%super" in fMAA methodName super obj (reverse args) s1 cds Eduardo Bonelli Programación Orientada a Objetos (Clase 2) Sintaxis de SOOL Intérprete de programas y expresiones Representación y creación de objetos Llamadas a métodos y llamada super Intérprete de expresiones Implementando findMethodAndApply Llamada super Resumen Hemos implementado un intérprete para un lenguaje orientado a objetos sencillo y representativo del paradigma Algunas extensiones posibles a SOOL a modo de ejercicio: Agregar una sentencia instanceof(e,clase) que determina si el objeto resultante de evaluar e es instancia de la clase clase Incorporar calificadores private, protected y public para las declaraciones de métodos que restringen su acceso: los públicos se pueden llamar desde cualquier lado, los protegidos sólo desde la clase anfitriona o sus subclases, los privados sólo desde la clase anfitriona Eduardo Bonelli Programación Orientada a Objetos (Clase 2)