Expresiones de Tipos: Tipos Básicos Tipos atómicos definidos por el lenguaje Ejemplos: Enteros Booleanos floats caracteres type_error Tipo especial que produce un error void Tipo básico que denota “la ausencia de un valor”
Expresiones de Tipo: Nombres Ya que las expresiones de tipos pueden ser nombradas, un nombre de tipo es una expresión de tipo
Expresiones de Tipo: Productos Si T1 y T2 son expresiones de tipo, T1 ? T2 es también una expresión de tipo
Expresiones de Tipo: Arrays Si T es una expresión de tipo, un array(T, I) es también una expresión de tipo I es una constante entera que denota el número de elementos de tipo T Ejemplo: int foo[128]; array(integer, 128)
Expresiones de Tipo: Function Calls Matemáticamente una función mapea Elementos de un conjunto (el dominio) A elementos de otro conjunto (el contradominio) Ejemplo int foobar(int a, boolean b, int c) integer ? boolean ? integer ? integer
Expresiones de Tipo: Otras Records Estructuras y clases Ejemplo class { int i; int j;} integer ? integer Lenguajes Funcionales Funciones que toman funciones y retornan funciones Ejemplo (integer ? integer) ? integer ? (integer ? integer)
Un lenguaje simple con tipos Un lenguaje que tiene una secuencia de declaraciones seguidas de una sola expresión P ? D; E D ? D; D | id : T T ? char | integer | array [ num ] of T E ? literal | num | id | E + E | E [ E ] Programa Ejemplo var: integer; var + 1023
Un lenguaje simple con tipos Un lenguaje que tiene una secuencia de declaraciones seguidas de una sola expresión P ? D; E D ? D; D | id : T T ? char | integer | array [ num ] of T E ? literal | num | id | E + E | E [ E ] ¿Cuáles son las acciones del parser para este lenguaje?
Acciones del Parser P ? D; E D ? D; D D ? id : T { addtype(id.entry, T.type); } T ? char { T.type = char; } T ? integer { T.type = integer; } T ? array [ num ] of T1 { T.type = array(T1.type, num.val); }
Acciones del Parser E ? literal { E.type = char; } E ? num { E.type = integer; } E ? id { E.type = lookup_type(id.name); }
Acciones del Parser E ? E1 + E2 { if E1.type == integer and E2 .type == integer then E.type = integer else E.type = type_error } 24
Acciones del Parser E ? E1 [E2 ] { if E2.type == integer and E1 .type == array(s, t) then E.type = s else E.type = type_error }
Equivalencia de Tipos ¿Cómo sabemos si dos tipos son iguales? Mismo entrada de tipo Ejemplo: int A[128]; foo(A);
foo(int B[128]) { … } Dos entradas de tipo distintas en dos tablas de símbolos distintas Pero deberían ser iguales
Equivalencia Estructural Si la expresión de tipo de dos tipos tiene la misma construcción, entonces son equivalentes “Misma Construcción” Tipos base equivalentes Mismo conjunto de constructores de tipo son aplicados en el mismo orden (e.d. árbol de tipos equivalente)
Coerción de Tipos Conversión implícita de un tipo a otro tipo Ejemplo int A; float B; B = B + A Dos tipos de coerción widening conversions narrowing conversions
Widening conversions Conversiones sin pérdida de información Ejemplos: integers a floats shorts a longs
Narrowing conversions Conversiones que pueden perder información Ejemplos: integers a chars longs a shorts Raro en lenguajes
Type casting Conversión explícita de un tipo a otro Tanto widening como narrowing Ejemplo int A; float B; A = A + (int)B Typecasting ilimitado puede ser peligroso
Pregunta: ¿Podemos asignarle un solo tipo a todas las variables, funciones y operadores? ¿Qué hay de +, cuál es su tipo?
Overloading Algunos operadores pueden tener más de un tipo. Ejemplo int A, B, C; float X, Y, Z; A = A + B X = X + Y Complica el sistema de tipos Ejemplo A = A + X ¿Cuál es el tipo de + ?
Clases Una clase es un tipo de datos abstracto Contiene Datos (campos) Acciones (métodos) Restricciones de acceso Cada instancia de una clase va a crear un objeto separado Con su propia copia de las variables instanciadas (compos) Comparte las acciones (métodos)
Clase Ejemplo class vehicle { int num_wheels; void print_num_wheels( ) { … } } (Gp:) campo
(Gp:) método
vehicle A; A.print_num_wheels( ) (Gp:) El Objeto es un parámetro implícito de la llamada del método
Herencia Extiende las clases al permitirles relaciones de supertipo/subtipo
Soporta reuso de código incremental Partes comúnes en un supertipo común Diferencias individuales en cada subtipo
Ejemplo de Herencia class SUV extends vehicle { int rollover_speed; int get_rollover_speed( ) { … } void print_rollover_speed( ) { … } }
La clase SUV es una subclase de la clase vehicle La clase vehicle es una superclase de la clase SUV Una instancia (objeto) de la clase SUV contiene Todos los campos de la clase vehicle Todos los campos de la clase SUV Los métodos tanto en SUV como en vehicle son visibles a la clase SUV
Página anterior | Volver al principio del trabajo | Página siguiente |