viernes, 8 de noviembre de 2013

Funciones y estructuas

Tarea 7__López



FUNCIONES Y ESTRUCTURAS

La generación de código para las funciones es la parte mas complicada porque depende de la maquina objeto y de la organización del entorno de ejecución. La traducción de funciones implica dos etapas:

·        La definición de la función. Una definición de función crea un nombre, parámetros y código del cuerpo de la función pero no se ejecuta la función en ese punto.
·        La llamada a la función desde una parte del programa (trataremos a los procedimientos como funciones que no de vuelven valores). Una llamada crea los valores actuales para los parámetros y realiza un salto al código de entrada de la función que se ejecuta y retorna al punto de la llamada.




Supongamos que el sub árbol sintáctico correspondiente a una función tiene como raíz un nodo de tipo n_ call, llamada a función, con una serie de hijos que corresponden a los argumentos, que en general, serán expresiones E1; : : : ;En a evaluar para obtener el valor actual de los n-argumentos.

A continuación se incluye una implantación para generar el código de 3-direcciones correspondiente a la llamada de la función en primer lugar. Posteriormente analizaremos el caso de la definición de la función. Supondremos que se han comprobado previamente las condiciones semánticas de la llamada (número y tipo de argumentos).

Ejemplo de llamada a la función


La llamada a una función de dos argumentos genera el siguiente código intermedio:
Se hace uso de una pila en donde se apilan los valores actuales de los parámetros de la función para después, como veremos en  Siguiente apartado, en la implantación del cuerpo de la función, 








Nota: Respecto a la dirección de la llamada a la función (índice de la instrucción del código de entrada a la función), se podrá conocer en el caso de que el código para la función ya se hubiera generado antes de la llamada (por ejemplo, se podrá haber almacenado en la entrada de la tabla de símbolos correspondiente a esa función en un campo definido para ese propósito).

En el caso de que aun no se haya generado el código para la dedición de la función tendremos que hacer un relleno de retroceso en todas las llamadas a esa función. Una forma será para cada función almacenar los índices de las instrucciones donde se hace una llamada dicha función (por ejemplo, en un vector de índices) y Una vez definida la función que ya se conoce la dirección de entrada recorremos el vector de índices y rellenamos con la dirección adecuada en todas las proposiciones de llamadas a esa función.







No hay comentarios:

Publicar un comentario