diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..746e85314 Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.ipynb_checkpoints/cp1-checkpoint.ipynb b/.ipynb_checkpoints/cp1-checkpoint.ipynb new file mode 100755 index 000000000..b4df627b8 --- /dev/null +++ b/.ipynb_checkpoints/cp1-checkpoint.ipynb @@ -0,0 +1,463 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Clase Práctica #1 (Compilación)\n", + "\n", + "A lo largo del curso estaremos implementando un compilador para el lenguaje de programación COOL, paso a paso, introduciendo nuevas características del lenguaje o mejorando la implementación de otras características a medida que vamos descubriendo las técnicas fundamentales de la teoría de lenguajes y la compilación.\n", + "\n", + "El objetivo de esta clase es construir un evaluador de expresiones \"a mano\", usando los recursos que tenemos hasta el momento. Para ello vamos a comenzar con una versión de COOL muy sencilla, un lenguaje de expresiones aritméticas." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Evaluador de expresiones\n", + "\n", + "Definiremos a continuación este lenguaje de manera informal:\n", + "\n", + "Un programa en `xCOOL` (la `x` por `expression`) consta de una secuencia de expresiones. Cada expresión está compuesta por:\n", + "\n", + "- números (con coma flotante de 32 bits), \n", + "- operadores `+ *` con el orden operacional, y\n", + "- paréntesis `(` y `)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Análisis lexicográfico\n", + "\n", + "Comenzaremos construyendo un prototipo bien simple, donde asumiremos que en la expresión hay espacios en blanco entre todos los elementos, de modo que el *lexer* se reduce a dividir por espacios. Luego iremos adicionando elementos más complejos.\n", + "\n", + "El siguiente método devuelve una lista de *tokens*, asumiendo que la expresión solo tiene números, operadores y paréntesis, separados por espacios en blanco." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def tokenize(text):\n", + " \"\"\"\n", + " Returns the set of tokens. At this point, simply splits by \n", + " spaces and converts numbers to `float` instances.\n", + " \"\"\"\n", + " tokens = []\n", + " for item in text.split():\n", + " try: \n", + " tokens.append(float(item))\n", + " except ValueError :\n", + " tokens.append(item)\n", + " \n", + " return tokens\n", + "\n", + "assert tokenize('5 + 6 * 9') == [5, '+', 6, '*', 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Análisis sintáctico y evaluación\n", + "\n", + "Una vez que tenemos los *tokens*, solo nos queda evaluar la expresión. Usaremos para ello una idea simple, pero bien útil: evaluaremos recursivamente la expresión descendiendo por los distintos niveles de precedencia.\n", + "\n", + "Toda expresión del lenguaje puede ser vista como una suma de _términos_, donde cada uno de estos \"_términos_\" se descompone a su vez en operaciones de multiplicación entre _factores_. Incluso si no hay operadores `+` en toda la expresión queda claro que esta idea es válida puesto que estaríamos en presencia de una expresión formada por un solo _término_. Los _factores_ del lenguaje son todos unidades atómicas: por ahora solo números y expresiones complejas envueltas entre paréntesis. Nótese que el uso de paréntesis permite reiniciar el descenso por los niveles de precedencia (regresar a los niveles más altos)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# These lambda expressions map from operators to actual executable code\n", + "operations = {\n", + " '+': lambda x,y: x + y,\n", + " '*': lambda x,y: x * y,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Some util classes and methods\n", + "\n", + "class ParsingError(Exception):\n", + " \"\"\"\n", + " Base class for all parsing exceptions.\n", + " \"\"\"\n", + " pass\n", + "\n", + "class BadEOFError(ParsingError):\n", + " \"\"\"\n", + " Unexpected EOF error.\n", + " \"\"\"\n", + " \n", + " def __init__(self):\n", + " ParsingError.__init__(self, \"Unexpected EOF\")\n", + " \n", + "class UnexpectedToken(ParsingError):\n", + " \"\"\"\n", + " Unexpected token error.\n", + " \"\"\"\n", + " \n", + " def __init__(self, token, i):\n", + " ParsingError.__init__(self, f'Unexpected token: {token} at {i}')\n", + " \n", + "class MissingCloseParenthesisError(ParsingError):\n", + " \"\"\"\n", + " Missing ')' token error.\n", + " \"\"\"\n", + " \n", + " def __init__(self, token, i):\n", + " ParsingError.__init__(self, f'Expected \")\" token at {i}. Got \"{token}\" instead')\n", + " \n", + "class MissingOpenParenthesisError(ParsingError):\n", + " \"\"\"\n", + " Missing '(' token error.\n", + " \"\"\"\n", + " \n", + " def __init__(self, token, i):\n", + " ParsingError.__init__(self, f'Expected \"(\" token at {i}. Got \"{token}\" instead')\n", + "\n", + "def get_token(tokens, i, error_type=BadEOFError):\n", + " \"\"\"\n", + " Returns tokens[i] if 'i' is in range. Otherwise, raises ParsingError exception.\n", + " \"\"\"\n", + " try:\n", + " return tokens[i]\n", + " except IndexError:\n", + " raise error_type()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9.0\n", + "9.0\n", + "2.0\n" + ] + } + ], + "source": [ + "def evaluate(tokens):\n", + " \"\"\"\n", + " Evaluates an expression recursively.\n", + " \"\"\"\n", + " try:\n", + " i, value = parse_expression(tokens, 0)\n", + " assert i == len(tokens)\n", + " return value\n", + " except ParsingError as error:\n", + " print(error)\n", + " return None\n", + "\n", + "def parse_expression(tokens, i):\n", + " i, term = parse_term(tokens, i)\n", + " \n", + " if i < len(tokens):\n", + " if tokens[i] == '+':\n", + " i, term_iz = parse_expression(tokens, i + 1)\n", + " term = operations[\"+\"](term,term_iz)\n", + " \n", + " return i, term\n", + " \n", + "def parse_term(tokens, i):\n", + " i,factor = parse_factor(tokens,i)\n", + " if i < len(tokens):\n", + " if tokens[i] == \"*\":\n", + " i,factor_iz = parse_factor(tokens,i +1 )\n", + " factor = operations[\"*\"](factor,factor_iz)\n", + " \n", + " return i , factor\n", + "\n", + "def parse_factor(tokens,i):\n", + " if tokens[i] == \"(\":\n", + " i,result = parse_expression(tokens,i + 1)\n", + " if tokens[i] != \")\":\n", + " pass\n", + " return i + 1 ,result\n", + " return i + 1 , tokens[i]\n", + " \n", + "assert evaluate(tokenize('5 + 6 * 9')) == 59.\n", + "assert evaluate(tokenize('( 5 + 6 ) * 9')) == 99.\n", + "assert evaluate(tokenize('( 5 + 6 ) + 1 * 9 + 2')) == 22." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adicionando constantes\n", + "\n", + "Agreguemos constantes numéricas al lenguaje `xCOOL` Para ello, simplemente añadiremos un diccionario con todas las constantes disponibles, que usaremos durante la tokenización. Nótese que solo es necesario modificar el _lexer_ para añadir este rasgo al lenguaje." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "constants = {\n", + " 'pi': 3.14159265359,\n", + " 'e': 2.71828182846,\n", + " 'phi': 1.61803398875,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def tokenize(expr):\n", + " \"\"\"\n", + " Returns the set of tokens. At this point, simply splits by \n", + " spaces and converts numbers to `float` instances.\n", + " Replaces constants.\n", + " \"\"\"\n", + " tokens = []\n", + " for item in expr.split():\n", + " try: \n", + " tokens.append(float(item))\n", + " except ValueError :\n", + " try:\n", + " tokens.append(constants[item])\n", + " except KeyError : \n", + " tokens.append(item)\n", + " \n", + " return tokens\n", + "\n", + "assert tokenize('2 * pi') == [2.0, '*', 3.14159265359]\n", + "assert evaluate(tokenize('2 * pi')) == 6.28318530718" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adicionando operadores `-` y `/`\n", + "\n", + "- **Restricción:** No utilizar ciclos!!!" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# These lambda expressions map from operators to actual executable code\n", + "operations = {\n", + " '+': lambda x,y: x + y,\n", + " '-': lambda x,y: x - y,\n", + " '*': lambda x,y: x * y,\n", + " '/': lambda x,y: x / y,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def parse_expression(tokens, i):\n", + " i,term = parse_term(tokens,i)\n", + " return parse_expression_(tokens,i,term)\n", + " \n", + "def parse_expression_(tokens,i,pivot):\n", + " if i < len(tokens):\n", + " if tokens[i] == \"+\" or tokens[i] == \"-\":\n", + " op = tokens[i]\n", + " i,term = parse_term(tokens,i + 1)\n", + " pivot = operations[op](pivot,term)\n", + " return parse_expression_(tokens,i,pivot)\n", + " return i,pivot\n", + " \n", + "def parse_term(tokens, i):\n", + " i,left = parse_factor(tokens,i)\n", + " return parse_term_(tokens,i,left)\n", + "\n", + "def parse_term_(tokens,i,pivot):\n", + " if i < len(tokens):\n", + " if tokens[i] == \"*\" or tokens[i] == \"/\":\n", + " op = tokens[i]\n", + " i,factor = parse_factor(tokens,i + 1)\n", + " pivot = operations[op](pivot,factor)\n", + " return parse_term_(tokens,i,pivot)\n", + " return i,pivot\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "assert evaluate(tokenize('8 / 4 / 2')) == 1\n", + "assert evaluate(tokenize('1 - 1 + 1')) == 1\n", + "#duda en python como se hace para crea metodos con el mismo nombre\n", + "#el ejercicio esta pensado para hacerlo sin funciones aux" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adicionando funciones elementales\n", + "\n", + "Agreguemos funciones elementales `sin`, `cos`, `tan`, `log`, `sqrt`, etc. El llamado a funciones se hará en notación prefija, comenzando por el nombre de la función y seguido, entre paréntesis, por los argumentos, que estarán separados entre sí por _comas_.\n", + "\n", + "Para las funciones elementales haremos algo similar a las constantes, pero en vez de a la hora de tokenizar, las reemplazaremos a la hora de evaluar, pues necesitamos evaluar recursivamente los argumentos de la función. Empezaremos por garantizar que nuestro tokenizador que es capaz de reconocer expresiones con funciones elementales de más de un argumento, en caso de no ser así es necesario arreglarlo." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "assert tokenize('log ( 64 , 1 + 3 )') == ['log', '(', 64.0, ',', 1.0, '+', 3.0, ')']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Adicionaremos entonces un diccionario con todas las funciones elementales que permitiremos." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "\n", + "functions = {\n", + " 'sin': lambda x: math.sin(x),\n", + " 'cos': lambda x: math.cos(x),\n", + " 'tan': lambda x: math.tan(x),\n", + " 'log': lambda x,y: math.log(x, y),\n", + " 'sqrt': lambda x: math.sqrt(x),\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Por último, modificaremos el método `evaluate` para que use las funciones elementales. Recordemos que los argumentos están separados por el token _coma_ (`,`) y que cada uno puede a su vez tener sub-expresiones que consistan también en llamados a funciones." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ")\n", + "True\n" + ] + } + ], + "source": [ + "def parse_factor(tokens,i):\n", + " try: \n", + " function = functions[tokens[i]]\n", + " if i + 1 < len(tokens) and tokens[i + 1] != \"(\":\n", + " pass\n", + " i,param = parse_expression(tokens,i + 2)\n", + " if tokens[i] == \",\":\n", + " i,param2 = parse_expression(tokens,i + 1)\n", + " if tokens[i] != \")\":\n", + " pass\n", + " return i + 1,function(param,param2)\n", + " else:\n", + " if i + 1 < len(tokens) and tokens[i + 1] != \")\":\n", + " pass\n", + " return i + 1, function(param)\n", + " except KeyError: \n", + " if tokens[i] == \"(\":\n", + " i,result = parse_expression(tokens,i + 1)\n", + " if tokens[i] != \")\":\n", + " pass\n", + " return i + 1 ,result\n", + " return i + 1 , tokens[i]\n", + " \n", + " \n", + "print(evaluate(tokenize('log ( 64 , 1 + 3 )')) == 3.0)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "print(2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100755 index 000000000..96175924b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.pythonPath": "/home/dany/.cache/pypoetry/virtualenvs/cmp-Jp0snq0--py3.8/bin/python", + "jupyter.jupyterServerType": "remote" +} \ No newline at end of file diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Pipfile b/Pipfile new file mode 100644 index 000000000..7aaaba5d5 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +sly = "*" + +[dev-packages] + +[requires] +python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 000000000..22f85d6f8 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,28 @@ +{ + "_meta": { + "hash": { + "sha256": "3bde8af921c40030bb9efe0825fabe050a56785bb01f6de168c8064bffad3393" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.9" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "sly": { + "hashes": [ + "sha256:e5f2266a231322cc17519fbc3a3ba1c6335fed5a9a55abe0e598a35aea0ac32a" + ], + "index": "pypi", + "version": "==0.4" + } + }, + "develop": {} +} diff --git a/Readme.md b/Readme.md old mode 100644 new mode 100755 index a47d48b9e..e3df113ac --- a/Readme.md +++ b/Readme.md @@ -1,172 +1,43 @@ -# COOL: Proyecto de Compilación +# ⚙️ Compiler for COOL language + +[![Tests](https://github.com/matcom-school/cool-compiler-2021/actions/workflows/tests.yml/badge.svg)](https://github.com/matcom-school/cool-compiler-2021/actions/workflows/tests.yml) -> Proyecto base para el compilador de 4to año en Ciencia de la Computación. -## Generalidades +## 🤔 What's it? -La evaluación de la asignatura Complementos de Compilación, inscrita en el programa del 4to año de la Licenciatura en Ciencia de la Computación de la Facultad de Matemática y Computación de la -Universidad de La Habana, consiste este curso en la implementación de un compilador completamente -funcional para el lenguaje _COOL_. +Compiler for the COOL language, you can see its official documentation [here](https://github.com/matcom-school/cool-compiler-2021/tree/master/doc). +The COOL language is a static and strongly typed tool, with imperative syntax and influenced by +the object-oriented design pattern. In this project a compiler is developed that transforms +plain text code into executable [MIPS](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjr4bytrL_7AhXZi7AFHVj3D-QQFnoECAoQAQ&url=https%3A%2F%2Fwww.mips.com%2F&usg=AOvVaw0pNYEgrs30qfMWUUI1txqH) +code. To perform this transformation, the system is +composed of 4 main modules that represent the 4 main phases of language theory +(lexer, parser, semantic checking and code generation). \ +**Principal Skills**: `Python` `Metaprogramming` `AST` `Visitor Pattern` `Sly` `MIPS` -_COOL (Classroom Object-Oriented Language)_ es un pequeño lenguaje que puede ser implementado con un esfuerzo razonable en un semestre del curso. Aun así, _COOL_ mantiene muchas de las características de los lenguajes de programación modernos, incluyendo orientación a objetos, tipado estático y manejo automático de memoria. +## 🤓 Motivation -## Cómo comenzar (o terminar) +This project was developed as part of a compilation course at the University of Havana. +With the educational foundation of knowing the main aspects of a compiler or interpreter, +tools that developers use on a daily basis. -El proyecto de Compilación será recogido y evaluado **únicamente** a través de Github. Es imprescindible tener una cuenta de Github para cada participante, y que su proyecto esté correctamente hosteado en esta plataforma. A continuación le damos las instrucciones mínimas necesarias para ello: +## 🧐 How to use it? -### 1. Si no lo han hecho ya, regístrense en [Github](https://github.com) todos los miembros del equipo (es gratis). - -![](img/img1.png) - -### 2. Haga click en el botón **Fork** para hacer una copia del proyecto en el perfil de Github de uno de los miembros. - -Opcionalmente pueden [crear una organización](https://github.com/organizations/new) y copiar el proyecto en el perfil de la misma. - -![](img/img2.png) - -### 3. Una vez hecho esto, tendrá un nuevo repositorio en `github/`. - -Revise que el repositorio de su equipo está en su perfil. -En este ejemplo se ha copiado a la cuenta de `github.com/apiad`. - -Debe indicar bajo el nombre del repositorio: `"forked from matcom/cool-compiler-2021"`. - -![](img/img3.png) - -### 4. Clone este proyecto en un repositorio local. - -Busque la URL de su proyecto en la interfaz web de Github. - -Asegúrese de clonar **su copia** y no el proyecto original en `matcom/cool-compiler-2021`. - -![](img/img4.png) - -```bash -$ git clone git@github.com:/cool-compiler-2021.git -``` - -> Donde `` es posiblemente el nombre de su equipo o del miembro donde se hizo el _fork_. - -A partir de este punto debe tener un proyecto `cool-compiler-2021` local. -El siguiente paso depende de si usted ya tiene su código versionado con `git` o no. - -### 5.A. Si tiene su proyecto en git (y no quiere perder la historia): - -#### 5.1. Mezcle hacia el nuevo respositorio su repositorio anterior: +First download the project ```bash -$ cd cool-compiler-2021 -$ git pull --allow-unrelated-histories master -``` - -#### 5.2. Organice su proyecto, código fuente y documentación, de acuerdo a las instrucciones de este documento, y vuelva a hacer `commit`. - -```bash -$ mv src/ -$ git add . -$ git commit -a -m "Mezclado con el proyecto base" -``` - -#### 5.3. A partir de este punto puede hacer `push` cada vez que tenga cambios que subir. - -```bash -$ git push origin master +$ git clone https://github.com/matcom-school/cool-compiler-2021.git +$ pip install -r requirements.txt ``` - -### 5.B Si aún no tiene su proyecto en git (o no le importa la historia): - -#### 5.1. Simplemente copie el código de su proyecto en la carpeta correspondiente `src` y haga su primer commit. +Check that all tests are working properly ```bash -$ mv src/ -$ git commit -a -m "Hello Git!" +$ cd src +$ make test ``` -#### 5.2. A partir de este punto asegúrese de hacer `commit` de forma regular para mantener su repositorio actualizado. - -Si necesita saber más sobre `git`, todo lo imprescindible está en [esta guía](doc/github-git-cheat-sheet.pdf). - -#### 5.3. A partir de este punto puede hacer `push` cada vez que tenga cambios que subir. +Then type your COOL code and save the changes in .cl and execute the following commands ```bash -$ git push origin master +$ make .cl ``` -## Entregas - -En este proyecto se realizarán entregas parciales a lo largo del curso. Para realizar una entrega, siga los siguientes pasos. - -### 1. Cree un pull request al proyecto original desde su copia. - -![](img/img5.png) - -### 2. Asegúrese de tener la siguiente configuración antes de hacer click en **Create pull request**. - -- **base repository**: `matcom/cool-compiler-2021` (repositorio original) - - **branch**: `master` -- **head repository**: `/cool-compiler-2021` (repositorio propio) - - **branch**: `master` (o la que corresponda) - -> Asegúrese que se indica **Able to merge**. De lo contrario, existen cambios en el repositorio original que usted no tiene, y debe actualizarlos. - -> **NOTA**: Asegúrese que el _pull request_ se hace a la rama `master`. - -![](img/img6.png) - -### 3. Introduzca un título y descripción adecuados, y haga click en **Create pull request**. - -![](img/img7.png) - -### 4. Espere mientras se ejecutan las pruebas. - -Verá la indicación **Some checks haven't completed yet**. - -![](img/img8.png) - -Es posible que tenga que actualizar los cambios que se hayan hecho en el repositorio original, por ejemplo, si se han agregado nuevos tests. En este caso obtendrá el siguiente mensaje: - -> **This branch is out-of-date with base branch** - -Haga click en **Update branch** y siga las instrucciones. -### 5. Verifique que no hubo errores en las pruebas. - -Si ve el mensaje **(All | Some) checks have failed**, significa que su código no pasó las pruebas. - -![](img/img9.png) - -Para ver los resultados de las pruebas haga click en el link **Details**. - -![](img/img10.png) - - -### 6. Arregle los errores y repita el paso 5 hasta que todas las pruebas pasen. - -Para cualquier modificación que haga a su proyecto, haga _commit_ y _push_ para **su repositorio personal** y automáticamente se actualizará el estado del _pull request_ y se volverán a ejecutar las pruebas. **No es necesario** abrir un _pull request_ nuevo por cada entrega, sino actualizar el anterior. - -> **Por favor asegúrese de mantener un solo _pull request_ activo por equipo**. En caso de abrir uno nuevo, cerrar el anterior. - -## Sobre la implementación - -Ponga todo su código e instrucciones necesarias en la carpeta `src`. Más información en [`src/Readme.md`](src/Readme.md). - -## Sobre la documentación - -Usted debe presentar un reporte escrito documentando el proceso de construcción de su compilador y los detalles más importantes de su funcionamiento. Más información en [`doc/Readme.md`](doc/Readme.md). - -## Sobre los equipos de desarrollo - -Para desarrollar el compilador del lenguaje COOL se trabajará en equipos de 2 o 3 integrantes. - -## Sobre los casos de prueba - -La carpeta `tests` contiene todos los casos de prueba que son obligatorios de pasar para que su proyecto tenga derecho a ser evaluado. - -Estos tests se ejecutan automáticamente cada vez que hace un _pull request_ al repositorio `matcom/cool-compiler-2021`. Solo aquellos proyectos que pasen todas las pruebas con éxito serán evaluados. - -Para ejecutar las pruebas localmente, debe tener instalado `Python 3.7`, `pip` y `make` (normalmente viene con Linux). Ejecute: - -```bash -$ pip install -r requirements.txt -$ cd src -$ make test -``` diff --git a/doc/Readme.md b/doc/Readme.md old mode 100644 new mode 100755 diff --git a/doc/content/chap0.pmd b/doc/content/chap0.pmd new file mode 100644 index 000000000..19198a612 --- /dev/null +++ b/doc/content/chap0.pmd @@ -0,0 +1,307 @@ +--- +next-chapter: chap1 +--- + +# Introducción {-} + +```python echo=False +import sys +import os + +sys.path.append(os.path.abspath(os.curdir)) + +from source.trees import Tree +from source.diagrams import Pipeline, Lexer +``` + +Este documento tiene como objetivo presentar el diseño de un curso de Compilación para estudiantes de Ciencia de la Computación. Este documento no es en absoluto un libro de texto de la asignatura Compilación (ni pretende serlo). Se asume que los profesores y estudiantes cuentan con documentación adicional para profundizar en los conocimientos impartidos. Cuando se presenta una sección de contenido, es más con el objetivo de presentar una guía sobre qué contenido será impartido, ilustrar un posible enfoque para introducir dicho contenido, y quizá además para acotar ciertas cuestiones específicas que consideramos de especial importancia. En cualquier caso, los estudiantes pueden encontrar también en este documento respuestas a preguntas de su interés, no solo desde el punto de vista puramente técnico (preguntas sobre el contenido) sino también desde el punto de vista metodológico (preguntas sobre la forma, o preguntas sobre las preguntas). De esta manera pueden entender mejor qué podemos prometerles como instructores, que se espera de ellos en cambio, y de qué forma pueden sacar el máximo provecho de este curso. + +## Diseño del Curso {-} + +Este curso fue diseñado bajo una concepción más dinámica e interactiva, más integrada con el resto de las disciplinas, y más práctica, pero sin perder en formalidad, precisión y profundidad en el conocimiento impartido. Para desarrollar este curso, primeramente nos planteamos primerante la siguiente pregunta: *¿Cuáles son las cuestiones fundamentales que esta asignatura ayuda a responder y comprender?* + +El objetivo de esta pregunta es cuestionarse primeramente el porqué de un curso de Compilación, antes de decidir qué contenidos específicos se deben incluir. Para ellos analizamos el lugar que ocupa la asignatura dentro del plan general de la carrera de Ciencia de la Computación, y los diversos conocimientos que enlaza. De esta forma pretendemos diseñar un curso más integrado y de mayor utilidad para la formación profesional. + +En una primera mirada, el curso de Compilación ocupa un lugar privilegiado dentro de la carrera. Ocurre justo en un momento donde los estudiantes han obtenido la mayor parte de los conocimientos básicos (programación, diseño de algoritmos, lógica y matemática y discreta), y están a punto de comenzar a adentrarse en las cuestiones propias de la Ciencia de la Computación. Esta asignatura viene a ser, de un modo tal vez un poco arrogante, la asignatura más integradora de toda esta primera parte. En este punto los estudiantes conocen cuestiones de muy alto nivel, tales como diseños de algoritmos y estructuras de datos, teoría de la computabilidad y la complejidad computacional, patrones de diseño y diversos paradigmas de programación, así como una creciente colección de lenguajes de programación particulares. Además conocen muchos detalles de bajo nivel, tales como la arquitectura de los procesadores, la memoria, los procesos y los sistemas operativos, lenguajes de máquina y ensambladores y modelos computacionales para la implementación de operaciones aritméticas eficientes. + +Compilación viene a ser la asignatura que enlaza estos dos mundos, el de alto nivel, y el de bajo nivel. Por primera vez los estudiantes pueden hacerse una idea del proceso completo que sucede desde la concepción de una idea de un algoritmo o sistema, su análisis, su implementación en un lenguaje de alto nivel (o varios lenguajes, frameworks y bibliotecas), y como todo ello se traduce a un lenguaje de máquina, y se ejecuta encima de un dispositivo de cómputo concreto. Desde este punto de vista, Compilación permite integrar los conocimientos del resto de las disciplinas de esta primera parte de la carrera, y viene a cerrar lo que podemos llamar el perfil básico del Científico de la Computación. Es en cierta forma la última de las asignaturas básicas y la primera de las asignaturas avanzadas. + +En una primera enumeración, podemos intentar definir habilidades y conocimientos concretos que los estudiantes pueden aspirar a obtener en esta asignatura. Un buen ejercicio consiste en preguntar a los propios estudiantes qué creen que deberían aprender en esta asignatura. Aunque realmente no tienen una idea clara de cuál es el campo de estudio que tienen delante, o dicho de otra forma, sobre qué *deberían* aprender; hemos encontrado que los estudiantes sí tienen expectativas bastante claras sobre qué *quieren* aprender. Por supuesto, encontrar un balance adecuado entre ambos intereses (los *nuestros* y los *suyos*) debe ser un objetivo a perseguir. Presentamos a continuación una posible e incompleta lista de estas habilidades, que hemos recopilado de varias sesiones de preguntas a estudiantes, edulcoradas con nuestras propias concepciones: + +- Reconocer problemas típicos de compilación y teoría de lenguajes. +- Crear reconocedores y generadores de lenguajes. +- Entender el funcionamiento de un compilador. +- Saber cómo se implementan instrucciones de alto nivel. +- Diseñar lenguajes de dominio específico. +- Poder implementar intérpretes y compiladores de un lenguaje arbitrario. +- Entender las diferencias y similaridades entre lenguajes distintos. +- Conectar lenguajes de alto nivel con arquitecturas de máquina. +- Aprender técnicas de procesamiento de lenguaje natural. + +Estas habilidades cubren desde los temas más prácticos sobre el diseño de lenguajes y compiladores hasta cuestions más filósoficas y abstractas relacionadas con otras áreas del conocimiento, desde la ingeniería de software hasta la inteligencia artificial. Los estudiantes quieren no sólo ser capaces de _hacer_, sino también, y tal vez más importante, quieren ser capaces de _entender_ cómo funcionan los algoritmos, técnicas, estructuras de datos, patrones de diseño, modelos de razonamiento, que son empleados en esta ciencia. + +Para dar forma a un curso que pueda ayudar a los estudiantes a obtener estas habilidades (y otras relacionadas), nos dimos entonces a la tarea de resumir las preguntas o cuestiones fundamentales que debe responder dicho curso. En una primera instancia, parece que una pregunta tan clara cómo _¿qué es un compilador?_ o incluso _¿cómo funciona un compilador?_ puede servir de guía al contenido del curso. Sin embargo, en una mirada más profunda, podemos descubrir que hay cuestiones más primarias, a las cuáles un compilador es ya una respuesta, un medio más que un fin en sí mismo. De hecho, podemos cuestionarnos porqué surgió la necesidad de hacer compiladores en primer lugar, a qué problema intentaron dar respuesta, y tratar de escarbar entonces las preguntas más primarias que subyacen en esta historia. + +## Un poco de historia {-} + +Podemos comenzar esta historia más o menos así. Hay una gran distancia entre el nivel de razonamiento que ocurre en el cerebro y el nivel de razonamiento que ocurre en una computadora. Los problemas de cualquier dominio se resuelven pensando a un nivel de abstracción con un lenguaje que describe las reglas de ese dominio. Hubo una época en que estos niveles de abstracción tenía que conectarlos el programador. De hecho, en esta época, la diferencia entre analista y programador era justamente que el analista diseñaba la solución en su lenguaje, y el programador la traducía a un programa ejecutable en el lenguaje de máquina. + +Por ejemplo, en 1952 Grace Hooper trabajaba en la simulación de trayectorias balísticas. Para dirigir un proyectil a su objetivo, los modelos físicos se describen en un lenguaje de ecuaciones diferenciales y mecánica newtoniana. Sin embargo, para poder implementar estos modelos en un dispositivo de cómputo hay que hablar en un lenguaje de registros, pilas e interrupciones. Esta diferencia es lo que hace que programar sea tan difícil, y hacía extremadamente lento el desarrollo de nuevos modelos porque a cada paso podían haber errores tanto en la modelación como en la codificación. ¿Cuando algo fallaba, de quién era la culpa? ¿Del analista o del programador? ¿O peor, del sistema de cómputo? + +Entonces a Grace Hooper se le ocurrió una genial idea: viendo que el proceso de convertir las ecuaciones diferenciales a programas concretos era fundamentalmente mecánico, ¿por qué no dejar que la propia computadora hiciera esta conversión? + +Esta idea genial tomaría varios años en perfeccionarse al punto de ser una realidad. El primer compilador de Grace Hooper para el lenguaje A-0 realmente era prácticamente un linker con algunas funciones básicas. Los primeros lenguajes de alto nivel en tener compiladores "serios" son FORTRAN (1957, John Backus), ALGOL (1958, Friedrich Bauer) y COBOL (1960, Grace Hooper). Una ventaja adicional además de reducir el tiempo de desarrollo, era la posibilidad de compilar el mismo programa para múltiples plataformas. En 1960 por primera vez se compiló el mismo programa de COBOL para dos máquinas distintas: UNIVAC II y RCA 501. + +En este punto los lenguajes se volvieron suficientemente complicados, al punto que ya los compiladores no se podían escribir "a mano". Entonces hizo falta volcarse a la teoría, y desarrollar una ciencia sobre qué tipos de lenguajes de programación se podían compilar, y con qué compiladores. Esto dio nacimiento, en 1960, a la ciencia que hoy conocemos como Compilación. Motivada no solo por un motivo práctico, sino también fundamentada en los principios teóricos más sólidos, la compilación vino a convertirse en una de las primeras justificaciones para que la computación se cuestionara problemas propios, y dejara de ser una mera herramienta de cálculo. Problemas tan distantes como el procesamiento de lenguaje natural y la naturaleza de las funciones computables han caído bajo el diapasón de las problemáticas estudiadas en este campo. Hoy la compilación es una ciencia sólida, fundamentada en años de teoría formal y práctica ingenieril. + +Escondida bajo todo este aparataje formal y toda la gama de experiencias y resultados teóricos y prácticos de los últimos 60 años, podemos encontrar una cuestión más fundamental, una pregunta que quizá retroceda hasta el propio Alan Turing, o incluso más allá, hasta Ada Lovelace y Charles Babbage con su máquina analítica. La cuestión es esta: + +> **¿Cómo hablar con una computadora?** + +Esta pregunta es, a nuestro modo de ver, en última instancia la cuestión a responder en este curso. Todos los intentos de diseñar lenguajes, todos los algoritmos y técnicas descubiertos, todos los patrones de diseño y arquitecturas, están en última instancia ligados al deseo de poder hacer una *pregunta* a la computadora, y obtener una *respuesta* a cambio. No importa si la pregunta es calcular cierta trayectoria de proyectiles, o encontrar la secuencia de parámetros que minimizan cierta función. Todo programa es en cierto modo una conversación con la computadora, un canal de comunicación, que queremos que sea lo suficientemente poderoso como para poder expresar nuestras ideas más complejas, y lo suficientemente simple como para poder ser entendido por una máquina de Turing. Como veremos en este curso, hallar el balance adecuado es un problema sumamente interesante, e intentar responderlo nos llevará por un camino que nos planteará muchas otras interrogantes, entre ellas las siguientes: + +- ¿Qué tipos de lenguajes es capaz de *entender* una computadora? +- ¿Cuánto de un lenguaje debe ser *entendido* para poder entablar una conversación? +- ¿Qué es *entender* un lenguaje? +- ¿Es igual de fácil o difícil *entender* que *hablar* un lenguaje? +- ¿Podemos caracterizar los lenguajes en términos computacionales según su complejidad para ser *entendidos* por una computadora? +- ¿Cómo se relacionan estos lenguajes con el lenguaje humano? +- ¿Qué podemos aprender sobre la naturaleza de las computadoras y los problemas computables, a partir de los lenguajes que son capaces de reconocer? +- ¿Qué podemos aprender sobre el lenguaje humano para hacer más inteligentes a las computadoras? +- ¿Qué podemos aprender sobre el lenguaje humano, y la propia naturaleza de nuestra inteligencia, a partir de estudiar los lenguajes entendibles por distintos tipos de máquinas? + +Estas preguntas, aunque no serán directamente respondidas en los siguientes capítulos, forman la columna vertebral del contenido del curso, en el sentido en qué todo lo presentado es con la intención de, al menos, poder echar un poco de luz en estos temas. Esperamos que al finalizar el curso, los estudiantes sean capaces de discutir las implicaciones filosóficas de las posibles respuestas a estas preguntas, y no solo a las cuestiones técnicas o más prácticas que el curso ataca. Por este motivo, sí trataremos en la medida de lo posible de, además del contenido técnico, adicionar en ocasiones algunos comentarios o discusiones más filósoficas al respecto de estas preguntas y otras similares. + +## Anatomía de un Compilador {-} + +Comenzaremos este viaje diseccionando el sistema computacional canónico de la teoría de lenguajes formales: un compilador. A grandes razgos, un compilador no es más que un programa, cuya entrada y salida resultan ser también programas. La entrada es un programa en un lenguaje que llamaremos "de alto nivel", y la salida en un lenguaje de "bajo nivel", que es equivalente al primero. Exactamente qué es alto y bajo nivel dependerá de muchos factores, y no existe una definición formal. De forma general, un lenguaje de alto nivel es aquel que nos es cómodo a los programadores para expresar las operaciones que nos interesa ejecutar. Así mismo, un lenguaje de bajo nivel es aquel que un dispositivo de cómputo puede ejecutar de forma eficiente. Tal vez los ejemplos más típicos sean un lenguaje orientado a objetos y un lenguaje ensamblador respectivamente, pero existen muchas otras combinaciones de lenguaje de entrada y salida de interés. + +![Representación abstracta del proceso de compilación.](../graphics/mountain.svg){ width=100% } + +Ahora bien, antes de zambullirnos de lleno en la anatomía de un compilador, es conveniente mencionar algunas sistemas de procesamiento de lenguajes relacionados. Podemos intentar categorizarlos según el "tipo" del lenguaje de entrada y salida. En primer lugar, el ejemplo clásico es cuando queremos convertir un lenguaje de alto nivel a otro de bajo nivel, y justamente llamamos a este sistema un **compilador**. El caso contrario, cuando queremos convertir de un lenguaje en bajo nivel a otro en alto nivel, podemos llamarle por analogía un **decompilador**. Este tipo de herramientas son útiles para analizar y realizar ingeniería inversa en programas para los que, tal vez, ya no tenemos el código fuente, y necesitamos entender o modificar. Los otros dos casos, de alto nivel a alto nivel y de bajo nivel a nivel son básicamente **traductores**; y en ocasiones se les llama también **transpiladores**. Por ejemplo, TypeScript es un lenguaje de alto nivel que se "transpila" a JavaScript, otro lenguaje también de alto nivel. Entre lenguajes de bajo nivel podemos tener también traductores. Un ejemplo son los llamados **compiladores JIT** (*just-in-time*), que se usan para traducir un programa compilado a un lenguaje de bajo nivel genérico (por ejemplo **IL**) a un lenguaje de máquina específico para la arquitectura donde se ejecuta. + +Volvamos entonces al caso clásico, el **compilador**. o este curso vamos a usar como una guía didáctica el diseño de un compilador para el lenguaje HULK, que compilará a un lenguaje de máquina denominado MIPS. Los detalles de ambos lenguajes serán introducidos a medida que sea conveniente, pero por el momento cabe decir que HULK es un lenguaje orientado a objetos, con recolección automática de basura, herencia simple, polimorfismo, y un sistema de tipos unificado. MIPS es un lenguaje ensamblador de pila para una arquitectura de 32 bits con registros y operaciones aritméticas, lógicas y orientadas a cadenas. + +Intentemos entonces definir esta maquinaria paso a paso. De forma abstracta nuestro compilador es una "caja negra" que convierte programas escritos en HULK a programas escritos en MIPS: + +```python echo=False, results="plain" +Pipeline(['HULK', 'Compilador', 'MIPS'], [ + (0, 1, ""), + (1, 2, ""), +], startshape='plaintext', endshape='plaintext').print(width="50%", float=False) +``` + +Para comenzar a destapar esta caja negra, notemos que al menos tenemos dos componentes independientes: uno que opera en lenguaje COOL y otro que opera en lenguaje MIPS. Necesitamos ser capaces de "leer" un programa en COOL y "escribirlo" en MIPS. Al primer módulo, que "lee", le llamaremos *parser*, o analizador sintáctico, por motivos históricos que veremos más adelante. Al segundo componente le llamaremos simplemente el *generador*. + +```python echo=False, results="plain" +Pipeline(['HULK', 'Parser', 'Generador', 'MIPS'], [ + (0, 1, ""), + (1, 2, ""), + (2, 3, ""), +], startshape='plaintext', endshape='plaintext').print(width="70%", float=False) +``` + +De aquí surge immediatamente una pregunta: ¿qué protocolo de comunicación tienen estos módulos? Es necesario diseñar una especie de lenguaje intermedio, un mecanismo de representación que no sea ni COOL ni MIPS, sino algo que esté "a medio camino" entre ambos. Es decir, hace falta traducir el programa en COOL a alguna forma de representación abstracta, independiente de la sintaxis, que luego pueda ser interpretada por el generador y escrita en MIPS. Llamésmole de momento *representación intermedia (IR)*. + +```python echo=False, results="plain" +Pipeline(['HULK', 'Parser', 'Generador', 'MIPS'], [ + (0, 1, ""), + (1, 2, "IR"), + (2, 3, ""), +], startshape='plaintext', endshape='plaintext').print(width="75%", float=False) +``` + +Pasemos entonces a analizar qué forma debe tener esta representación intermedia. En principio, debe ser totalmente independiente de COOL o de MIPS, en términos de sintaxis. A fin de cuentas, podemos estar generando para cualquier otra plataforma, no solo MIPS. Por otro lado, tiene que ser capaz de capturar todo lo qué es posible expresar en COOL. A este tipo de representación, independiente de la sintaxis, pero que captura todo el significado, le vamos a llamar indistintamente *representación semántica* en ocasiones, justamente por este motivo. ¿Qué va en una representación semántica? Pues todos los conceptos que son expresables en un programa, dígase clases, métodos, variables, expresiones, ciclos. ¿Qué no va? Pues todo lo que sea "superfluo" al significado. Por ejemplo, el hecho de que un método tiene un nombre, pertenece a una clase, y tiene ciertos argumentos de ciertos tipos, es importante semánticamente. Dos métodos se diferencian por alguno de estos elementos. Por otro lado, el hecho de que un método se escribe primero por su nombre, luego por los argumentos entre paréntesis seguidos por los nombres de sus tipos, es poco importante *en este momento*. Daría lo mismo que los tipos fueran delante o detrás de los nombres de los argumentos, ya en esta fase del procesamiento lo que nos interesa es de qué tipo es un argumento, y no si ese tipo se declara antes o después textualmente. + +Definir exactamente qué es semánticamente importante en un lenguaje particular no es una tarea fácil, y veremos una vez llegados a ese punto algunas ideas para atacar este problema (qué es en última instancia un problema de diseño, y por lo tanto es más un arte que una ciencia, al menos en el sentido artístico de Donald Knuth). Lo que sí es interesante de momento, es analizar qué tipo de procesamiento es importante, o al menos conveniente, realizar sobre esta representación intermedia. + +Cómo justificaremos más adelante, existen estructuras linguísticas que no son fáciles de reconocer, porque son dependientes del contexto. Por ejemplo, la expresión `x = y + z` es muy sencilla de reconocer sintácticamente, pero en un lenguaje con tipado estático esta expresión puede no pertenecer al lenguaje según los tipos de cada variable. Este es un problema clásico de dependencia del contexto, donde la expresión `x = y + z` es válida si existe en el contexto donde, por ejemplo existe, `int x, int y, int z` pero no donde el contexto es `int x, int y, object z`. Hay muchos problemas que son dependientes del contexto, entre ellos: + +- Declaración de variables antes de su uso +- Consistencia en los tipos declarados y las operaciones realizadas +- Consistencia entre la declaración de una función y su invocación +- Retornos en todos los caminos de ejecución + +La solución de estos problemas empleando las técnicas de la teoría de lenguajes solamente es en general no polinomial, y a veces no computable. Pero muchos de estos problemas se pueden resolver de forma más sencilla analizando la estructura computacional intermedia. ¿Por qué? Veremos más adelante que esta estructura tiene generalmente forma arbórea, y en una estructura arbórea es fácil analizar la consistencia de los tipos y problemas similares recorriendo cada uno de los nodos. De forma recursiva, el nodo raíz (o programa) estará correcto si cada hijo está correcto. Para realizar este tipo de procesamiento, introduciremos una nueva fase, que llamaremos *chequeo semántico*, y que opera justamente sobre la representación semántica del programa. + +```python echo=False, results="plain" +Pipeline(['HULK', 'Parser', 'Semántico', 'Generador', 'MIPS'], [ + (0, 1, ""), + (1, 2, ""), + (2, 3, ""), + (3, 4, ""), +], startshape='plaintext', endshape='plaintext').print(width="100%", float=False) +``` + +Finalmente, justo antes de generar el código ejecutable final, cabe preguntarse si existe algún tipo de procesamiento adicional conveniente. Descubriremos más adelante varios tipos de optimizaciones que se pueden aplicar en este punto, entre ellas: + +- Eliminar código no alcanzable +- Expandir expresiones constantes +- Elimiar asignaciones superfluas +- Desenrrollar ciclos con extremos constantes + +Estas optimizaciones a menudo son convenientes de realizar sobre una estructura del programa mucho más cercana al código de máquina que al código original. Son muchos los factores que influyen en esto y que veremos más adelante, pero de forma intuitiva, es fácil entender que optimizar un programa debe ser un proceso muy cercano al código de máquina, pues la propia naturaleza de la optimización requiere explotar características propias de la maquinaria donde será ejecutado el código. Introduciremos entonces una fase de optimización, que de momento visualizaremos de forma *paralela* al proceso de generación, pues en la práctica ambas fases comparten la misma representación y ambos procesos ocurren de forma más o menos simultánea. + +```python echo=False, results="plain" +Pipeline(['HULK', 'Parser', 'Semántico', 'Generador', 'MIPS'], [ + (0, 1, ""), + (1, 2, ""), + (2, 3, ""), + (3, 4, ""), + (3, 3, "Optimización"), +], startshape='plaintext', endshape='plaintext').print(width="100%", float=False) +``` + +Antes de terminar vamos a develar una fase adicional, justo antes del proceso de *parsing*. Para entender por qué, debemos introducirnos un poco más profundamente en este proceso. El proceso de *parsing* básicamente de lo que se encarga es convertir cadenas de texto (escritas en el lenguaje origen) a una estructura (arbórea) que captura la semántica del programa. Por ejemplo, supongamos que tenemos la siguiente expresión como parte de un programa en HULK: + +```HULK +if (a <= 0) + b +else + c +``` + +Esta expresión, desde el punto de vista semántico, podemos pensar que se transforma a una estructura como la siguiente: + +```python echo=False, results="plain" +Tree("IF-EXPR", + Tree("<=", + Tree("a"), + Tree("0") + ), + Tree("b"), + Tree("c"), +).print(float=False, width="40%") +``` + +De forma simplificada, en esta estructura hemos representado semánticamente el significado de la expresión sintáctica anterior, extrayendo los elementos importantes (el hecho de que una expresión `if` contiene tres elementos: condición, parte del cuerpo `true` y parte del cuerpo `false`) y obviando los detalles de sintaxis que ya no son imporantes (por ejemplo las palabras `then`, `else` y `fi` que solamente sirven para separar los bloques correspondientes). + +La solución de este problema (convertir una secuencia de texto en una representación semántica) nos tomará la primera mitad del curso, pues es uno de los temas centrales en toda la teoría de lenguajes y la compilación en particular. Más adelante formalizaremos con exactitud este problema y veremos muchísimas estrategias de solución. Pero antes de llegar a ese punto, es necesario resolver un sub-problema de menor complejidad, que aún así nos dará suficiente trabajo como para desarrollar gran parte de la teoría de lenguajes en su solución. El problema en cuestión es el siguiente. + +La cadena de texto de entrada, realmente está formada por una secuencia de caracteres. En el caso anterior, por ejemplo, tenemos la siguiente secuencia: + +```python echo=False, results="plain" +Lexer('i f \\\\s ( a < = 0 ) \\\\n \\\\t b \\\\n e l s e \\\\n \\\\t c \\\\n'.split()).print(float=False, width="100%") +``` + +En esta secuencia hemos representado cada caracter por separado, y hemos puesto explícitamente los espacios en blanco (`\s`), cambios de línea (`\n`) y espacios de tabulación (`\t`). Esta secuencia es lo que realmente "ve" el compilador en la entrada. Por lo tanto, desde el punto de vista puramente sintáctico, existen muchas secuencias que son exactamente el mismo programa. Por ejemplo, si existen varios espacios entre dos símbolos, o si no hay cambios de línea, o si los bloques están indentados con 4 espacios en vez con un caracter `\t`, realmente estamos en presencia del mismo programa. + +Para simplificar la tarea del *parser*, es conveniente convertir primeramente esta secuencia de caracteres en una secuencia de **tokens**, que no son más que los elementos básicos que componen el lenguaje, lo que pudiéramos llamar las *palabras* o *símbolos* más básicos. Por ejemplo, en el caso anterior, quisiéramos obtener la siguiente secuencia de **tokens**: + +```python echo=False, results="plain" +Lexer('if ( a <= 0 ) b else c'.split()).print(float=False, width="45%") +``` + +Introduciremos entonces una primera fase, que llamaremos indistintamente *tokenización*, o análisis lexicográfico, para transmitir la idea de que en esta fase solamente se procesan los elementos *léxicos*, es decir, las palabras, sin llegar todavía a tocar los elementos *sintácticos*, es decir, la estructura. Al mecanismo encargado de resolver este problema le llamaremos entonces *lexer*. + +```python echo=False, results="plain" +Pipeline(['HULK', 'Lexer', 'Parser', 'Semántico', 'Generador', 'MIPS'], [ + (0, 1, ""), + (1, 2, ""), + (2, 3, ""), + (3, 4, ""), + (4, 4, "Optimización"), + (4, 5, ""), +], startshape='plaintext', endshape='plaintext').print(width="100%", float=False) +``` + +A modo de resumen, tenemos entonces cinco fases fundamentales: + +Análisis Lexicográfico (*lexer*) +: donde se realiza la conversión de una secuencia de caracteres a una secuencia de *tokens*. + + En esta fase se detectan los errores relacionados con la escritura incorrecta de símbolos, por ejemplo, un número decimal con más dígitos de los permitidos, una cadena de texto que no termina en `"`, un identificador que usa un caracter inválido (e.j. `$`). + +Análisis Sintáctico (*parser*) +: donde se determina la estructura sintáctica del programa a partir de los *tokens* y se obtiene una estructura intermedia. + + En esta fase se detectan los errores relacionados con la sintaxis, por ejemplo, un paréntesis no balanceado, una función que no tiene cuerpo, un `if-else` con la parte `else` vacía. + +Análisis Semántico +: donde se verifican las condiciones semánticas del programa y se valida el uso correcto de todos los símbolos definidos. + + En esta fase se determinan los errores relacionados con los símbolos y tipos, por ejemplo, variables no declaradas o usadas antes de su declaración o funciones invocadas con un número o un tipo incorrecto de los argumentos. + +Optimización +: donde se eliminan o simplifican secciones del programa en función de la arquitectura de máquina hacian donde se vaya a compilar. + +Generación +: donde se convierte finalmente la estructura semántica y optimizada hacia el lenguaje objetivo en la arquitectura donde será ejecutado. + +Comenzaremos entonces a estudiar la fase de análisis lexicográfico, donde introduciremos los primeros elementos de la teoría de lenguajes formales. + +## Contenido {-} + +Para intentar responder algunas de las interrogantes planteadas arriba, hemos dividido el contenido del curso en 6 temas fundamentales, aunque existen muchos elementos que son trans-temáticos y por tanto no quedarían bien ubicados en ningún lugar particular. Por este mismo motivo, estos temas no deben tomarse como particiones rígidas del contenido, sino más bien guías a grandes razgos que giran alrededor de un concepto común. De hecho, estos temas no son presentados estrictamente en orden, sino que se van entrelazando a medida que avanza el curso. Los motivos para esto quedarán más claros adelante. + +Teoría de lenguajes: +: En este tema trataremos sobre los aspectos teóricos de la teoría de lenguajes formales, entre otras cuestiones: + + - Definiciones matemáticas y computacionales + - Tipos de lenguajes y características + - Equivalencias y relaciones entre lenguajes + - Problemas interesantes sobre lenguajes + - Relación entre la teoría de lenguajes y la computabilidad + +Mecanismos de generación: +: En este tema trataremos las diferentes clases de gramáticas, sus propiedades, los tipos de lenguajes que pueden generar, y algunos algoritmos de conversión entre ellas: + + - Jerarquía de gramáticas de Chomsky + - Gramáticas atributadas + - Formas normales y algoritmos de conversión + +Mecanismos de reconocimiento: +: En este tema trataremos sobre los autómatas como reconocedores de lenguajes, sus propiedades, y los algoritmos de construcción a partir de las gramáticas correspondientes: + + - Tipos de autómatas según el tipo de lenguaje + - Conversión entre autómatas y expresiones regulares + - Autómatas para el problema de *parsing* + +Análisis semántico: +: En este tema trataremos los problemas fundamentales de semántica en el contexto de los compiladores y las estrategias de modelación y solución: + + - Representaciones semánticas y problemas típicos + - Solución de referencias y *aliases* + - Inferencia de tipos y expresiones + - Validación de pre- y post-condiciones e invariantes + +Generación de código: +: En este tema trataremos las diferentes arquitecturas de código de máquina y los problemas asociados: + + - Semánticas operacionales + - Arquitecturas de generación código + - Optimizaciones + +Ejecución de código: +: En este tema trataremos los problemas que surgen o son resueltos posterior a la generación de código, y que dependen de operaciones especiales por parte del mecanismo de ejecución: + + - Intérpretes y máquinas virtuales + - Manejo de excepciones + - Recolección de basura + +La guía general del curso será orientada a la tarea canónica de construir un compilador. Para ello usaremos el lenguaje `COOL` diseñado específicamente para este propósito. Con esta guía en mente, iremos presentando los contenidos en el orden que sean necesarios para ir avanzando en el propósito de construir el compilador. Por este motivo, a diferencia de otros cursos, no daremos primero toda la teoría de lenguajes formales y luego los algoritmos de *parsing*, sino que iremos introduciendo elementos teóricos y prácticos según lo vaya requiriendo el compilador que estamos diseñando en clase. + +El objetivo de esta forma de ordenar los contenidos es, en primer lugar, brindar una visión más unificada de todo el proceso de compilación y todas las técnicas, elementos teóricos y cuestiones de diseño. Por otro lado, aspiramos con esto a lograr que los estudiantes realmente obtengan las habilidades planteadas al inicio, al tener que poner desde el principio del curso todo el conocimiento en función de un proyecto práctico. + +## Evaluación y retroalimentación {-} + +Una vez que los estudiantes saben que habilidades obtendrán, entonces se plantea el problema de la evaluación. +En este curso consideramos la evaluación como una necesidad y una ventaja para los estudiantes, no como una obligación o una arbitrariedad del profesor. Por eso hemos diseñado un sistema de evaluación que permita a los estudiantes reconocerlo como un mecanismo de retroalimentación que les permite entender su propio avance y optimizar su estudio. Claro que la evaluación tiene un valor externo, que le permite a la sociedad saber quienes están preparados o no. Pero las notas particulares obtenidas en una asignatura no significan nada fuera del sistema educacional. A nadie se le ofrece un trabajo por las notas que obtuvo. Lo que cuenta es graduarse o no. Entonces, ¿por qué se toma tanto trabajo en cuantificar la evaluación? La respuesta es que el número obtenido en una evaluación es una métrica de retroalimentación para que el estudiante sepa en qué grado fue capaz de cumplir las expectativas del profesor. + +Teniendo esta máxima en cuenta, hemos planteado algunos principios básicos que creemos deben guiar el sistema de evaluación del curso. En primer lugar, la idea de que todos los estudiantes deben tener tantas oportunidades como sea posible para experimentar y aprender. Esto significa que deben permitirse fallar sin miedo a ser recriminados. Por tanto, no consideramos ninguna práctica que penalice a los estudiantes por fallar en una evaluación, en particular, todos los estudiantes tienen derecho a todos los exámenes independientemente de los resultados obtenidos anteriormente. + +Por otro lado, queremos incentivar un estudio constante y consistente en vez de un maratón de última hora, por lo que sí aprobamos las prácticas que premien por el trabajo continuado, incluso teniendo en cuenta los posibles errores que hayan cometido. De modo que hemos dividido el curso en 3 grandes conjuntos de habilidades: + +- Habilidades teóricas de modelación con lenguajes formales. +- Habilidades en el uso y diseño de algoritmos relacionados con lenguajes. +- Habilidades en el diseño de arquitecturas y patrones para sistemas de procesamiento de lenguajes. + +De forma aproximada podemos incluir todo contenido dado en el curso en uno de estos conjuntos de habilidades. Consideramos en un estudiante que domine de forma efectiva estos tres conjuntos de habilidades, está preparado para enfrentarse a las preguntas y problemáticas típicas de este campo de estudio. Por el mismo motivo, consideramos que es imprescindible haber vencido las tres habilidades para poder aprobar el curso. + +Por tanto, hemos concebido un sistema de evaluación que se compone de 3 exámenes parciales y tres proyectos opcionales, cada par respectivamente orientado a evaluar uno de los tres conjuntos de habilidades mencionados. Los estudiantes que obtienen resultados satisfactorios en cada caso se considera que vencieron dicha habilidad. Al finalizar el curso hay un exámen final que permite a los estudiantes complementar sus resultados hasta el momento, en caso de no haber cumplido todos los objetivos en las evaluaciones parciales. + +Así mismo, se orientarán a menudo tareas de menor envergadura que pueden ayudar también a complementar la comprensión (y la consecuente evaluación) en cualquiera de los temas presentados. + +## Conclusiones {-} + +Este curso es un viaje, un viaje por una de las ramas más espectaculares de la historia de la computación, una rama que definió a la computación como ciencia, y que creó algunos de sus héroes más famosos. Es un viaje lleno de dificultades, pero detrás de cada obstáculo hay algo increíble que descubrir. Los que hemos pasado por este viaje les podemos prometer que vale la pena. Pero la mejor forma de experimentarlo no es como espectador, como un simple pasajero. La mejor forma de experimentarlo es coger el timón y decidir ustedes cuáles son los lugares que quieren explorar. Nosotros haremos el mejor esfuerzo por llevarlos allí, pero no les podemos mantener los ojos abiertos. Mirar, oler y tocar todo lo que puedan es responsabilidad de ustedes. diff --git a/doc/content/chap1.pmd b/doc/content/chap1.pmd new file mode 100644 index 000000000..e999cd468 --- /dev/null +++ b/doc/content/chap1.pmd @@ -0,0 +1,292 @@ +--- +previous-chapter: chap0 +next-chapter: chap2 +--- + +# Análisis Lexicográfico + +```python echo=False +import sys +import os + +sys.path.append(os.path.abspath(os.curdir)) + +from source.automata import Automaton +``` + +En este capítulo vamos a atacar el problema de implementar un *lexer*, y todos los elementos teóricos que nos ayudarán en esta tarea, y que nos servirán además para resolver problemas independientes pero relacionados con esta fase. Vamos a comenzar definiendo formalmente el problema que queremos resolver, y luego veremos como desarrollar una teoría que nos permita atacar su solución. Para ello: + +* Definiremos el concepto de [*token*](#tokens). +* Diseñaremos [autómatas finitos deterministas](#dfa) para reconocer lenguajes regulares. +* Caracterizaremos los [lenguajes regulares](#regular). +* Conoceremos las [expresiones regulares](#expreg) para describir esta clase de lenguajes. +* Veremos un algoritmo [convertir expresiones regulares en autómatas](#regnfa). +* Aprenderemos sobre las [operaciones entre lenguajes regulares](#opers). +* Y por si fuera poco, veremos finalmente [los límites de los lenguajes regulares](#pumping). + +## Los *tokens* de nuestro lenguaje {#tokens} + +Comenzaremos por definir el concepto de *token*, básicamente, como una secuencia de caracteres con cumple con cierta estructura sintáctica. Más adelante impondremos restricciones sobre qué tipos de estructuras son válidas. De momento, pondremos algunos ejemplos: + +* Las palabras claves de un lenguaje: **if**, **else**, **function**, **class**, etc. +* Los literales numéricos: `42`, `3.1415`, `0.123e-44`, etc. +* Los literales de cadena: `"hello world!"`, etc. +* Los literales booleanos: `True`, `False`. +* Los operadores: `+`, `-`, `*`, `<`, `<=`, etc. +* Identificadores: `x`, `value`, `someMethodName`, etc. + +De modo que queremos idear un mecanismo que reciba como entrada una descripción del conjunto de *tokens* de nuestro lenguaje, y una cadena de caracteres, y nos devuelva la secuencia de *tokens* que aparecen en la cadena. + +Un primer análisis nos puede llevar a pensar idea similar a dividir la cadena por espacios en blanco y quedarnos con cada elemento como un *token*, pero es muy sencillo ver por qué esta idea no es suficiente. En primer lugar, existen *tokens* que no necesariamente aparecen separados por espacio, como en el caso de `value<=0.001`. Además, existen *tokens* que son prefijos de otros *tokens*, como `<` y `<=`; o `class` que es una palabra clave y `class1` que es un identificador cualquiera. Esto quiere decir que necesitamos realizar un análisis un poco más complejo para determinar qué parte de una secuencia de caracteres corresponde a un *token* o a *otro*. + +Veamos el problema entonces desde el siguiente punto de vista: supongamos que escaneamos la secuencia de caracteres de inicio a fin, un caracter a la vez, y lo que deseamos es en cada momento ser capaces de determinar si estamos en el medio de un *token*, o si acabamos de reconocer un *token* completo. Por ejemplo, tomemos nuevamente la cadena de ejemplo del capítulo anterior: + + if (a<=0) b else c + +Vamos a simbolizar con el símbolo `|` el punto que divide el fragmento de la cadena que hemos analizado, de la parte de la cadena que falta por analizar. Es decir, al inicio de nuestro procesamiento, estamos en el siguiente estado: + + |if (a<=0) b else c + +Que simboliza que aún no hemos visto ningún caracter de la cadena. Queremos entonces idear una maquinaria que "avance" por la cadena, caracter a caracter, y en cada instante sepa determinar si con los caracteres vistos hasta el momento ya tiene un *token* construido, o si necesita seguir avanzando. Veamos paso a paso cómo podría funcionar un mecanismo así. Comenzamos con el inicio de la cadena, y vamos además a almacenar el fragmento de *token* que estamos construyendo, y la lista de *tokens* que vamos reconociendo como salida: + + CADENA: |if a<=0 then b else c + TOKEN: + SALIDA: + +El primer paso consiste en analizar el caracter `i`. Cómo acabamos de empezar, no tenemos nada almacenado, entonces la única posibilidad es que este caracter `i` sea parte del *token* que estamos intentando reconocer. + + CADENA: i|f a<=0 then b else c + TOKEN: i + SALIDA: + +Ahora vemos el caracter `f`. Cómo viene immediatamente después de otro caracter, pudiera ser que estemos viendo un *token* de tipo identificador. Por otro lado, pudiera ser que estuviéramos viendo particularmente el *token* `if`, que es una palabra clave. De momento, lo tomamos. + + CADENA: if| a<=0 then b else c + TOKEN: if + SALIDA: + +Nos encontramos entonces con un espacio en blanco, lo que nos permite decidir que efectivamente hemos encontrado el *token* `if`, por lo que podemos devolverlo en la secuencia de salida. + + CADENA: if |a<=0 then b else c + TOKEN: + SALIDA: [if] + +Ahora nos encontramos un caracter `a`, que pudiera ser un identificador, pero todavía no podemos decir nada al respecto pues es posible que el identificador tenga más letras. + + CADENA: if a|<=0 then b else c + TOKEN: a + SALIDA: [if] + +En este paso nos encontramos un caracter `<`, y como estábamos tratando de reconocer un identificador que empieza con `a`, y nuestras reglas dicen que `<` no puede ser parte del nombre de ningún identificador, entonces podemos concluir que el *token* anterior es justamente `a`, y comenzar un nuevo *token*: + + CADENA: if a<|=0 then b else c + TOKEN: < + SALIDA: [if] [a] + +Del mismo modo, hemos comenzado a construir un *token* `<`, que pudiera ser el operador en sí, o pudiera ser el operador `<=`, todo depende de lo que le siga. Al ver a continuación el caracter `=`, concluimos que tenemos el *token* `<=` sin necesidad de seguir buscando, pues no existe ningún *token* con prefijo `<=`. + + CADENA: if a<=|0 then b else c + TOKEN: + SALIDA: [if] [a] [<=] + +Es fácil ver como continúa este proceso, llevando finalmente a la secuencia de *tokens* correcta: + + [if] [a] [<=] [0] [then] [b] [else] [c] + +La pregunta consiste entonces en cómo implementamos este mecanismo computacionalmente. De modo general, la decisión que hemos tomado en cada paso depende únicamente de dos factores: el caracter que estamos examinando, y lo que hemos hecho hasta el paso anterior. Para modelar este segundo factor de "lo que hemos hecho hasta el paso anterior", analizemos primero de cuántas formas posibles podemos hablar de lo que hemos hecho hasta el paso anterior. Básicamente, tenemos un conjunto finito de clases de *tokens*, y lo que necesitamos saber es simplemente que clase de *token* estamos intentando construir, para saber si el nuevo caracter puede completar esta clase o no. + +De modo que podemos pensar en una especie de **máquina de estados**, donde modelaremos con los estados el hecho de llevar la cuenta de qué clase de *token* estamos construyendo, y por ende, cuáles son los posibles caracteres a esperar a continuación. Esta máquina de estados es una clase particular de máquina de *Turing*, que tiene la característica de que solo puede moverse hacia la izquierda en la cinta y solo puede leer (no está permitido escribir). A las máquinas de estado que solo se mueven en una dirección en la cinta se les llama **autómatas**. Distintos tipos de autómatas se diferencian entonces por los tipos de transiciones que le son permitidas, y los tipos de análisis que pueden realizar para tomar una decisión. En este caso particular, estaremos definiendo la clase más sencilla de autómata, un **autómata finito determinista**. + +## Autómatas Finitos Deterministas {#dfa} + +Formalizando, un autómata finito determinista es un quíntuplo $A = $ con las siguientes características: + +* $Q$ es un conjunto finito de estados ($Q = \{ q_0, \ldots, q_n \}$), de ahí el adjetivo de **finito**. +* $q_0 \in Q$ es el estado inicial. +* $V$ es un conjunto finito de símbolos que pueden aparecer en la cinta. +* $F \subseteq Q$ es un subconjunto de estados que denominaremos *estados finales*. +* $f: Q \times V \to Q$ es una *función de transición*, que determina, para cada par posible de estados y símbolos, cuál es el estado de destino. Se denomina un autómata **determinista** justamente porque en un estado particular, para un símbolo particular, existe solamente un estado posible de destino (o ninguno), por lo tanto, siempre existe una única decisión que tomar. + +El modo de funcionamiento de un autómata finito determinista es el siguiente. Tenemos una cadena de entrada, que no es más que una secuencia de símbolos de $V$, o sea, un elemento $\omega \in V^k$ para algún valor de $k$ (que será la longitud de la cadena). El estado inicial del autómata es $q^{(0)} = q_0$. Por cada símbolo en $\omega_i \in \omega$, realizamos la operación $q^{(i)} = f(q^{(i-1)}, \omega_i)$. Al concluir, si $q^{(k)} \in V$, decimos que el autómata **acepta** o **reconoce** la cadena $\omega$. + +Si en un caso particular la función $f(q_i,a_i)$ no estuviera definida, entonces diremos que el autómata "se traba", y no reconoce la cadena. Este convenio lo tomamos para evitar tener que definir un autómata completamente cuando existen muchos estados "superfluos". Siempre es posible convertir un autómata con algunas transiciones no definidas (*parcialmente especificado*) a un autómata con todas las transiciones definidas (*completamente especificado*), si añadimos un estado adicional $q_{error}$, a dónde apuntan todas las transiciones faltantes, y de donde salen además para el propio estado $q_{error}$ todas transiciones con todos los símbolos. Este estado sirve como especie de "sumidero". + +Veamos entonces un ejemplo. Para representar gráficamente un autómata, usaremos un grafo dirigido para visualizar la función de transición, donde el nodo $i$ representa al estado $q_i$, y la artista $(i,j)$ está etiquetada con el símbolo $a_k$ si $f(q_i,a_k) = q_j$. Los estados finales se representan con un borde doble, y el resto de los estados con un borde normal. + +Por ejemplo, si tenemos el siguiente autómata $A=$, donde: + +* $Q = {q_0, q_1, q_2}$ +* $V = \{a,b\}$ +* $F = \{q_2\}$ +* $f$ se define por la siquiente tabla: + + Estado | Símbolo | $f$ + --------+---------+------- + $q_0$ | $a$ | $q_1$ + $q_0$ | $b$ | $q_0$ + $q_1$ | $a$ | $q_2$ + $q_1$ | $b$ | $q_0$ + $q_2$ | $a$ | $q_2$ + $q_2$ | $b$ | $q_0$ + +Podemos representar gráficamente el autómata anterior con el siguiente gráfico: + +```python echo=False, results="plain" +Automaton('q0', ['q2'], { + ('q0', 'a'): 'q1', + ('q0', 'b'): 'q0', + ('q1', 'a'): 'q2', + ('q1', 'b'): 'q0', + ('q2', 'a'): 'q2', + ('q2', 'b'): 'q0', +}).print(float=False, width="50%") +``` + +En este gráfico queda completamente representado el autómata, sin necesidad de especificar el resto, pues de la función de transición se pueden inferir los estados y el alfabeto, y se toma el convenio de que el estado $q_0$ siempre es el estado inicial. + +Cabe preguntarnos entonces la siguiente interrogante: + +> ¿Qué lenguajes es capaz de reconocer un autómata finito determinista? + +A responder esta pregunta dedicaremos la mayor parte del resto de este capítulo. Para comenzar, debemos formalizar primeramente la pregunta planteada. Necesitamos definir qué es un **lenguaje**, y qué significa que un autómata **reconozca** cierto lenguaje. + +Para definir un lenguaje, comenzaremos con la definición de **alfabeto**. Un alfabeto $V$ no es más que un conjunto de símbolos, que son elementos básicos indivisibles. Por ejemplo, $V = \{a, b\}$ es el alfabeto que contiene los símbolos $a$ y $b$. El "significado" de cada símbolo no nos interesa en la teoría de lenguajes formales, solamente nos interesa diferenciar un símbolo de otro. Dejaremos el problema del "significado" para cuando lleguemos a la fase semántica. + +Una vez armados con el concepto de alfabeto, podemos definir el concepto de **cadena**. Una cadena $\omega$ es un elemento del conjunto $V^k$ para algún valor de $k$ arbitrario. Por ejemplo, la cadena $abba$ es un elemento del conjunto $\{a,b\}^4$. Se llama *longitud* de la cadena justamente al valor $k$. Si $k=0$, tenemos la *cadena vacía*, que se simboliza generalmente como $\epsilon$ independientemente del conjunto $V$. + +Finalmente, definiremos un **lenguaje** $L$, como un conjunto de cadenas sobre un alfabeto particular, o alternativamente, como un subconjunto de la clausura del producto cartesiano de dicho de alfabeto. Es decir, $L \subseteq V^*$, donde: + +$$ +V^* = \bigcup_{k=0}^{\infty} V^k +$$ + +Vamos a introducir entonces algo de notación adicional. Sea $A$ un autómata finito determinista, denominaremos $L_A$ al lenguaje de todas las cadenas reconocidas por $A$. Es decir, $\omega \in L_A$ si y solo $A$ reconoce $\omega$. Cabe entonces preguntarnos qué tipos de lenguajes pueden ser reconocidos por este mecanismo. Podemos entonces definir la interrogante anterior de manera más precisa cómo: + +> ¿Qué características tienen los lenguajes que son posibles de reconocer por algún autómata finito determinista? + +A este tipo de lenguajes les llamaremos **lenguajes regulares**, por motivos históricos que veremos más adelante. A modo definición: + +> **Definición (Lenguaje Regular):** Sea $L$ un lenguaje sobre el alfabeto $V$, se dice que $L$ es **regular** si y solo si existe un autómata finito determinista $A=$ (sobre el mismo alfabeto), tal que $L = L_A$. + +Pasemos entonces a describir algunos ejemplos de lenguajes regulares, que nos darán una idea intuitiva del poder de cómputo de estos autómatas. + +## Lenguajes Regulares {#regular} + +El más simple de todos los lenguajes que podemos definir sobre un alfabeto $V$ es justamente $V^*$, el lenguaje de todas las cadenas que se pueden construir con los símbolos de $V$. A este lenguaje le llamamos *universo*. Para construir un autómata para este lenguaje, simplemente necesitamos un estado que será a la vez inicial y final, y una transición para cada símbolo del alfabeto desde este estado hacia el propio estado. Por ejemplo, si $V = \{ a, b, c \}$, tenemos el siguiente autómata: + +```python echo=False, results="plain" +Automaton('q0', ['q0'], { + ('q0', 'a b c'): 'q0' +}).print(width="20%", float=False) +``` + +Con esta idea podemos demostrar nuestro primer teorema en la teoría de lenguajes formales: + +> **Teorema:** El lenguaje *universo* $L = V^*$ es regular. + +La demostración se realiza por construcción. Sea $V = \{ a_1, \ldots, a_n \}$ el alfabeto, sea $A$ el autómata $$, donde $Q = F = \{ q_0\}$ y $f(q_0, a_i) = q_0$ para todo símbolo $a_i \in V$; entonces $A$ reconoce el lenguaje $V^*$. + +Yendo al extremo contrario, vamos a definir el lenguaje que contiene exactamente las palabras claves **if**, **then**, **else**, **fi**. Para este lenguaje también es fácil definir un autómata. Creamos dos estados, uno inicial y uno final, y por cada palabra del lenguaje creamos un camino entre el estado inicial y final con un estado intermedio para cada símbolo de la palabra correspondiente (menos el último, claro): + +```python echo=False, results="plain" +Automaton('q0', ['q02', 'q06', 'q10', 'q12'], { + ('q0', 'i'): 'q01', + ('q01', 'f'): 'q02', + + ('q0', 't'): 'q03', + ('q03', 'h'): 'q04', + ('q04', 'e'): 'q05', + ('q05', 'n'): 'q06', + + ('q0', 'e'): 'q07', + ('q07', 'l'): 'q08', + ('q08', 's'): 'q09', + ('q09', 'e'): 'q10', + + ('q0' , 'f'): 'q11', + ('q11', 'i'): 'q12', +}).print(width="80%", float=False) +``` + +Este autómata nos da una idea para demostrar nuestro segundo teorema: + +> **Teorema:** Sea $L = \{ \omega_1, \ldots, \omega_n \}$ un lenguaje *finito*, entonces $L$ es regular. + +La demostración es muy sencilla, simplemente necesitamos construir un autómata que contenga un camino por cada cadena del lenguaje. Si existen cadenas con prefijos comunes, los estados correspondientes a los símbolos que participan en los prefijos se comparten (para mantener el determinismo, aunque veremos pronto que esto no es estrictamente necesario). + +Para nuestro siguiente ejemplo, vamos a complejizar un poco el lenguaje a reconocer, y de paso veremos una estrategia general para la construcción de autómatas. El lenguaje que queremos reconocer es el lenguaje de las cadenas sobre el alfabeto $V = \{a, b\}$, con exactamente $3$ letras $a$. Antes de lanzarnos a construir el autómata, tratemos de pensar en una solución algorítmica para este problema. De forma general, la estrategia de solución sería algo así: + +```python +def match(s: str) -> bool: + count_a = 0 + + for c in s: + if c == 'a': + count_a += 1 + + return count_a == 3 +``` + +Esta solución es correcta, pero padece de un problema que nos hace imposible convertirla en un autómata finito. El problema es justamente que la cantidad de memoria que usa esta solución es potencialmente *infinita*, o al menos, proporcional al tamaño de la cadena. ¿Por qué? Pues, porque hemos utilizado un contador no acotado superiormente (`count_a`), por lo que, en principio, podemos necesitar hasta $log_2(n)$ bits de memoria para una cadena con longitud $|w|=n$. Claro que en la práctica sabemos que ese entero es de 32 bits, independientemente del tamaño de la cadena, pero la idea que queremos transmitir es que *no hemos acotado la cantidad de memoria*, por lo que no sabemos cuántos estados debería tener un autómata que haga lo mismo que este método. + +Una solución mejor consiste en notar que solamente hay 5 posibles situaciones: + +* Hemos visto $0$ símbolos $a$. +* Hemos visto $1$ símbolo $a$. +* Hemos visto $2$ símbolos $a$. +* Hemos visto $3$ símbolos $a$. +* Hemos visto $4$ símbolos $a$ _o más_. + +Una vez que hayamos visto $4$ veces una $a$ en la cadena, ya sabemos que la cadena es incorrecta, y no es posible que "se arregle" más adelante pues la cantidad de $a$ solo puede aumentar. Con esta idea en mente, cambiemos el método anterior para que solo use, a lo sumo, **5 valores diferentes** de la variable `count_a`: + +```python +def match(s: str) -> bool: + count_a = 0 + + for c in s: # esto es lo nuevo + if c == 'a' and count_a <= 3: + count_a += 1 + + return count_a == 3 +``` + +Parece que no hemos hecho mucho, pero hemos logrado garantizar que nuestro método solamente tiene a lo sumo **5 valores diferentes** de la variable `count_a`, a saber, $0 \ldots 4$. ¿De qué nos sirve esto? Pues, ahora podemos diseñar un autómata tranquilamente, con la siguiente idea: contamos la cantidad posible de valores que toman *todas las variables locales*, y por *cada combinación de valores* tendremos un estado. Si este número es finito, entonces tenemos un autómata finito (que puede ser o no determinista, ya llegaremos a ese problema). + +En este ejemplo, tenemos entonces 5 posibles estados, desde $q_0$ hasta $q_4$. Para determinar las transiciones, veremos cómo cambian los valores en nuestro método. En todo momento, si tenemos un valor `count_a = qi`, en la siguiente iteración o bien `count_a = qi` o de lo contrario `count_a = qi + 1`, y esto solo ocurre si el símbolo recién "visto" es $a$. Esto nos dice entonces que tenemos entre los estados $q_i$ y $q_{i+1}$ siempre una transición con $a$, *excepto* en $q_4$, pues en ese caso no se cumple la condición `count_a <= 3`. Solo nos queda definir el estado final, y en este ejemplo no puede estar más claro, pues la línea `return count_a == 3` nos dice exactamente qué estado (valor de `count_a`) corresponde a un valor `True`. De modo que tenemos nuestro autómata: + +```python echo=False, results="plain" +Automaton('q0', ['q3'], { + ('q0', 'a'): 'q1', + ('q1', 'a'): 'q2', + ('q2', 'a'): 'q3', + ('q3', 'a'): 'q4', + + ('q0', 'b'): 'q0', + ('q1', 'b'): 'q1', + ('q2', 'b'): 'q2', + ('q3', 'b'): 'q3', + ('q4', 'b'): 'q4', +}).print(float=False, width="70%") +``` + +Lo que hemos hecho es un ejemplo de lo que informalmente llamamos "programar con autómatas". La idea fundamental radica en pensar en una solución algorítmica al problema de reconocer una cadena de cierto lenguaje $L$, y luego extraer de esta solución un autómata. Para que funcione, informalmente, la solución algorítmica debe cumplir: + +1. Consiste en un método que recibe una cadena y devuelve verdadero o falso. +2. El método consiste en **una sola iteración** sobre la cadena, que analiza cada símbolo exactamente una vez. +3. La memoria local de dicho método, para cualquier cadena, *tanto si pertenece o no* al lenguaje, debe alcanzar a lo sumo una cantidad **finita** de valores diferentes (estos serán los estados de nuestro autómata). + +Para obtener el autómata correspondiente, simplemente contamos *todos* los posibles valores que pueden alcanzar todas las variables locales de nuestro método, y definimos un estado por cada uno. Luego, analizando cómo cambian estos valores en función del símbolo siguiente en la cadena, se definen las transiciones (asumamos que son deterministas de momento). Los estados finales estarán determinidos por las combinaciones de valores para los cuáles el método devuelve `True`. + +De manera general, informalmente, podemos decir que los lenguajes regulares son todos aquellos cuyas cadenas pueden ser reconocidas mediante un método (función en un lenguaje de programación) que, usando *un solo recorrido* sobre la cadena, y una *cantidad finita de memoria (independiente del tamaño de la cadena)* es capaz de determinar *para toda cadena*, si pertenece o no al lenguaje. Si tal método existe, podremos construir un autómata equivalente. + +## Expresiones Regulares {#expreg} + +Ahora que ya sabemos cómo construir autómatas para cualquier lenguaje regular, y sabemos (intuitivamente) que el lenguaje de los *tokens* de un lenguaje de programación se puede definir como un lenguaje regular, nos dedicamos a la pregunta de cómo es mejor definir ese lenguaje. Evidentemente, podemos diseñar un autómata, de forma manual, que reconozca los *tokens*, pero esta tarea, incluso para los lenguajes más sencillos, es muy engorrosa. El problema radica en los autómatas son un mecanismo de cómputo, podemos decir, un mecanismo *procedural* o *imperativo*, para definir lenguajes. Para definir un autómata hay que decidir una cantidad de estados, el conjunto de estados finales y las transiciones. Todo esto no parece intuitivo de antemano. Por otro lado, un autómata es muy difícil de "leer" para un humano. Al mirar un autómata, identificar rápidamente el lenguaje que reconoce no es una tarea sencilla, mucho menos intuitiva. + +De forma alternativa, pudiéramos desear tener un mecanismo *declarativo* que nos permita definir lenguajes de forma más sencilla, y de dónde sea posible de forma automática obtener el autómata correspondiente. Como sabemos de la experiencia anterior en otros lenguajes de programación, los humanos somos muchos mejores mientras mayor sea el nivel de abstracción, y las máquinas son mucho mejores mientras menor sea el nivel abstracción. ¡Justamente por esta diferencia es que surgió la ciencia de la compilación en sí misma! Estamos volviendo a enfrentarnos al mismo problema original, pero en una escala menor. Cabe preguntarnos entonces si podemos crear un mecanismo de "alto nivel" para definir lenguajes regulares, y una especie de "compilador" que transforme este mecanismo de alto nivel al autómata correspondiente. + +## Convirtiendo expresiones regulares a autómatas finitos {#regnfa} + +## Operaciones entre lenguajes regulares {#opers} + +## Los límites de los lenguajes regulares {#pumping} diff --git a/doc/content/chap2.pmd b/doc/content/chap2.pmd new file mode 100644 index 000000000..247d744d8 --- /dev/null +++ b/doc/content/chap2.pmd @@ -0,0 +1,716 @@ +--- +previous-chapter: chap1 +next-chapter: chap3 +--- + +# Parsing Descendente (*Top-Down*) + +Hasta el momento hemos visto el proceso de compilación a grandes razgos, y hemos definido que la primera fase consiste en el análisis sintáctico. Esta fase a su vez la hemos divido en 2 procesos secuenciales: el análisis lexicográfico (*tokenización* o *lexing*), y el análisis sintáctico en sí (*parsing*). En esta sección nos concentraremos en este segundo proceso. + +Recordemos que el proceso de parsing consiste en analizar una secuencia de tokens, y producir un árbol de derivación, lo que es equivalente a producir una derivación extrema izquierda o derecha de la cadena a reconocer. Tomemos la siguiente gramática, que representa expresiones aritméticas (sin ambigüedad): + + E = T + | T + E + + T = int * T + | int + | (E) + +Tomemos la cadena siguiente: + + 2 * (3 + 5) + +Que una vez procesada por la fase lexicográfica produce la siguiente secuencia de *tokens*. + + int * ( int + int ) + +Intentemos producir una derivación (en principio, extrema izquierda, por comodidad) de esta cadena. Como sabemos, si existe una derivación extrema izquierda, es porque se cumple que: + + [1] E -*-> int * ( int + int ) + +Preguntémonos entonces, ¿de cuántas formas pudiera `E` derivar en la cadena? Evidentemente, hay exactamente dos formas en que `E` es capaz de producir esta cadena, es decir, hay solamente dos producciones posibles que pudieran seguir en la derivación extrema izquierda. O bien `E -> T` o bien `E -> T + E`. Probemos entonces con la primera de ellas: + + [2] E -*-> T -*-> int * ( int + int ) + +Como estamos produciendo una derivación extrema izquierda, tenemos que expandir a continuación el símbolo `T`. Nuevamente, hay varias opciones, probemos con la primera: + + [3] E -*-> int * T -*-> int * ( int + int ) + +De momento parece que vamos por buen camino, pues hemos logrado producir los primeros 2 *tokens* de la cadena. Expandimos entonces nuevamente el no-terminal más a la izquierda con la primera producción posible `T -> int * T`: + + [4] E -*-> int * int * T -*-> int * ( int + int ) + +En este punto, podemos darnos cuenta de que hemos tomado el camino equivocado. Como estamos produciendo una derivación extrema izquierda, y los terminales no derivan en ningún símbolo, sabemos que todo lo que esté a la izquierda del primer no-terminal no va a cambiar en el futuro. Luego, es evidentemente que ya no seremos capaces de generar la cadena, pues estos terminales (`int * int *`) no son prefijo de la cadena a reconocer. Deshagamos entonces la última producción (volviendo al paso 3) y probemos otro camino (`T -> int`): + + [4] E -> int * int -*-> int * ( int + int ) + +Nuevamente, hemos generado una secuencia de *tokens* que no es prefijo de la cadena. Probamos de nuevo: + + [4] E -*-> int * ( E ) -*-> int * ( int + int ) + +Parece que en este punto hemos hecho un avance, pues logramos reconocer tres *tokens* de prefijo. Expandimos entonces el nodo `E -> T` nuevamente, y de ahí probamos la próxima producción (`T -> int * T`), que también falla: + + [5] E -*-> int * ( T ) -*-> int * ( int + int ) + [6] E -*-> int * ( int * T ) -*-> int * ( int + int ) + +Probando con cualquiera de las producciones de `T` nunca podremos generar el *token* `+` que falta, por lo tanto eventualmente volveremos a probar con `E -> T + E`: + + [5] E -*-> int * ( T + E ) -*-> int * ( int + int ) + +Una vez llegados a este punto, ya podemos hacernos una idea de cómo funciona este proceso. Eventualmente, tendremos que derivar `T -> int` y `E -> T -> int` para lograr producir la cadena final. Finalmente obtenemos la derivación extrema izquierda siguiente: + + E -> T + -> int * T + -> int * ( E ) + -> int * ( T + E ) + -> int * ( int + E ) + -> int * ( int + T ) + -> int * ( int + int ) + +Básicamente, lo que hemos hecho ha sido probar todas las posibles derivaciones extrema izquierda, de forma recursiva, podando inteligentemente cada vez que era evidente que habíamos producido una derivación incorrecta. Tratemos de formalizar este proceso. + +## Parsing Recursivo Descendente + +De forma general, tenemos tres tipos de operaciones o situaciones que analizar: + +* La expansión de un no-terminal en la forma oracional actual. +* La prueba recursiva de cada una de las producciones de este no-terminal. +* La comprobación de que un terminal generado coincide con el terminal esperado en la cadena. + +Para cada una de estas situaciones, vamos a tener un conjunto de métodos. Para representar la cadena a reconocer, necesitamos mantener un estado global que indique la parte reconocida de la cadena. Diseñemos una clase para ello: + +```cs +interface IParser { + bool Parse(Token[] tokens); +} + +class RecursiveParser : IParser { + Token[] tokens; + int nextToken; + + //... +} +``` + +Para reconocer un terminal, tendremos un método cuya función es a la vez decidir si se reconoce el terminal, y avanzar en la cadena: + +```cs +bool Match(Token token) { + return tokens[nextToken++] == token; +} +``` + +A cada no-terminal vamos a asociar un método recursivo cuya función es determinar si el no-terminal correspondiente genera una sub-cadena "adecuada" del lenguaje. Por ejemplo, para el caso de la gramática anterior, tenemos los siguientes métodos: + +```cs +bool E() { + // Parsea un no-terminal E +} + +bool T() { + // Parsea un no-terminal T +} +``` + +La semántica de cada uno de estos métodos es que devuelven `true` si y solo si el no-terminal correspondiente genera una parte de la cadena, comenzando en la posición `nextToken`. Tratemos de escribir el código del método `E`. Para ello, recordemos que el símbolo `E` deriva en 2 producciones: `E -> T` y `E -> T + E`. Por tanto, de forma recursiva podemos decir que `E` genera esta cadena si y solo si la genera a partir de una de estas dos producciones. El primer caso es fácil: `E` genera la cadena a partir de derivar en `T` si y solo si `T` a su vez genera dicha cadena, y ya tenemos un método para eso: + +```cs +bool E1() { + // E -> T + return T(); +} +``` + +Para el segundo caso, notemos que la producción `E -> T + E` básicamente lo que dice es: necesitamos generar una cadena a partir de `E`, de forma tal que primero se genere una parte con `T`, luego se genere un `+` y luego se genere otra parte con `E`. Dado que ya tenemos todos los métodos necesarios: + +```cs +bool E2() { + // E -> T + E + return T() && Match(Token.Plus) && E(); +} +``` + +Aprovechamos el operador `&&` con cortocircuito para podar lo antes posible el intento de generar la cadena, de forma que el primero de estos tres métodos que falle ya nos permite salir de esa rama recursiva. Ahora que tenemos métodos para cada producción, podemos finalmente develar el cuerpo del método `E`: + +```cs +bool E() { + int currToken = nextToken; + if (E1()) return true; + + nextToken = currToken; + if (E2()) return true; + + return false; +} +``` + +Este método simplemente prueba cada una de las producciones en orden, teniendo cuidado de retornar `nextToken` a su valor original tras cada llamado recursivo fallido. Así mismo, podemos escribir el método asociado al símbolo `T`, basado en los métodos correspondientes a cada producción: + +```cs +bool T1() { + // T -> int * T + return Match(Token.Int) && Match(Token.Times) && T(); +} + +bool T2() { + // T -> int + return Match(Token.Int); +} + +bool T3() { + // T -> (E) + return Match(Token.Open) && E() && Match(Token.Closed) +} +``` + +Y el método general para `T` queda así: + +```cs +bool T() { + int currToken = nextToken; + if (T1()) return true; + + nextToken = currToken; + if (T2()) return true; + + nextToken = currToken; + if (T3()) return true; + + return false; +} +``` + +Es posible hacer estos métodos más compactos introduciendo un nuevo método auxiliar: + +```cs +bool Reset(int pos) { + nextToken = pos; + return true; +} +``` + +Este método nos permite reescribir cada método con una sola expresión, haciendo uso del operador `||` con cortocircuito: + +```cs +bool E() { + int n = nextToken; + return E1() || Reset(n) && E2(); +} + +bool T() { + int n = nextToken; + return T1() || Reset(n) && T2() || Reset(n) && T3(); +} +``` + +Finalmente, para reconocer la cadena completa, solo nos queda garantizar que se hayan consumido todos los *tokens*: + +```cs +bool Parse(Token[] tokens) { + this.tokens = tokens; + nextToken = 0; + + return E() && nextToken == tokens.Length; +} +``` + +Usualmente por comodidad se asume que existe un terminal especial `$` generado directamente por el Lexer al final de toda cadena. Esto se hace para poder generalizar desde el punto de vista teórico, y no tener que especificar siempre si estamos al final de la cadena o no. Si nuestro Lexer produce este token, al que llamaremos `Token.EOF` en el código, entonces podemos reescribir el método anterior de la siguiente forma: + +```cs +bool Parse(Token[] tokens) { + this.tokens = tokens; + nextToken = 0; + + return E() && Match(Token.EOF); // <-- Este es el cambio +} +``` + +Esta metodología para crear parsers recursivos descendentes puede ser aplicada fácilmente a cualquier gramática libre del contexto. Sin embargo, no todas las gramáticas pueden ser reconocidas de esta forma. Según la estructura de la gramática, es posible que el parser definido no funcione correctamente. + +Por ejemplo, para gramáticas ambigüas, el parser (si termina) dará alguna de las derivaciones extrema izquierda posibles, en función del orden en que hayan sido definidas las producciones. Esto se debe al uso de operadores con cortocircuito. Es posible modificar este tipo de parsers fácilmente para generar no solo la primera sino todas las derivaciones extrema izquierda disponibles, simplemente reemplazando los operadores `||` más externos. + +Consideremos ahora la siguiente gramática: + + S -> Sa | b + +Para esta gramática, el parser recursivo descendente queda de la siguiente forma (simplificada): + +```cs +bool S() { + int c = nextToken; + return S() && Match(Token.A) || Reset(n) && Match(Token.B); +} +``` + +El problema evidente con este parser es que al intentar reconocer el símbolo `S` el algoritmo cae en una recursión infinita. Este tipo de gramáticas se denominan gramáticas con recursión izquierda, que definiremos así: + +> **Definición:** Una gramática libre del contexto `G=` se dice recursiva izquierda si y solo si `S -*-> Sw` (donde `w` es una forma oracional). + +La forma más sencilla de las gramáticas recursivas izquierdas es cuando existe directamente una producción `S -> Sw`. A este caso le llamamos *recursión izquierda directa*. Para este caso, es posible eliminar la recursión izquierda de forma sencilla. Tomemos nuevamente la gramática anterior: + + S -> Sa | b + +Es fácil ver que esta gramática general el lenguaje `ba*`. Otra gramática que genera dicho lenguaje sin recursión izquierda es: + + S -> bX + X -> aX | epsilon + +Aún cuando `a` y `b` son formas oracionales en general, y no simplemente terminales, el patrón anterior es válido. De forma general, si una gramática tiene recursión izquierda de la forma: + + S -> Sa1 | Sa2 | ... San | b1 | b2 | ... | bm + +Es posible eliminar la recursión izquierda con la transformación: + + S -> b1X | b2X | ... | bmX + X -> a1X | a2X | ... | anX | epsilon + +Para el caso más general de recursión izquierda indirecta, también existe un algoritmo para su eliminación, pero de momento no lo presentaremos :(. + +El algoritmo de parsing que hemos desarrollado resuelve, al menos de forma teórica, el problema de construir el árbol de derivación. Aunque el código presentado no construye explícitamente el árbol de derivación, es bastante fácil modificarlo al respecto. Sin embargo, aunque en principio el problema ha sido resuelto, el algoritmo recursivo descendente es extremadamente ineficiente. El problema es que, en principio, es necesario probar con todos los árboles de derivación posibles antes de encontrar el árbol correcto. De cierta forma, para resolver el problema de parsing lo que hemos hecho es buscar entre todos los posibles programas, cuál de ellos tiene una representación textual igual a la cadena deseada. + +## Parsing Predictivo Descendente + +Idealmente, quisiéramos un algoritmo de parsing que construya el árbol de derivación con un costo lineal con respecto a la cadena de entrada. Para ello, necesitamos poder "adivinar", en cada método recursivo, cuál es la rama adecuada a la que descender. Con vistas a resolver este problema, consideremos nuevamente la gramática vista en la sección anterior: + + E -> T | T + E + T -> int * T | int | (E) + +Analicemos ahora nuevamente la cadena de *tokens* `int * ( int + int )`, y tratemos de "adivinar" en cada paso de una derivación extrema izquierda qué producción es necesario aplicar. Tengamos en cuenta que en cada paso del proceso de parsing, hay al menos un *token* que conocemos tiene que ser generado de inmediato (dado que la gramática no puede "intercambiar" *tokens* una vez generados). Por tanto, observando el siguiente *token* que es necesario generar (`nextToken` en nuestra implementación), tenemos una pista de cuáles producciones no son posibles. En el caso anterior, el primer *token* a generar es `int`. Por tanto, es evidente que ninguna producción que derive en `(E)` funciona, pues el `(` no coincidirá con el *token* `int`. La primera producción a aplicar tiene que derivar en una forma oracional que comience por `int`. + +Desafortunadamente existen varias producciones que generan un `int` al inicio. Tanto `T -> int` como `T -> int * T` pudieran ser escogidas. Aún más, a cualquiera de estas dos producciones se llega tanto por `E -> T` como por `E -> T + E`. Por tanto, hay varios caminos por los cuáles se pudiera generar el primer *token* `int`. Intuitivamente, esto se debe a que la gramática no está **factorizada**. Informalmente, llamaremos a una gramática **factorizada a la izquierda** si las producciones de cualquier símbolo, dos a dos, no comparten ningún prefijo. + +En muchas ocasiones es fácil factorizar una gramática. Se introduce un no-terminal nuevo por cada grupo de producciones que compartan un prefijo común. Se reemplazan dichas producciones por una sola producción nueva que contiene el prefijo común, y el nuevo no-terminal se hace derivar en todos los posibles sufijos: + + E -> T X + X -> + E | epsilon + T -> int Y | (E) + Y -> * T | epsilon + +Por supuesto, es posible que la relación entre los prefijos sea más complicada, y una vez que se realice la transformación anterior aún queden producciones no factorizadas (e.j. `X -> abC | abD | aY`). Incluso en estos casos es posible factorizar la gramática aplicando varias veces el proceso de factorización anterior. + +Esta modificación evidentemente no cambia el lenguaje, y ni siquiera cambia la ambigüedad o no de la gramática. Simplemente nos permite delegar la decisión de qué producción tomar un *token* hacia adelante. Si antes no sabíamos cuando venía `int` que producción tomar, porque podía ser `T -> int` o `T -> int * T`, ahora simplemente reconocemos el primer `int`, y delegamos la decisión de generar `epsilon` o `* T` a un nuevo no-terminal. + +Desde el punto de vista del diseño de lenguajes, el beneficio de este cambio es discutible. Por un lado nos permite aplicar un algoritmo que de otra forma no funcionaría. Sin embargo, por otra parte, estamos provocando un cambio en el diseño de la gramática, que es una cuestión de "alto nivel", para poder usar un algoritmo particular, que es una cuestión de "bajo nivel". En otras palabras, estamos cambiando el diseño en función de la implementación. Este cambio puede tener efectos adversos. Por ejemplo, nuestra gramática para expresiones aritméticas es ahora más difícil de entender, pues contiene símbolos "extraños" que no significan nada desde el punto de vista semántico, solamente están ahí para simplificar la implementación. El árbol de derivación ahora es más complejo. Más adelante discutiremos esta problemática en mayor profundidad. + +Consideremos ahora nuevamente el proceso de parsing, y tratemos de ver si es posible adivinar en todo caso cuál producción aplicar. Tomemos como ejemplo la cadena `int * ( int + int )`, y tratemos de generar la derivación extrema izquierda: + + E -*-> int * ( int + int ) + +La primera producción tiene que ser necesariamente `E -> T X` pues es la única disponible: + + E -*-> T X -*-> int * ( int + int ) + +Ahora, tenemos que expandir el primer símbolo `T`. Afortunadamente, sabemos que esta expansión obligatoriamente genera un *token* a continuación, ya sea `int` o `(`. Por tanto es trivial escoger la única producción posible: + + E -*-> int Y X -*-> int * ( int + int ) + +El nuevo símbolo a expandir es `Y`, y ahora se nos complica un poco el análisis. `Y` bien pudiera desaparecer (`Y -> epsilon`) o generar un `* T`. Sabemos que la producción `* T` nos genera el token que queremos. Pero la pregunta es, ¿cómo sabemos que la producción `Y -> epsilon` no pudiera redundar en que eventualmente aparezca ese `*` por otro lado? Observando la gramática, intuitivamente, podemos ver que si `Y` desaparece, `X` nunca podrá poner un `*` justamente en esa posición, ya que `X` tiene que generar primero un `+` (`X -> + E`) antes de que aparezca otro no-terminal que pudiera generar el `*`. Por tanto, la única producción posible es `Y -> * T`: + + E -*-> int * T X -*-> int * ( int + int ) + +En este punto es fácil ver que la única solución es derivar `T -> ( E )`, pues `T` nunca desaparece: + + E -*-> int * ( E ) X -*-> int * ( int + int ) + +Ahora volvemos al punto inicial: + + E -*-> int * ( T X ) X -*-> int * ( int + int ) + +Nuevamente `T` tiene que generar un `int`: + + E -*-> int * ( int Y X ) X -*-> int * ( int + int ) + +Evidentemente `Y` no puede generar el token `+` que hace falta, así que solo puede desaparecer: + + E -*-> int * ( int X ) X -*-> int * ( int + int ) + +Volvemos entonces a la situación complicada anterior. Es cierto que `X -> + E` nos sirve, pero ¿cómo sabemos que es la única opción? ¿Es posible que de `X -> epsilon` se logre en algún momento que aparezca un `+`. Si miramos la forma oracional generada hasta el momento, vemos que no nos queda otra `X` dentro los paréntesis que pueda poner el `+` que falta. Sin embargo, este análisis no lo puede hacer nuestro algoritmo, que solamente conoce el no-terminal actual, y el siguiente token que es necesario generar. Tratemos de hacer un razonamiento un poco más generalizable. La pregunta que estamos haciendo aquí básicamente es si es conveniente eliminar `X` con la esperanza de que aparezca un `+` de lo que sea que venga detrás. Más adelante formalizaremos este concepto, pero por ahora baste decir que, intuitivamente, podemos ver que detrás de una `X` solamente puede venir o bien un `)` o bien el fin de la cadena. Por tanto, no queda otra opción que derivar `X -> + E`: + + E -*-> int * ( int + E ) X -*-> int * ( int + int ) + +Generar el siguiente `int` es fácil: + + E -*-> int * ( int + T X ) X -*-> int * ( int + int ) + E -*-> int * ( int + int Y X ) X -*-> int * ( int + int ) + +Finalmente nos queda por generar un `)`. Claro que si miramos la forma oracional generada, sabemos que es necesario eliminar `Y` y `X`, pero recordemos que nuestro algoritmo no puede ver tan hacia adelante. De todas formas, no hace falta mirar más, ni `Y` ni `X` son capaces de generar nunca un `)`, así que ambos símbolos desaparecen: + + E -*-> int * ( int + int X ) X -*-> int * ( int + int ) + E -*-> int * ( int + int ) X -*-> int * ( int + int ) + +Y finalmente la última `X` debe desaparecer también pues se ha generado toda la cadena. Finalmente nos queda: + + E -> T X + -> int Y X + -> int * T X + -> int * ( E ) X + -> int * ( T X ) X + -> int * ( int Y X ) X + -> int * ( int X ) X + -> int * ( int + E ) X + -> int * ( int + T X ) X + -> int * ( int + int Y X ) X + -> int * ( int + int X ) X + -> int * ( int + int ) X + -> int * ( int + int ) + +La derivación extrema izquierda producida es considerablemente mayor con esta gramática factorizada, dado que existen más producciones. Sin embargo, ganamos en un factor exponencial al eliminar el *backtrack* por completo. Intuitivamente, el largo de esta derivación debe ser lineal con respecto a la longitud de la cadena de entrada, pues a lo sumo en cada paso o bien generamos un nuevo *token* o derivamos el símbolo más izquierdo en nuevos símbolos. Dado que no tenemos recursión izquierda, estas operaciones con cada símbolo no pueden ser "recursivas". Es decir, si el no-terminal más izquierdo es `Y`, y empezamos a derivarlo, eventualmente terminaremos con ese `Y`, ya sea produciendo un terminal o derivando en `epsilon`. De forma general, el costo está acotado superiormente por `|w| * |N|`, pues no es posible que para generar un *token* sea necesario usar `|N| + 1` no terminales, ya que en ese caso tendríamos un no-terminal derivando en sí mismo (al menos de forma indirecta), lo que contradice que la gramática no tenga recursión izquierda. + +Tratemos ahora de formalizar este proceso de "adivinación" de qué producción aplicar en cada caso. De forma general nos hemos enfrentado a dos interrogantes fundamentalmente distintas: + +* Saber si alguna de las producciones de X puede derivar en una forma oracional cuyo primer símbolo sea el terminal que toca generar. +* Si `X -> epsilon`, saber si esta derivación puede potencialmente redundar en que "lo que sea que venga detrás" de `X` genere el terminal que toca. + +Si para las preguntas anteriores obtenemos una sola producción como respuesta, entonces podemos estar seguros de la decisión a tomar. En caso de que obtengamos más de una respuesta, nuestro algoritmo no podrá decidir qué producción tomar, y será inevitable el *backtrack*. Para encontrar una respuesta a estas preguntas, intentemos formalizar estos conceptos de "`X` puede derivar en..." y "lo que venga detrás de `X`...". + +Llamaremos `First(W)` al conjunto de todos los terminales que pueden ser generados por `W` como primer elemento (siendo `W` una forma oracional cualquiera, no solamente un no-terminal). Formalmente: + +> **Definición**: Sea $G=$ una gramática libre del contexto, $W \in { N \cup T }^*$ una forma oracional, y $x \in T$ un terminal. Decimos que $x \in First(W)$ si y solo si $W \prs xZ$ (donde $Z \in \{ N \cup T \}^*$ es otra forma oracional). + +Este concepto captura formalmente la noción de "comenzar por". De forma intuitiva, si logramos computar el conjunto `First(W)` para todas las producciones `X -> W` de nuestra gramática, y cada uno de estos conjuntos de las producciones del mismo símbolo son disjuntos dos a dos, entonces podremos decir inequívocamente qué producción aplicar para generar el terminal que toca (o cuando no es posible generarlo). Notemos que fue necesario definir `First(W)` no solo para un no-terminal, sino para una forma oracional en general, pues necesitamos computarlo en toda parte derecha de una producción. + +Por otro lado, la noción de "lo que viene detrás" se formaliza en un concepto similar, denominado `Follow(X)`. En este caso solo necesitamos definirlo para un no-terminal, pues solo nos interesan las producciones `X -> epsilon`. Informalmente diremos que el `Follow(X)` son todos aquellos terminales que pueden aparecer en cualquier forma oracional, detrás de un no-terminal `X`. Formalmente: + +> **Definición**: Sea $G=$ una gramática libre del contexto, $X \in N$ un no-terminal, y $x \in T$ un terminal. Decimos que $x \in Follow(X)$ si y solo si $S -*-> WXxZ$ (donde $W, Z \in \{ N \cup T \}^*$ son formas oracionales cualesquiera). + +La definición de `Follow(X)` básicamente nos dice que si en algún momento el terminal que queremos generar `x` está justo detrás del no-terminal `X` que toca expandir, entonces `X -> epsilon` es una producción válida a aplicar, porque existe la posibilidad de que otro no-terminal genere a `x` justo en esa posición (aunque en la cadena particular que se está reconociendo puede que esto no sea posible). + +Supongamos entonces que tenemos todos estos conjuntos calculados (o potencialmente calculables en cualquier momento). ¿Cómo podemos utilizarlos para guiar la búsqueda del árbol de derivación correcto? Veamos como podría quedar el método recursivo descendente para generar `T` en esta nueva gramática: + +```cs +bool T() { + // T -> int Y + if (tokens[currToken] == Token.Int) + return Match(Token.Int) && Y(); + + // T -> ( E ) + else if (tokens[currToken] == Token.Open) + return Match(Token.Open) && E() && Match(Token.Close); + + return false; +} +``` + +Como `T` siempre genera un token, es fácil decidir qué camino escoger. Por otro lado, en la expansión de `X`, es posible que sea necesario escoger `X -> epsilon`. En este caso, el método recursivo sería: + +```cs +bool X() { + // X -> + E + if (tokens[nextToken] == Token.Plus) + return Match(Token.Plus) && E() + + // X -> epsilon + else if (Follow("X").Contains(tokens[currToken])) + return true; + + return false; +} +``` + +En el caso de `X -> epsilon`, simplemente retornamos `true` de inmediato y no consumimos el terminal correspondiente. + +De forma general, podemos escribir cualquier método recursivo descendente de la siguiente forma (asumimos algunos métodos y clases utilitarios que no presentaremos formalmente): + +```cs +bool Expand(NonTerminal N) { + foreach(var p in N.Productions) { + if (!p.IsEpsilon && First(p).Contains(tokens[nextToken])) + return MatchProduction(p); + + if (p.IsEpsilon && Follow(N).Contains(tokens[nextToken])) + return true; + } + + return false; +} +``` + +El método `MatchProduction` puede a grandes razgos implementarse de la siguiente forma: + +```cs +bool MatchProduction(Production p) { + foreach(var symbol in p.Symbols) { + if (symbol.IsTerminal && !Match(symbol as Token)) + return false; + + if (!symbol.IsTerminal && !Expand(symbol as NonTerminal)) + return false; + } + + return true; +} +``` + +En todos estos casos hemos asumido que la primera producción aplicable era la única posible. Para ello deben cumplirse ciertas restricciones entre los conjuntos `First` y `Follow` que formalizaremos a continuación. + +## Gramáticas LL(1) + +Llamaremos gramáticas LL(1) justamente a aquellas gramáticas para las cuales el proceso de cómputo de `First` y `Follow` descrito informalmente en la sección anterior nos permite construir un parser que nunca tenga que hacer *backtrack*. El nombre LL(1) significa *left-to-right left-derivation look-ahead 1*. Es decir, la cadena se analiza de izquierda a derecha, se construye una derivación extrema izquierda, y se analiza un solo *token* para decidir que producción aplicar. De forma general, existen las gramáticas LL(k), donde son necesarios k *tokens* para poder predecir que producción aplicar. Aunque los principios son los mismos, el proceso de construcción de estos conjuntos es más complejo, y por lo tanto no analizaremos estas gramáticas por el momento :(. + +Para poder formalizar este concepto, será conveniente primero encontrar algoritmos explícitos para computar los conjuntos `First` y `Follow`. Comencemos por el `First` ;). Veamos primero algunos hechos interesantes que se cumplen en este conjunto, y luego veremos cómo se diseña un algoritmo para su cómputo. No presentaremos demostración para estos hechos, pues la mayoría son intuitivos. + +* Si $X \pr W1 | W2 | \ldots | Wn$ entonces por definición, $First(X) = \cup First(W_i)$. +* Si $X \prs \ep$ entonces $\ep \in First(X)$. +* Si $W = xZ$ donde $x$ es un terminal, entonces trivialmente $First(W) = { x }$. +* Si $W = YZ$ donde $Y$ es un no-terminal y $Z$ una forma oracional, entonces $First(Y) \subseteq First(W)$. +* Si $W = YZ$ y $Y \prs \ep$ entonces $First(Z) \subseteq First(W)$. + +Las observaciones anteriores nos permiten diseñar un algoritmo para calcular todos los conjuntos `First(X)` para cada no-terminal `X`. Como de forma general pueden existir producciones recursivas, calcularemos todos los conjuntos `First` a la vez, aplicando cada una de las "reglas" anteriores, hasta que no se modifique ninguno de los conjuntos `First`. Nuevamente abusaremos de la imaginación y creatividad para introducir métodos y clases utilitarias sin definirlos de manera formal. + +```cs +Firsts CalculateFirsts(Grammar G) { + var Firsts = new Firsts(); // Parecido a un Diccionario + + // Calculamos el First de cada terminal + foreach(var t in G.Terminals) { + Firsts[t] = new FirstSet() { t }; + } + foreach(var T in G.NonTerminals) { + Firsts[T] = new FirstSet(); // Parecido a un HashSet + } + + bool changed; + + do { + changed = false; + + // Vamos por cada producción + foreach(var p in G.Productions) { + // X -> W + var X = p.Left; + var W = p.Right; + + if (p.IsEpsilon) { // X -> epsilon + changed = Firsts[X].Add(epsilon); + } + else { + bool allEpsilon = true; + + foreach(var s in W) { + // Agregamos todo en el First(s) + changed = Firsts[X].AddAll(Firsts[s]); + + // Si s_i deriva en epsilon, + // agregamos también el First(s_i+1) + if (!Firsts[s].Contains(epsilon)) { + allEpsilon = false; + break; + } + } + + // Si todos los s_i derivan en epsilon + // entonces epsilon pertenece al First(X) + if (allEpsilon) { + changed = Firsts[X].Add(epsilon); + } + } + } + } while (changed); + + return Firsts; +} +``` + +El algoritmo anterior computa todos los conjuntos `First` de todos los terminales y no-terminales a la vez. Hemos supuesto la existencia de estructuras de datos `Firsts` y `FirstSet` con operaciones convenientes para ello. Estas estructuras se implementan fácilmente usando diccionarios y conjuntos. Una vez obtenidos todos los `First` anteriores, podemos calcular fácilmente el `First` de cualquier forma oracional. + +```cs +FirstSet CalculateFirst(Symbol[] p, Firsts firsts) { + FirstSet result = new FirstSet(); + bool allEpsilon = true; + + foreach(var s in p) { + result.AddAll(Firsts[s]); + + if (!Firsts[s].Contains(epsilon)) { + allEpsilon = false; + break; + } + } + + if (allEpsilon) { + result.Add(epsilon); + } + + return result; +} +``` + +Básicamente este nuevo algoritmo consiste en repetir la parte más interna del algoritmo anterior, así que no son necesarias más explicaciones. + +Pasemos entonces a calcular el conjunto `Follow` de cada no-terminal. Para ello, veamos también algunos hechos que nos ayudarán a entender como está formado este conjunto: + +* `$` pertenece al `Follow(S)`. +* Por definición `epsilon` nunca pertenece al `Follow(X)` para todo `X`. +* Si `X -> WAZ` siendo `W` y `Z` formas oracionales, y `A` un no-terminal cualquiera, entonces `First(Z) - { epsilon } \subseteq Follow(A)`. +* Si `X -> WAZ` y `Z -*-> epsilon` (o igualmente `epsilon` está en el `First(Z)`), entonces `Follow(X) \subseteq Follow(A)`. + +De la misma forma que en el caso del conjunto `First`, dado que las relaciones entre los `Follow` de cualquier par de no-terminales pueden ser recursivas, diseñaremos un algoritmo que los computa a todos a la misma vez: + +```cs +Follows CalculateFollows(Grammar G, Firsts firsts) { + var Follows = new Follows(); + + Follows[S] = new FollowSet() { Token.EOF }; + + foreach(var X in G.NonTerminals) { + Follows[X] = new FollowSet(); + } + + bool changed; + + do { + changed = false; + + foreach(var p in G.Productions) { + // X -> W + var X = p.First; + var W = p.Last; + + for(int i=0; i < W.Length; i++) { + var S = W[i]; + + if (S.IsTerminal) + continue; + + var first = CalculateFirst(W.Sufix(i+1)); + changed = Follows[S].AddAll(first.Remove(epsilon)); + + if (first.Contains(epsilon) || i == W.Length - 1) { + changed = Follows[S].AddAll(Follows[X]); + } + } + } + + } while (changed); +} +``` + +Una vez tenemos todos los conjuntos `First` y `Follow` calculados, podemos decir formalmente en qué consiste una gramática LL(1). Para ello, construiremos una tabla `T`, donde asociaremos a cada par no-terminal `X` / token `t` una producción (a lo sumo). Dicha producción es la única que tiene sentido aplicar si se debe expandir el no-terminal `X` y el token actual es `t`. + +Las reglas generales para generar esta tabla son las siguientes: + +1. Si `X -> W` y `t` pertenece al `First(W)` entonces `T[X,t] = X -> W`. +2. Si `X -> epsilon` y `t` pertenece al `Follow(X)` entonces `T[X,t] = X -> epsilon`. + +Si al aplicar estas reglas, en cada posición `T[X,t]` obtenemos a lo sumo una producción, entonces decimos que una gramática es LL(1). En caso contrario, tenemos al menos un conflicto, pues hay más de una producción que tiene sentido utilizar en algún caso. Formalmente: + +> **Definición:** Sea $G=$ una gramática libre del contexto. $G$ es LL(1) si y solo si para todo no-terminal $X \in N$, tal que $X \leftarrow W_1 | W_2 | ... | W_n$ se cumple que: +> +> * $First(Wi) \bigcap First(Wj) = \emptyset \,\, \forall i \neq j$ +> +> * $\epsilon \in First(Wi) => First(Wj) \bigcap Follow(X) = \emptyset \,\, \forall j \neq i$ + +Esta definición nos garantiza que en toda entrada de la tabla LL(1) exista a lo sumo una producción a aplicar. Ahora podemos demostrar que la gramática anterior para expresiones, una vez factorizada, es LL(1): + + E -> T X + X -> + E | epsilon + T -> int Y | ( E ) + Y -> * T | epsilon + +Comencemos por calcular todos los conjuntos `First`. Para los terminales es trivial: + + First( int ) = { int } + First( + ) = { + } + First( * ) = { * } + First( ( ) = { ( } + First( ) ) = { ) } + +Ahora calculemos los `First` de cada no-terminal: + + First(E) = { (, int } + First(X) = { +, epsilon } + First(T) = { (, int } + First(Y) = { *, epsilon } + +Luego podemos calcular los `First` de cada parte derecha de cada producción: + + First( T X ) = { (, int } + First( + E ) = { + } + First(int Y) = { int } + First( (E) ) = { ( } + First( * T ) = { * } + +Calculemos finalmente los `Follow` de cada no-terminal: + + Follow(E) = { $, ) } + Follow(X) = { $, ) } + Follow(T) = { +, $, ) } + Follow(Y) = { +, $, ) } + +Ahora podemos llenar la tabla LL(1). Comencemos por la fila correspondiente a `E`. Para ello analizamos la producción `E -> T X`. Por la regla (1) podemos decir que esta producción se aplica solo para los terminales `(` y `int`. + + int \+ \* ( ) $ + --- ------- ------- ------- ------- ------- ------- + E T X T X + --- ------- ------- ------- ------- ------- ------- + +Veamos entonces la fila asociada a `T`. La producción `T -> int Y` solamente se aplica para el token `int` mientas que la producción `T -> (E)` se aplica solamente para `(`. + + int \+ \* ( ) $ + --- ------- ------- ------- ------- ------- ------- + T int Y ( E ) + --- ------- ------- ------- ------- ------- ------- + +Ahora veamos las producciones de `X`. Para `X -> + E` la única entrada importante es con el token `+`. Por otro lado, la producción `X -> epsilon` se aplica en todos los tokens que pertenezcan al `Follow(X)`, es decir, `$` y `)`. + + int \+ \* ( ) $ + --- ------- ------- ------- ------- ------- ------- + X \+ E \ep \ep + --- ------- ------- ------- ------- ------- ------- + +Finalmente para el no-terminal `Y`, la producción `Y -> * T` es trivial, y la producción `Y -> \epilon` se aplica para `+`, `$` y `)`. + + int \+ \* ( ) $ + --- ------- ------- ------- ------- ------- ------- + Y \ep \* T \ep \ep + --- ------- ------- ------- ------- ------- ------- + +Finalmente, nos queda la tabla completa. Dado que no encontrarmos conflictos al construirla, podemos concluir que la gramática es LL(1): + + int \+ \* ( ) $ + --- ------- ------- ------- ------- ------- ------- + E T X T X + T int Y ( E ) + X \+ E \ep \ep + Y \ep \* T \ep \ep + --- ------- ------- ------- ------- ------- ------- + +## Parsing Descendente No Recursivo + +Una vez obtenida la tabla LL(1) podemos escribir un algoritmo de parsing descendente no recursivo. La idea general consiste en emplear una pila de símbolos, donde iremos construyendo la forma oracional que eventualmente derivará en la cadena a reconocer. Si leemos la pila desde el tope hasta el fondo, en todo momento tendremos una forma oracional que debe generar la parte de la cadena no reconocida. + +El símbolo en el tope de la pila representa el terminal o no-terminal a analizar. En caso de ser un terminal, debe coincidir con el token analizado. En caso de ser un no-terminal, se consulta la tabla LL(1) y se ejecuta la producción correspondiente, insertando en la pila (en orden inverso) la forma oracional en que deriva el no-terminal extraído: + +```cs +bool NonRecursiveParse(Grammar G, Token[] tokens) { + Stack stack = new Stack() { G.Start }; + int nextToken = 0; + LLTable table = BuildLLTable(G); + + while (stack.Count > 0 && nextToken < tokens.Length) { + var symbol = stack.Pop(); + + if (symbol.IsTerminal && tokens[nextToken++] != symbol.Value) { + return false; + } + else if (symbol.IsNonTerminal) { + var prod = LLTable[symbol, tokens[nextToken]]; + + if (prod == null) + return false; + + for(var s in prod.Reverse()) { + stack.Push(s); + } + } + } + + return stack.Count == 0 && nextToken == tokens.Length; +} +``` + +En la práctica la mayoría de las gramáticas interesantes no son LL(1). Sin embargo, con suficiente esfuerzo pueden lograrse gramáticas LL(k) para un valor k > 1, que también pueden ser parseadas con técnicas similares. Por otro lado, para gramáticas suficientemente simples (como las expresiones aritméticas) este parser es muy eficiente, y fácil de implementar. + +Finalmente, en el caso que la gramática no sea LL(1), este análisis nos permite reducir al mínimo necesario la cantidad de producciones a probar en cada terminal. La tabla LL(1) en estos casos pudiera tener más de una producción en cada entrada, y en esos casos implementaríamos un parser recursivo que solamente probara aquellas producciones listadas en la tabla. De esta forma, podemos obtener el parser (descendiente) más eficiente posible, sin perder en expresividad. + +De todas formas las gramáticas LL(1) son un conjunto estrictamente menor que las gramáticas libres del contexto. Más adelante veremos estrategias de parsing basadas en principios similares que permiten reconocer lenguajes y gramáticas más expresivas. diff --git a/doc/content/chap3.pmd b/doc/content/chap3.pmd new file mode 100644 index 000000000..e70005c7a --- /dev/null +++ b/doc/content/chap3.pmd @@ -0,0 +1,1043 @@ +--- +previous-chapter: chap2 +next-chapter: chap4 +--- + +# Parsing Ascendente (*Bottom-Up*) + +En la sección anterior vimos las técnicas de parsing descendente, y aprendimos algunas de las limitaciones más importantes que tienen. Dado que el objetivo es poder predecir exactamente que producción es necesario ejecutar en cada momento, las gramáticas LL(1) tienen fuertes restricciones. En particular, deben estar factorizadas, y no pueden tener recursión izquierda (criterios que son necesarios pero no suficientes). Por este motivo, para convertir una gramática "natural" en una gramática LL(1) es necesario adicionar no-terminales para factorizar y eliminar la recursión, que luego no tienen ningún significado semántico. Los árboles de derivación de estas gramáticas son por tanto más complejos, y tienen menos relación con el árbol de sintaxis abstracta que queremos obtener finalmente (aunque aún no hemos definido este concepto formalmente). + +Intuitivamente, el problema con los parsers descendentes, es que son demasiado exigentes. En cada momento, se quiere saber qué producción hay que aplicar para obtener la porción de cadena que sigue. En otras palabras, a partir de una forma oracional, tenemos que decidir cómo expandir el no-terminal más a la izquierda, de modo que la siguiente forma oracional esté "más cerca" de generar la cadena. Por este motivo se llama parsing descendente. + +¿Qué pasa si pensamos el problema de forma inversa? Comenzamos con la cadena completa, y vamos a intentar reducir fragmentos de la cadena, aplicando producciones "a la inversa" hasta lograr reducir toda la cadena a `S`. En vez de intentar adivinar que producción aplicar "de ahora en adelante", intentaremos deducir, dado un prefijo de la cadena analizado, qué producción se puede "desaplicar" para reducir ese prefijo a una forma oracional que esté "más cerca" del símbolo inicial. Si pensamos el problema de forma inversa, puede que encontremos una estrategia de parsing que sea más permisiva con las gramáticas. + +Veamos un ejemplo. Recordemos la gramática "natural" no ambigua para expresiones aritméticas: + + E = T + E | T + T = int * T | int | ( E ) + +Y la cadena de siempre: `int * ( int + int )`. Tratemos ahora de construir una derivación "de abajo hacia arriba", tratando de reducir esta cadena al símbolo inicial `E` aplicando producciones a la inversa. Vamos a representar con una barra vertical `|` el punto que divide el fragmento de cadena que hemos analizado del resto. De modo que empezamos por: + + |int * ( int + int ) + +Miramos entonces el primer token: + + int|* ( int + int ) + +El primer token de la cadena es `int`, que se puede reducir aplicando `T -> int` a la inversa. Sin embargo, esta reducción no es conveniente. ¿Por qué? El problema es que queremos lograr reducir hasta `E`, por tanto hay que tener un poco de "luz larga" y aplicar reducciones que, en principio, dejen la posibilidad de seguir reduciendo hasta `E`. Como no existe ninguna producción que derive en `T * w`, si reducimos `T -> int` ahora no podremos seguir reduciendo en el futuro. Más adelante formalizaremos esta idea. Seguimos entonces buscando hacia la derecha en la cadena: + + int *|( int + int ) + int * (|int + int ) + int * ( int|+ int ) + +En este punto podemos ver que sí es conveniente reducir `T -> int`, porque luego viene un `+` y tenemos, en principio, la posibilidad de seguir reduciendo aplicando `E -> T + E` en el futuro: + + int * ( T|+ int ) + +Avanzamos hacia el siguiente token reducible: + + int * ( T +|int ) + int * ( T + int|) + +Aquí nuevamente podemos aplicar la reducción `T -> int`: + + int * ( T + T|) + +Antes de continuar, dado que tenemos justo delante de la barra (`|`) un sufijo `T + T`, deberíamos darnos cuenta que es conveniente reducir `E -> T` para luego poder reducir `E -> T + E`: + + int * ( T + E|) + int * ( E|) + +En este punto, no hay reducciones evidentes que realizar, así que seguimos avanzando: + + int * ( E )| + +Hemos encontrado entonces un sufijo `( E )` que podemos reducir con `T -> (E)`: + + int * T| + +Luego reducimos `T -> int * T`: + + T| + +Y finalmente reducimos `E -> T`: + + E + +En este punto hemos logrado reducir al símbolo inicial toda la cadena. Veamos la secuencia de formas oracionales que hemos obtenido: + + int * ( int + int ) + int * ( T + int ) + int * ( T + T ) + int * ( T + E ) + int * ( E ) + int * T + T + E + +Si observamos esta secuencia en orden inverso, veremos que es una derivación extrema derecha de `E -*-> int * ( int + int )`. Justamente, un parser ascendente se caracteriza porque construye una derivación extrema derecha en orden inverso, desde la cadena hacia el símbolo inicial. Tratemos ahora de formalizar este proceso. Para ello, notemos primero algunas propiedades interesante que cumple todo parser ascendente. Partimos del hecho que hemos dado como definición de un parser bottom-up: + +> Un parser bottom-up construye una derivación extrema derecha de $S \rightarrow^* \omega$. + +A partir de este hecho, que hemos dado como definición, podemos deducir una consecuencia muy interesante: + +> Sea $\alpha \beta \omega$ una forma oracional en un paso intermedio de un parser ascendente. +> Sea $X \rightarrow \beta$ la siguiente reducción a realizar. +> Entonces $\omega$ es una cadena de terminales (formalmente $\omega \in T^*$). + +Para ver por qué esto es cierto, basta notar que si la derivación que construiremos es extrema derecha, la aplicación de $X \rightarrow \beta$ en este paso solamente puede ocurrir si $X$ es el no-terminal más a la derecha. O sea, si $\alpha \beta \omega$ es el paso correspondiente, y reducimos por $X \rightarrow \beta$, entonces el siguiente paso es la forma oracional $\alpha X \omega$, donde $X$ es el no-terminal más a la derecha, debido justamente a que estamos construyendo una derivación extrema derecha. + +Esta propiedad nos permite entonces entender que en todo paso de un parser ascendente, cada vez que sea conveniente reducir $X \rightarrow \beta$, es porque existe una posición (que hemos marcado con `|`), tal que $\alpha \beta | \omega$ es la forma oracional, donde $\alpha \beta \in \{ N \cup T \}^*$ y $\omega \in T^*$. Tenemos entonces dos tipos de operaciones que podemos realizar, que llamaremos **shift** y **reduce**. La operación **shift** nos permite mover la barra `|` un token hacia la derecha, lo que equivale a decir que analizamos el siguiente token. La operación **reduce** nos permite coger un sufijo de la forma oracional que está antes de la barra `|` y reducirla a un no-terminal, aplicando una producción a la inversa (o "desaplicando" la producción). Veamos nuevamente la secuencia de operaciones que hemos realizado, notando las que fueron **shift** y las que fueron **reduce**: + + |int * ( int + int ) | shift + int|* ( int + int ) | shift + int *|( int + int ) | shift + int * (|int + int ) | shift + int * ( int|+ int ) | reduce T -> int + int * ( T|+ int ) | shift + int * ( T +|int ) | shift + int * ( T + int|) | reduce T -> int + int * ( T + T|) | reduce E -> T + int * ( T + E|) | reduce E -> T + E + int * ( E|) | shift + int * ( E )| | reduce T -> ( E ) + int * T| | reduce T -> int * T + T| | reduce E -> T + E | OK + +Debido a estas operaciones, llamaremos a este tipo de mecanismos *parsers shift-reduce*. Veamos de forma general como implementar este tipo de parsers. + +## Parsers *Shift-Reduce* + +Notemos que la parte a la izquierda de la barra siempre cambia porque un sufijo es parte derecha de una producción, y se reduce a un no-terminal. La parte derecha solo cambia cuando un terminal "cruza" la barra y se convierte en parte del sufijo que será reducido en el futuro. De forma que la barra que la parte izquierda se comporta como una pila, ya que solamente se introducen terminales por un extremo, y se extraen símbolos (terminales o no-terminales) por el mismo extremo. La parte derecha es simplemente una secuencia de tokens, que se introducen en la pila uno a uno. Formalicemos entonces el funcionamiento de un parser *shift-reduce*. + +Un parser *shift-reduce* es un mecanismo de parsing que cuenta con las siguientes estructuras: + +* Una pila de símbolos `S`. +* Una secuencia de terminales `T`. + +Y las operaciones siguientes: + +* **shift**: Si $S = \alpha |$ es el contenido de la pila, y $T = c \omega \$$ la secuencia de terminales, entonces tras aplicar una operación **shift** se tiene en la pila $S' = \alpha c |$, y la secuencia de terminales ahora es $T' = \omega \$$. Es decir, se mete en la pila el token $c$. +* **reduce**: Si $S = \alpha \beta |$ el contenido de la pila, y $X \rightarrow \beta$ es una producción, entonces tras aplicar una operación **reduce $T \rightarrow \beta$** se tiene en la pila $S' = \alpha X |$. La secuencia de terminales no se modifica. Es decir, se extraen de la pila $| \beta |$ símbolos y se introduce el símbolo $X$ correspondiente. + +Podemos definir entonces el proceso de parsing como: + +> Sea $S = \emptyset$ la pila inicial, $T = \omega \$$ la cadena a reconocer, y $E$ el símbolo inicial, un parser shift-reduce reconoce esta cadena si y solo si existe una secuencia de operaciones **shift** y **reduce** tal que tras aplicarlas se obtiene $S = E$ y $T = \$$. + +Es decir, un parser shitf-reduce básicamente tiene que aplicar operaciones *convenientemente* hasta que en la pila solamente quede el símbolo inicial, y se hayan consumido todos los tokens de la cadena de entrada. En este punto, se ha logrado construir una derivación extrema derecha de la cadena correspondiente. Por supuesto, existe un grado importante de no determinismo en esta definición, porque en principio puede haber muchas secuencias de operaciones shift-reduce que permitan llegar al símbolo inicial. Si asumimos que la gramática no es ambigua, y por tanto solo existe una derivación extrema derecha, podemos intuir que debe ser posible construir un parser que encuentre la secuencia de shift-reduce que produce esa derivación. Desgraciadamente esto no es posible para todo tipo de gramáticas libre del contexto, pero existen gramáticas más restringidas para las que sí es posible decidir de forma determinista en todo momento si la operación correcta es **shift** o **reduce**, y en el segundo caso a qué símbolo reducir. + +Para simplificar la notación, en ocasiones identificaremos el estado de un parser shift-reduce en la forma $\alpha | \omega$, sobreentendiendo que el estado de la pila es $S = \alpha |$ y la cadena de entrada es $\omega \$$. Diremos además que un estado $\alpha | \omega$ es válido, si y solo si la cadena pertenece al lenguaje, y este estado forma parte de los estados necesarios para completar el parsing de forma correcta. + +Este tipo de parsers son en la práctica los más usados, pues permiten reconocer una cadena (y construir la derivación) con un costo lineal en la longitud de la cadena (la misma eficiencia que los parsers LL), y permiten parsear gramáticas mucho más poderosas y expresivas que las gramáticas LL. De hecho, la mayoría de los compiladores modernos usan alguna variante de un parser shift-reduce. La diferencia entre todos ellos radica justamente en cómo se decide en cada paso qué operación aplicar. Formalicemos entonces el problema de decisión planteado. Tomemos de nuevo la gramática anterior, y recordemos que en el paso: + + int|* ( int + int ) + +Habíamos dicho que aunque era posible reducir `T -> int`, no era convieniente hacerlo, porque caeríamos en una forma oracional que no puede ser reducida a `E`. En particular, en este caso caeríamos en: + + T|* ( int + int ) + +Y sabemos intuitivamente que esta forma oracional no es reducible a `E`, porque no existe ninguna producción que comience por `T *`, o dicho de otra forma, `*` no pertenece al `Follow(T)`. Tratemos de formalizar entonces este concepto de "momento donde es conveniente reducir". Para ello introduciremos una definición que formaliza esta intuición. + +> Sea $S \rightarrow^* \alpha X \omega \rightarrow \alpha \beta \omega$ una derivación extrema derecha de la forma oracional $\alpha \beta \omega$, y $X \rightarrow \beta$ una producción, decimos que $\alpha \beta$ es un **handle** de $\alpha \beta \omega$. + +Intuitivamente, un **handle** nos representa un estado en la pila donde es conveniente reducir, porque sabemos que existen reducciones futuras que nos permiten llegar al símbolo inicial. En la definición anterior la pila sería justamente $\alpha \beta |$, y la cadena de terminales sería $\omega \$$. Sabemos que es posible seguir reduciendo, justamente porque hemos definido un **handle** a partir de conocer que existe una derivación extrema derecha donde aparece ese prefijo. De modo que justamente lo que queremos es identificar cuando tenemos un **handle** en la pila, y en ese momento sabemos que es conveniente reducir. + +El problema que nos queda es que hemos definido el concepto de **handle** pero no tenemos una forma evidente de reconocerlos. Resulta que, desgraciadamente no se conoce ningún algoritmo para identificar un **handle** unívocamente en cualquier gramática libre del contexto. Sin embargo, existen algunas heurísticas que nos permiten reconocer algunos **handle** en ciertas ocasiones, y afortunadamente existen gramáticas donde estas heurísticas son suficientes para reconocer todos los **handle** de forma determinista. En última instancia, la diferencia real entre todos los parsers shitf-reduce radica en la estrategia que usen para reconocer los **handle**. Comenzaremos por la más simple. + +## Reconociendo **Handles** + +La forma en la que hemos definido el concepto de **handle** nos permite demostrar una propiedad interesante: + +> En un parser shift-reduce, los **handles** aparecen solo en el tope de la pila, nunca en su interior. + +Podemos esbozar una idea de demostración a partir de una inducción fuerte en la cantidad de operaciones **reduce** realizadas. Al inicio, la pila está vacía, y por tanto la hipótesis es trivialmente cierta. Tomemos entonces un estado intermedio de la pila $\alpha \beta |$ que es un **handle**. Además, es el único **handle** por hipótesis de inducción fuerte, ya que de lo contrario tendríamos un **handle** en el interior de la pila. Al reducir, el no-terminal más a la derecha queda en el tope de la pila, ya que es una derivación extrema derecha. Por tanto tendremos un nuevo estado en la pila $\alpha X |$. Ahora pueden suceder 2 cosas, o bien este estado es un **handle** también (y se cumple la hipótesis), o en caso contrario el siguiente **handle** aparecerá tras alguna secuencia solamente de operaciones **shift**. Este nuevo **handle** tiene que aparecer también en el tope de la pila, pues si apareciera en el interior de la pila, tendría que haber estado antes de $X$ (lo que es falso por hipótesis de inducción), o tendría que haber aparecido antes del último terminal al que se le hizo **shift**, pero en tal caso deberíamos haber hecho **reduce** en ese **handle**, lo que contradice el hecho de que solo han sucedido operaciones **shift** desde el último **reduce**. + +Este teorema nos permite, en primer lugar, formalizar la intuición de que solamente hacen falta movimientos **shift** a la izquierda. Es decir, una vez un terminal ha entrado en la pila, o bien será reducido en algún momento, o bien la cadena es inválida, pero nunca hará falta sacarlo de la pila y volverlo a colocar en la cadena de entrada. + +Por otro lado, este teorema nos describe la estructura de la pila, lo que será fundamental para desarrollar un algoritmo de reconocimiento de **handles**. Dado que los **handles** siempre aparecen en el tope de la pila, en todo momento tendremos, en principio, un prefijo de un **handle**. De modo que una idea útil para reconocer **handles** es intentar reconocer cuales son los prefijos de un **handle**. En general, llamaremos *prefijo viable* a toda forma oracional $\alpha$ que puede aparecer en la pila durante un reconocimiento válido de una cadena del lenguaje. Formalmente: + +> Sea $\alpha | \omega$ un estado válido de un parser shift-reduce durante el reconocimiento de una cadena, entonces decimos que $\alpha$ es un prefijo viable. + +Intuitivamente, un prefijo viable es un estado en el cual todavía no se ha identificado un error de parsing, por lo que, hasta donde se sabe, la cadena todavía pudiera ser reducida al símbolo inicial. Si podemos reconocer el lenguaje de todos los prefijos viables, en principio siempre sabremos si la pila actual representa un estado válido. Además podemos intuir que esto nos debería ayudar a decidir si hacer un **shift** o un **reduce**, según cual de las dos operaciones nos mantenga el contenido de la pila siendo un prefijo viable. De modo que hemos reducido el problema de identificar **handles** (de forma aproximada) al problema de identificar prefijos viables. + +Si analizamos todos los posibles estados válidos de la pila (los posibles prefijos viables), notaremos una propiedad interesante que nos ayudará a reconocer estos prefijos. Supongamos que tenemos un estado $\alpha \beta | \omega$ que es un **handle** para $X \rightarrow \beta$. Entonces por definición $\alpha \beta$ es también un prefijo viable. Además, una vez aplicada la reducción, tendremos el estado $\alpha X | \omega$. Por tanto $\alpha X$ también es un prefijo viable, porque de lo contrario esta reducción sería inválida, contradiciendo el hecho de que hemos reducido correctamente en un **handle**. Por tanto o bien $\alpha X$ es un **handle** en sí, o es un prefijo de un **handle**. En el segundo caso, entonces hay una producción $Y \rightarrow \theta X \phi$, tal que $\alpha = \delta \theta$. Es decir, hay un sufjo de $\alpha X$ que tiene que ser prefijo de la parte derecha de esa producción. + +¿Por qué?, pues porque como hemos reducido en un **handle**, esto quiere decir que sabemos que es posible en principio seguir reduciendo, por tanto tiene que haber alguna secuencia de tokens $\phi$, que pudiera o no venir en $\omega$ (aún no sabemos), que complete la parte derecha $\theta X \phi$. Es decir, como sabemos que potencialmente podríamos seguir reduciendo, entonces lo que tenemos en la pila ahora tiene que ser prefijo de la parte derecha de alguna producción. Si no lo fuera, ya en este punto podríamos decir que será imposible seguir reduciendo en el futuro, puesto que solamente introduciremos nuevos tokens en la pila, y nunca tocaremos el interior de la pila (excepto a través de reducciones, que siempre modifican el tope de la pila). + +Esta intuición nos dice algo muy importante sobre el contenido de la pila: + +> En todo estado válido $\alpha | \omega$ de un parser shift-reduce, la forma oracional $\alpha$ es una secuencia $\alpha = \beta_1 \beta_2 \ldots \beta_n$ donde para cada $\beta_i$ se cumple que existe una producción $X \rightarrow \beta_i \theta$. + +Es decir, todo estado válido de la pila es una concatenación de prefijos de partes derechas de alguna producción. En caso contrario, tendríamos una subcadena en la pila que no forma parte de ninguna producción, por tanto no importa lo que pase en el futuro, esta subcadena nunca sería parte de un **reduce**, y por tanto la cadena a reconocer tiene que ser inválida. Más aún, podemos decir exactamente de cuales producciones tienen que ser prefijo esas subcadenas. Dado que en última instancia tenemos que reducir al símbolo inicial $S$, entonces en la pila tenemos necesariamente que encontrar prefijos de todas las producciones que participan en la derivación extrema derecha que estamos construyendo. Formalmente: + +> Sea $S \rightarrow^* \alpha \delta \rightarrow^* \omega$ la única derivación extrema derecha de $\omega$, sea $\alpha | \delta$ un estado de un parser shift-reduce que construye esta derivación, sea $X_1 \rightarrow \theta_1, \ldots, X_n \rightarrow \theta_n$ la secuencia de producciones a aplicar tal que $S \rightarrow^* \alpha \delta$, entonces $\alpha = \beta_1 \ldots \beta_n$, donde $\beta_i$ es prefijo de $\theta_i$. + +Es decir, en todo momento en la pila lo que tenemos es una concatenación de prefijos de todas las producciones que quedan por reducir. Notemos intuitivamente que esto debe ser cierto, porque el parser va a construir esta derivación al revés. Por tanto en el estado $\alpha | \delta$, que corresponde a la forma oracional $\alpha \delta$ en la derivación, el parser ya ha reconstruido todas las producciones finales, que hacen que $\alpha \delta \rightarrow^* \omega$ (de atrás hacia adelante), y le falta por reconstruir las producciones que hacen que $S \rightarrow^* \alpha \delta$. Luego, lo que está en la pila tiene que reducirse a $S$, y como solo puede pasar que se metan nuevos terminales de $\delta$, todo lo que está en $\alpha$ tiene que de algún modo poderse encontrar en alguna de las producciones que faltan por reducir. De lo contrario, esta reducción sería imposible. + +Por supuesto, muchos de los prefijos $\beta_i$ pueden ser $\epsilon$, porque todavía no han aparecido ninguno de los símbolos que forman la producción en la pila (dependen de que reducciones siguientes introduzcan un no-terminal, o de que **shifts** siguientes introduzcan un terminal). De esta forma podemos entender que incluso la pila vacía es una concatenación de prefijos de producciones, todos $\epsilon$. Lo que no puede pasar es que tengamos una subcadena $\beta_k$ que no forme parte de ningún prefijo de ninguna producción, porque entonces nunca podremos reducir totalmente al símbolo inicial. De modo que un prefijo viable no es nada más que una concatenación de prefijos de las producciones que participan en la derivación extrema derecha que queremos construir. + +Para ver un ejemplo tomemos nuevamente nuestra gramática favorita: + + E -> T + E | T + T -> int * T | int | (E) + +Y veamos la cadena `( int )`. La derivación extrema derecha que nos genera esta cadena es: + + E -> T -> ( E ) -> ( T ) -> ( int ) + +Para esta cadena `( E | )` es un estado válido, pues en el siguiente **shift** aparecerá el token `)` que permite reducir (en dos pasos `T -> ( E )` y `E -> T`) al símbolo inicial. Por tanto, `( E` es un prefijo viable. Veamos cómo este prefijo es una concatenación de prefijos de las dos producciones que faltan por reducir. Evidentemente `( E` es prefijo de `T -> ( E )`, y además, $\epsilon$ es prefijo de `E -> T`. + +Esta idea es la pieza fundamental que nos permitirá deducir un algoritmo para reconocer prefijos viables. Como un prefijo viable no es más que una concatenación de prefijos de partes derechas de producciones, simplemente tenemos que reconocer *el lenguaje de todas las posibles concatenaciones de prefijos de partes derechas de producciones, que pudieran potencialmente aparecer en una derivación extrema derecha*. Parece una definición complicada, pero dado que conocemos la gramática que queremos reconocer, es de hecho bastante fácil. Notemos que hemos dicho, *que pudieran aparecer en una derivación*, lo cual nos debe dar una idea de cómo construir estas cadenas. Simplemente empezaremos en el símbolo inicial $S$, y veremos todas las posibles maneras de derivar, e iremos rastreando los prefijos que se forman. Para esto nos auxiliaremos de un resultado teórico impresionante, que fundamenta toda esta teoría de parsing bottom-up: + +> El lenguaje de todos los prefijos viables de una gramática libre del contexto es regular. + +Aunque parece un resultado caído del cielo, de momento podemos comentar lo siguiente. En principio, el lenguaje de todos los posibles prefijos de cada producción es regular (es finito). Y la concatenación de lenguajes regulares es regular. Por tanto, de alguna forma podríamos intuir que este lenguaje de todas las posibles concatenaciones de prefijos debería ser regular. Por tanto debería ser posible construir un autómata finito determinista que lo reconozca. Claro, queda la parte de que no son *todas* las concatenaciones posibles, sino solo aquellas que aparecen en alguna derivación extrema derecha. Tratemos entonces de construir dicho autómata, y a la vez estaremos con esto demostrando que efectivamente este lenguaje es regular. Recordemos que en última instancia lo que queremos es un autómata que lea el contenido de la pila, y nos diga si es un prefijo viable o no. + +Para entender como luce este autómata, introduciremos primero un concepto nuevo. Llamaremos **item** a una cadena de la forma $X \rightarrow \alpha . \beta$. Es decir, simplemente tomamos una producción y le ponemos un punto (`.`) en cualquier lugar en su parte derecha. Este **item** formaliza la idea de ver los posibles prefijos de todas las producciones. Por cada producción $X \rightarrow \delta$, tenemos $|\delta|+1$ posibles **items**. Por ejemplo, en la gramática anterior, tenemos los siguientes **items**: + + E -> .T + E + E -> T.+ E + E -> T +.E + E -> T + E. + + E -> .T + E -> T. + + T -> .int * T + T -> int.* T + T -> int *.T + T -> int * T. + + T -> .int + T -> int. + + T -> .( E ) + T -> (.E ) + T -> ( E.) + T -> ( E ). + +Cada uno de estos **items** nos representa un posible prefijo de una producción. Pero además, cada **item** nos permite también rastrear que esperamos ver a continuación de dicha producción, si es que realmente esa producción fuera la que tocara aplicar a continuación. Veamos entonces qué podemos decir de cómo estos **items** se relacionan entre sí. Tomemos por ejemplo el **item** `E -> T.+ E`. Este **item** nos dice que ya hemos visto algo en la cadena que se reconoce como un `T`, y que esperamos ver a continuación un `+`, si resulta que esta es la producción que realmente tocaba aplicar. El **item** `E -> .T + E` nos dice que si realmente esta es la producción correcta, entonces lo que viene en la cadena debería ser reconocible como un `T`, y luego debería vernir un `+`, y luego algo que se reconozca como un `E`. Por último, un **item** como `T -> ( E ).` nos dice que ya hemos visto toda la parte derecha de esta producción, y por tanto intuitivamente deberíamos poder reducir. De modo que estos **items** nos están diciendo además si es conviente hacer **shift** o hacer **reduce**. + +Vamos a utilizar ahora estos **items** para construir el autómata finito no determinista que nos dirá que es lo que puede venir el pila. Cada estado de este autómata es uno de los **items**. Vamos a decir que el estado asociado asociado al **item** $X \rightarrow \alpha . \beta$ representa que en el tope de la pila tenemos el prefijo $\alpha$ de esta producción, o en general, algo que es generado por este prefijo $\alpha$. Por tanto, todos los estados son estados finales, puesto que cada estado corresponde a un prefijo de alguna producción. Lo que tenemos que hacer es definir entonces un conjunto de transiciones que solamente reconozcan aquellas secuencias de prefijos que consituyen prefijos viables. + +Suponamos ahora que tenemos cierto estado de un parser shift-reduce, y queremos saber si es un estado válido. Hagamos a nuestro autómata leer esta la pila desde el fondo hacia el tope, como si fuera una cadena de símbolos. Supongamos entonces que durante esta lectura nos encontramos en cierto estado del autómata, asociado por ejemplo al **item** `E -> .T`, y hemos leído ya una parte del fondo de la pila, siguiendo las transiciones que aún no hemos definido del todo. La pregunta entonces es qué puede venir a continuación en la pila, justo encima del último símbolo que analizamos. Evidentemente, en la pila podría venir un no-terminal `T` directamente, que haya aparecido por alguna reducción hecha anteriormente. Si este fuera el caso, entonces todavía tendríamos un prefijo viable. Entonces podemos añadir una transición del estado `E -> .T` al estado `E -> T.`. + +Por otro lado, incluso si no viniera directamente un `T`, de todas formas todavía es posible que tengamos un prefijo viable. ¿Cómo? Supongamos que el no-terminal `T` todavía no ha aparecido porque esa reducción aún no ha ocurrido. Entonces lo que debería venir a continuación en la pila es algo que sea prefijo de alguna producción de `T`, de modo que un **reduce** futuro nos ponga ese `T` en la pila. En ese caso, todavía estaríamos en un prefijo viable, porque tendríamos un prefijo de `E -> T`, y luego un prefijo de algo que se genera con `T`. ¿Cómo reconocer entonces cualquier prefijo de cualquier producción que sale de `T`? Pues afortunadamente tenemos estados que hacen justamente eso, dígase `T -> .int` y `T -> .int * T`, es decir, los **items** iniciales de las producciones de `T`. Dado que estamos construyendo un autómata no-determinista, tenemos la libertad de añadir transiciones $\epsilon$ a estos dos estados. De modo que el estado `E -> .T` tiene tres transiciones, con un `T` se mueve a `E -> T.`, y con $\epsilon$ se mueve a `T -> .int` y a `T -> .int * T`. + +Por otro lado, si estuviéramos en el estado `E -> T.+ E`, lo único que podemos esperar que venga en la pila es un terminal `+`. En cualquier otro ya no tendríamos un prefijo viable, pues estábamos esperando tener un prefijo de `E -> T + E`, y ya hemos visto en la pila un `T`. Por tanto si fuera cierto que esta pila es un prefijo viable, tendría que venir algo que continuara este prefijo o empezara un nuevo prefijo. Pero dado que en la producción que estamos esperando lo que viene es un terminal, no existe forma de un **reduce** futuro nos ponga en esa posición a dicho terminal (los **reduce** siempre introducen un no-terminal en la pila). Luego, si no viene exactamente un `+` en la pila, ya podemos estar seguros que este prefijo no es viable (claro, como estamos en un autómata no-determinista puede que existan otros caminos donde sí se reconoce un prefijo viable). + +De forma general tenemos las siguientes reglas: + +* Si tenemos un estado $X \rightarrow \alpha . c \beta$ donde $c$ es un terminal, añadimos una transición con $c$ al estado $X \rightarrow \alpha c . \beta$. +* Si tenemos un estado $X \rightarrow \alpha . Y \beta$ donde $Y$ es un no-terminal, añadimos una transición con $Y$ al estado $X \rightarrow \alpha Y . \beta$, y además por cada producción $Y \rightarrow \delta$ añadimos una transición con $\epsilon$ al estado $Y \rightarrow .\delta$. + +Apliquemos entonces estas reglas al conjunto completo de **items** que hemos obtenido anteriormente. Primero definiremos un estado por cada **item**, y luego iremos adicionando las transiciones: + + [ 1] E -> .T + E { } + [ 2] E -> T.+ E { } + [ 3] E -> T +.E { } + [ 4] E -> T + E. { } + [ 5] E -> .T { } + [ 6] E -> T. { } + [ 7] T -> .int * T { } + [ 8] T -> int.* T { } + [ 9] T -> int *.T { } + [10] T -> int * T. { } + [11] T -> .int { } + [12] T -> int. { } + [13] T -> .( E ) { } + [14] T -> (.E ) { } + [15] T -> ( E.) { } + [16] T -> ( E ). { } + +Tomemos entonces el estado `E -> .T + E`. Primero ponemos la transición con `T` hacia `E -> T.+ E`: + + [ 1] E -> .T + E { T:2 } + +Y luego, dado que `T` es un no-terminal, adicionamos las transiciones $\epsilon$ correspondientes a los estados `T -> .int` y `T -> .int * T`: + + [ 1] E -> .T + E { T:2, e:7, e:11 } + +Por otro lado, para `E -> T.+ E` la única transición válida es con `+`, hacia el estado `E -> T +.E`: + + [ 2] E -> T.+ E { +:3 } + +Para el estado `E -> T+.E` igualmente tenemos una transición con `E` y dos transiciones con $\epsilon$: + + [ 3] E -> T +.E { E:4, e:1, e:5 } + +El estado `E -> T + E.` no tiene transiciones salientes, pues representa que se ha reconocido toda la producción. Es responsabilidad de otros estados continuar reconociendo (de forma no-determinista) los prefijos que puedan quedar en la pila. + +El estado `E -> .T` se parece mucho al estado `E -> .T + E`. De hecho, tiene las mismas transiciones: + + [ 5] E -> .T { T:2, e:7, e:11 } + +Finalmente el estado `E -> T.` tampoco transiciones salientes. Ya hemos dicho que todos los estados son finales, pues como las transiciones siempre nos mueven de un prefijo viable a otro, en cualquier momento en que se acabe la pila tenemos un prefijo viable reconocido. Solo queda definir el estado inicial. En principio, deberíamos empezar de forma no-determinista por cualquiera de los estados iniciales de las producciones de `E`. Afortunadamente, en un autómata no-determinista tenemos un recurso para simular esta situación en la que queremos 2 estados iniciales. Simplemente añadimos un estado "dummy", con transiciones $\epsilon$ a cada uno de los estados iniciales que deseamos. Desde el punto de la gramática, esto es equivalente a añadir un símbolo nuevo `E'` con la única producción `E' -> E` y convertirlo en el símbolo inicial. Para esta producción tenemos dos nuevos **items**: `E' -> .E` y `E' -> E.`. El estado `E' -> .E` se convertirá en el estado inicial de nuestro autómata. + +El estado `E' -> E.` también es convieniente, pues nos permite reconocer que hemos logrado reducir al símbolo inicial, y deberíamos haber terminado de consumir toda la cadena. De modo que este estado "especial" nos permitirá además saber cuando aceptar la cadena. No podemos simplemente aceptar la cadena en cualquier estado donde se reduzca a `E`, porque es posible que estuviéramos reduciendo a un `E` intermedio, por ejemplo, al `E` que luego de ser reducido en `T -> (E)`. + +Ahora que hemos visto como se construyen estas transiciones, veamos directamente el autómata completo. + + [ 0] E' -> .E { E: 17, e:1, e:5 } + [ 1] E -> .T + E { T:2, e:7, e:11 } + [ 2] E -> T.+ E { +:3 } + [ 3] E -> T +.E { E:4, e:1, e:5 } + [ 4] E -> T + E. { } + [ 5] E -> .T { T:2, e:7, e:11 } + [ 6] E -> T. { } + [ 7] T -> .int * T { int:8 } + [ 8] T -> int.* T { *:9 } + [ 9] T -> int *.T { T:10, e:7, e:11 } + [10] T -> int * T. { } + [11] T -> .int { int:12 } + [12] T -> int. { } + [13] T -> .( E ) { (:14 } + [14] T -> (.E ) { E:15, e:1, e:5 } + [15] T -> ( E.) { ):16 } + [16] T -> ( E ). { } + [17] E' -> E. + +A estos **items** se les denomina también **items LR(0)**, que significa *left-to-right rightmost-derivation look-ahead 0*. + +## Autómata LR(0) + +Hemos construido finalmente un autómata finito no-determinista que reconoce exactamente el lenguaje de los prefijos viables. Sabemos que existe un autómata finito determinista que reconoce exactamente el mismo lenguaje. Aplicando el algoritmo de conversión de NFA a DFA podemos obtener dicho autómata. Sin embargo, hay una forma más directa de obtener el autómata finito determinista, que consiste en construir los estados aplicando el algoritmo de conversión a medida que vamos analizando las producciones y obteniendo los **items**. + +Recordemos que el algoritmo de conversión de NFA a DFA básicamente construye un estado por cada subconjunto de los estados del NFA, siguiendo primero todas las transiciones con el mismo terminal, y luego computando la $\epsilon$-clausura del conjunto de estados resultante. Para cada uno de estos "super-estados" $Q_i$, la nueva transición con un terminal concreto $c$ va hacia el super-estado que representa exactamente al conjunto clausura de todos los estados originales a los que se llegaba desde algún estado $q_j \in Q_i$. + +Vamos ahora a reescribir este algoritmo, pero teniendo en cuenta directamente que los estados del NFA son **items**. Por tanto, los super-estados del DFA serán conjuntos de **items**, que son justamente la $\epsilon$-clausura de los **items** a los que se puede llegar desde otro conjunto de **items** siguiendo un símbolo concreto $X$ (terminal o no-terminal). Definiremos entonces dos tipos de **items** para simplicar: + +* Un **item kernel** es aquel de la forma $E' \rightarrow .E$ si $E'$ es nuevo símbolo inicial, o cualquier item de la forma $X \rightarrow \alpha . \beta$ con $|\alpha|>1$. + +* Un **item no kernel** es aquel de la forma $X \rightarrow .\beta$ excepto el **item** $E' \rightarrow .E$. + +Hemos hecho estas definiciones, porque de cierta forma los **items kernel** son los realmente importantes. De hecho, podemos definir dado un conjunto de **items kernel**, el conjunto clausura, que simplemente añade todos los **items no kernel** que se derivan de este conjunto. + +> Sea $I$ un conjunto de **items** (kernel o no), el conjunto clausura de $I$ se define como $CL(I) = I \cup \{ X \rightarrow .\beta \}$ tales que $Y \rightarrow \alpha .X \delta \in CL(I)$. + +Es decir, el conjunto clausura no es más que la formalización de la operación mediante la cuál añadimos todos los **items** no-kernel que puedan obtenerse de cualquier **item** en $I$. Nótese que la definición es recursiva, es decir, el conjunto clausura de $I$ se define a partir del propio conjunto clausura de $I$. Para computarlo, simplemente partimos de $CL(I) = I$ y añadimos todos los items no-kernel que podamos, mientras cambie el conjunto. Por ejemplo, computemos el conjunto clausura del item asociado estado inicial $E' \rightarrow .E$. Partimos del conjunto singleton que solo contiene a este item: + + I = { E' -> .E } + +Ahora buscamos todas las producciones de `E` y añadimos sus items iniciales: + + I = { E' -> .E, + E -> .T, + E -> .T + E } + +Ahora buscamos todas las producciones de `T` y añadimos sus items iniciales: + + I = { E' -> .E, + E -> .T, + E -> .T + E, + T -> .int, + T -> .int * T, + T -> .( E ) } + +Como no hemos añadido ningún item que tenga un punto delante de un no-terminal nuevo, este es el conjunto final. Notemos que esta definición no es nada más que la definición de $\epsilon$-clausura usada en la conversión de un NFA a un DFA, solo que la hemos definido en función de los **items** directamente. Si aplicamos la $\epsilon$-clausura al estado $q_0$ de nuestro NFA definido anteriormente, llegaremos exactamente al mismo conjunto de **items**. + +Una vez que tenemos este conjunto clausura de **items**, podemos definir entonces cómo añadir transiciones. Para ello definiremos la función $Goto(I,X) = J$, que nos mapea un conjunto de items a otro conjunto de items a partir de un símbolo $X$, de la siguiente forma: + +> $Goto(I,X) = CL(\{ Y \rightarrow \alpha X. \beta | Y \rightarrow \alpha .X \beta \in I \})$ + +La función $Goto(I,X)$ simplemente busca todos los items en $I$ donde aparece un punto delante del símbolo $X$, crea un nuevo conjunto donde el punto aparece detrás del símbolo $X$, y luego calcula la clausura de este conjunto. Básicamente lo que estamos es formalizando la misma operación $Goto$ que usábamos en la conversión de NFA a DFA, pero esta vez escrita en función de los **items**. Por ejemplo, si $I$ es el conjunto calculado anteriormente, entonces: + + Goto(I,T) = { E -> T., E -> T. + E } + +Dado que no existe ningún punto delante de un no-terminal, no es necesario computar la clausura. + +Una vez que tenemos estas dos definiciones, podemos dar un algoritmo para construir el autómata finito determinista que reconoce los prefijos viables. El estado inicial de nuestro autómata será justamente $CL({ E' \rightarrow .E })$. Luego, repetimos la siguiente operación mientras sea necesario: por cada estado $I$ y cada símbolo $X$, añadimos el estado $Goto(I,X)$ si no existe, y añadimos la transición $I \rightarrow^X J$. El algoritmo termina cuando no hay cambios en el autómata. + +Apliquemos entonces este algoritmo a nuestra gramática para expresiones. Partimos del estado $I_0$ ya computado: + + I0 = { E' -> .E, + E -> .T, + E -> .T + E, + T -> .int, + T -> .int * T, + T -> .( E ) } + +Calculemos ahora $Goto(I_0, E)$: + + I1 = { E' -> E. } + +Como no hay ningún punto delante de un no-terminal, la clausura se mantiene igual. Calculemos entonces $Goto(I_0, T)$: + + I2 = { E -> T., + E -> T.+ E } + +Igualmente la clausura no añade items. Calculemos ahora $Goto(I_0, int)$: + + I3 = { T -> int., + T -> int.* T } + +Y ahora $Goto(I_0, ( )$: + + I4 = { T -> (.E ) } + +A este estado si tenemos que calcularle su clausura: + + I4 = { T -> (.E ), + E -> .T, + E -> .T + E, + T -> .int, + T -> .int * T, + T -> .( E ) } + +De modo que ya terminamos con $I_0$. Dado que en $I_1$ no hay símbolos tras un punto, calculemos entonces $Goto(I_2,+)$, y aplicamos la clausura directamente: + + I5 = { E -> T +.E, + E -> .T, + E -> .T + E, + T -> .int, + T -> .int * T, + T -> .( E ) } + +Calculamos $Goto(I_3, *)$: + + I6 = { T -> int *.T, + T -> .int, + T -> .int * T, + T -> .( E ) } + +Calculamos $Goto(I_4, E)$: + + I7 = { T -> ( E.) } + +Si ahora calculamos $Goto(I_4, T)$, y nos daremos cuenta que es justamente $I_2$. Por otro lado, afortunadamente $Goto(I_4, int) = I_3$. Y finalmente $Goto(I_4, ()$ es el propio estado $I_4$! Por otro lado, $Goto(I_5, E)$ es: + + I8 = { E -> T + E. } + +Mientras que $Goto(I_5,T)$ nos lleva de regreso a $I_3$, y $Goto(I_5, ()$ a $I_4$. Saltamos entonces para $Goto(I_6, T)$ que introduce un estado nuevo: + + I9 = { T -> int * T. } + +Por otro lado, $Goto(I_6, int) = I_3$ nuevamente, mientras que $Goto(I_6, ()$ nos regresa nuevamente a $I_4$. Finalmente, $Goto(I_7, ))$ nos da el siguiente, y último estado del autómata (ya que $I_8$ e $I_9$ no tienen transiciones salientes): + + I10 = { T -> ( E ). } + +Para agilizar este algoritmo, podemos notar que, como dijimos anteriormente, solamente los item kernel son importantes. De hecho, podemos probar fácilmente que dos estados son iguales sí y solo si sus item kernel son iguales, dado que las operaciones de clausura sobre conjuntos de items kernel iguales nos darán el mismo conjunto final. Por lo tanto, en una implementación computacional (o un cómputo manual), si distinguimos los items kernel del resto de los items, cuando computamos un nuevo estado a partir de la función $Goto$, antes de computar su clausura vemos si su conjunto de items kernel coincide con el kernel de otro estado ya creado. En caso contrario, hemos descubierto un nuevo estado y pasamos a computar su clausura. + +## Parsing LR(0) + +Una vez construido el autómata, podemos finalmente diseñar un algoritmo de parsing bottom-up. Este algoritmo se basa en la idea de verificar en cada momento si el estado de la pila es un prefijo viable, y luego, según el terminal que corresponda en $\omega$, decidimos si la operación a realizar es **shift** o **reduce**. Para determinar si la pila es un prefijo viable, simplemente corremos el autómata construido en el contenido de la pila. Supongamos que este autómata se detiene en el estado $I$. Vamos que nos dicen los items de este estado sobre la operación más conveniente a realizar. + +Si en este estado tenemos un item $X \leftarrow \alpha .c \beta$, y $c \omega$ es la cadena de entrada (es decir, $c$ es el próximo terminal a analizar), entonces es evidente que una operación de **shift** me seguirá manteniendo en la pila un prefijo viable. ¿Por qué? Pues porque al hacer **shift** el contenido de la pila ahora crece en $c$, y si vuelvo a correr el autómata desde el inicio de la pila, llegaré nuevamente al estado $I$ justo antes de analizar $c$. Pero sé que desde $I$ hay una transición con $c$ a cierto estado $J$, que es justamente $Goto(I, c)$, por lo tanto terminaré en el estado $J$ habiendo leído toda la pila. Luego, por definición de prefijo viable, como he podido reconocer el contenido de la pila, todo está bien. + +Por otro lado, si en el estado $I$ tengo un item de la forma $X \leftarrow \beta.$, entonces es conveniente hacer una operación de **reduce** justamente en la producción $X \rightarrow \beta$. Para ver por qué esta operación me sigue manteniendo en la pila un prefijo viable, notemos que $X \rightarrow \beta.$ quiere decir que hemos reconocido en la pila toda la parte derecha de esta producción. Entonces en la pila lo que tenemos en un **handle**, y por su propia definición reducir en un **handle** siempre es correcto. + +De modo que tenemos un algoritmo. En cada iteración, corremos el autómata en el contenido de la pila, y analizamos cuál de las estrategias anteriores es válida según el contenido del estado en que termina el autómata. Si en algún momento el autómata no tiene una transición válida, tiene que ser con el último terminal que acabamos de hacer **shift** (ya que de lo contrario se hubiera detectado en una iteración anterior). Luego, este algoritmo reconoce los errores sintácticos lo antes posible. Es decir, nunca realiza una reducción innecesaria. + +Por otro lado, puede suceder que en un estado del autómata tenga items que nos sugieran operaciones contradictorias. Llamaremos a estas situaciones, **conflictos**. En general, podemos tener 2 tipos de conflictos: + +* Conflicto **shift-reduce** si ocurre que tengo un item que me sugiere hacer **shift** y otro que me sugiere hacer **reduce**. +* Conflicto **reduce-reduce** si ocurre que tengo dos items que me sugieren hacer **reduce** a producciones distintas. + +En cualquiera de estos casos, tenemos una fuente de no-determinismo, pues no sabemos por cuál de estas operaciones se pudiera reconocer la cadena. Este no-determinismo se debe a que en el autómata no-determinista había más de un camino posible que reconocía la cadena, y al convertirlo a determinista, estos caminos se expresan como items contradictorios en el mismo estado. En estos casos, decimos que la gramática no es LR(0). Luego: + +> Sea $G=$ una gramática libre del contexto, $G$ es LR(0) si y solo si en el autómata LR(0) asociado no existen conflictos **shift-reduce** ni conflictos **reduce-reduce**. + +Notemos que no es posible que tengamos conflictos **shift-shift**, pues solamente hay un caracter $c$ en la cadena $\omega$, y por tanto hay un solo estado hacia donde hacer **shift**. + +Desgraciadamente nuestra gramática favorita de expresiones no es LR(0). Sin ir más lejos, en el estado $I_3$ tenemos un conflicto **shift-reduce**. Podemos reducir `T -> int`, o hacer **shift** si viene un terminal `*`. Intuitivamente el problema es que la operación de **reduce** es demasiado permisiva. Donde quiera que encontremos un item **reduce** diremos que es conveniente reducir en esa producción, aunque sabemos que esto no siempre es cierto. De hecho, ya hemos tenido que lidiar con este problema anteriormente, en el algoritmo de parsing LL. + +## Parsing SLR(1) + +Recordemos que en el parsing LL teníamos la duda de cuando era conveniente aplicar una producción $X \rightarrow \epsilon$, y definimos para ello el conjunto $Follow(X)$, que justamente nos decía donde era conveniente eliminar $X$. Pues en este caso, este conjunto también nos ayudará. Intuitivamente, si tenemos $X \rightarrow \beta.$, solamente tiene sentido reducir si en el $Follow(X)$ aparece el terminal que estamos analizando. ¿Por qué? Pues porque de lo contrario no es posible que lo que nos quede en la pila sea un prefijo viable. + +Supongamos que $c$ es el terminal a analizar, $c \notin Follow(X)$ y hacemos la reducción. Entonces en el próximo **shift** tendremos en el tope de la pila la forma oracional $Xc$. Pero esta forma oracional no puede aparecer en niguna derivación extrema derecha, porque de lo contrario $c$ sería parte del $Follow(X)$. Por tanto, si esta forma oracional no es válida, entonces ningún **handle** puede tener este prefijo. Por tanto ya no tenemos un prefijo viable. Incluso si lo siguiente que hacemos tras reducir en $X$ no es **shift** sino otra secuencia de operaciones **reduce**, en cualquier caso si lo que queda una vez hagamos **shift** es un prefijo viable, entonces es porque $c \in Follow(X)$ (intuitivamente, aplicando las producciones en las que redujimos hasta que vuelva a aparecer X, obtendremos la forma oracional $Xc$ nuevamente). + +Justamente a esta estrategia denominaremos SLR(1), o *Simple LR look-ahead 1*, dado que usamos un terminal de look-ahead para decidir si vale la pena reducir. Con esta estrategia, podemos comprobar que ya en el estado $I_2$ no hay conflicto, pues $* \notin Follow(T)$, porque cuando viene un terminal $*$ solo tiene sentido hacer **shift**, nunca **reduce**. + +De forma análoga llamamos gramáticas SLR(1) a aquellas gramáticas donde, bajo estas reglas, no existen conflictos. + +Intentemos entonces reconocer la cadena `int * ( int + int )` con nuestro parser SLR(1). Comenzamos por el estado inicial: + + |int * ( int + int ) + +Como la pila está vacía, el autómata termina en el estado $I_0$. Dado que viene un terminal `int`, buscamos la transición correspondiente, que es justamente hacia el estado $Goto(I_0,int) = I_3$. Por tanto, como existe esta transición, significa que la acción a realizar es **shift**. + + int|* ( int + int ) + +Ahora corremos nuevamente el autómata, ya sabemos que caerá en el estado $I_3$. Ahora podemos potencialmente reducir o hacer **shift**. Calculamos el $Follow(T)$ + + Follow(T) = { +, ), $ } + +Por tanto, como `*` no está incluido en el `Follow(T)`, no hay conflicto, solamente no queda hacer **shift**, en este caso al estado $I_6$. + + int *|( int + int ) + +Corremos de nuevo y sabemos que acabaremos en $I_6$. Aquí no hay reducciones, así que solo queda hacer **shift** hacia el estado $I_4$: + + int * (|int + int ) + +En $I_4$ tampoco hay reducciones, así que hacemos **shift** hacia el estado $I_3$: + + int * ( int|+ int ) + +Ahora interesantemente si tenemos que `+` pertenece al `Follow(X)`, por tanto la reducción aplica. Afortunadamente no hay transiciones en este estado con `+`, por lo que no hay conflicto. Aplicamos entonces la reducción: + + int * ( T|+ int ) + +Ahora corremos el autómata nuevamente desde el inicio, siguiendo las transiciones (recordemos que mienstras estamos leyendo el contenido de la pila no nos importan los items). Terminamos en el estado $I_2$. En este estado podemos reducir a `E` o hacer **shift**. Pero resulta que `Follow(E)` no contiene al terminal `+`, por lo que la reducción no tiene sentido. Hacemos **shift** entonces: + + int * ( T +|int ) + +Ahora el autómata termina en el estado $I_5$. En este estado, viniendo `int`, solamente tiene sentido hacer **shift** hacia el estado $I_3$: + + int * ( T + int|) + +Ahora estamos en una situación conocida. Pero en este caso, `)` sí está en el `Follow(T)`, y no hay transiciones con este símbolo, luego lo que queda es reducir: + + int * ( T + T|) + +Al correr el autómata, en vez de $I_3$ como en la última vez, ahora de $I_5$ pasaríamos directamente a $I_2$, donde nuevamente estamos en territorio conocido. Sin embargo, de nuevo en este caso `)` sí está en el `Follow(E)`, luego podemos reducir (y no hay transiciones con `)`): + + int * ( T + E|) + +Ahora volvemos a correr el autómata, pero en vez de el estado $I_2$, terminaríamos en el estado $I_8$, donde la única opción es reducir (una vez comprobamos el `Follow(E)`): + + int * ( E|) + +En este caso, al correr el autómata desde el inicio, terminamos en $I_7$, que nos dice **shift**: + + int * ( E )| + +Ahora de $I_7$ saltaríamos para $I_{10}$, que nos indica la reducción (dado que `$` sí está en el `Follow(X)`): + + int * T| + +En este caso, rápidamente caeremos en el estado $I_9$, que nos indica reducir: + + T| + +El autómata con esta pila termina en el estado $I_2$ nuevamente, pero ahora `$` es el terminal a analizar, por lo que hacemos la reducción: + + E| + +Y finalmente, en esta entrada el autómata nos deja en el estado $I_1$, que nos permite reducir por completo al símbolo especial `E'` y aceptar la cadena: + + E'| + +De esta forma, el algoritmo de parsing SLR(1) ha logrado obtener una derivación extrema derecha de nuestra cadena favorita, pero empleando una gramática mucho más expresiva y "natural" que la gramática LL correspondiente. + +De todas formas, muchas gramáticas medianamente complicadas no son SLR(1), por lo que necesitaremos un parser de mayor potencia. Para ello, tendremos que refinar aún más el criterio con el cuál se producen los **reduce**. + +## Parsing LR(1) + +Veamos a continuación un ejemplo de una gramática clásica que no es SLR(1): + + S -> E + E -> A = A | i + A -> i + A | i + +Esta gramática representa un subconjunto del lenguaje de las ecuaciones algebraicas, donde tanto en la parte derecha como en la izquierda del token `=` podemos tener una expresión aritmética cualquiera. Veamos que sucede al construir el autómata SLR(1): + + I0 = { + S -> .E + E -> .A = A + E -> .i + A -> .i + A + A -> .i + } + +Viendo los items de este estado, ya podemos intuir dónde podría haber problemas. Al hacer `Goto(I0, i)` aparecerán dos items **reduce** con parte izquierda distinta: + + Goto(I0, i) = { + E -> i. + A -> i.+ A + A -> i. + } + +En este estado aperece entonces un conflicto **reduce-reduce**, ya que $Follow(E) = \{ \$ \}$, y $\$ \in Follow(A)$, puesto que `A` aparece como parte derecha de una producción de `E`. Por tanto esta gramática no es SLR(1). Sin embargo, la gramática no es ambigua, y esto es fácil de demostrar. Intuitivamente, la única cadena donde pudiera haber ambiguedad es justamente la cadena `i` (es el único token que es generado por más de un no-terminal). Sin embargo, para esta cadena, la única derivación posible es `S -> E -> i`. Aunque `A -> i` es una producción, la forma oracional `i` no es **handle** de `A`. Si solo existe un `i` en la pila, este tiene que ser generado por el no-terminal `E`, pues de lo contrario no sería posible reducir a `S`. + +Sin embargo, nuestro parser SLR(1) no es suficientemente inteligente para determinar esto. Al encontrarse con la forma oracional `i` en la pila, en principio, el autómata dice que `A -> i` es una reducción posible. Sin embargo, sabemos que esta reducción es inválida, porque luego quedaría `A` en la pila, que no es una forma oracional válida en ninguna derivación extrema derecha. De la producción `E -> A = A` podemos ver que esta gramática nunca genera una `A` sola. En otras palabras, nuestra heurística SLR(1) para detectar **handles** (reducir en `X` para todo terminal en el `Follow(X)`) es demasiado débil para manejar esta situación, y produce un falso positivo, al determinar que la forma oracional `ì$` es un **handle** de `A`, cuando realmente no lo es. + +La pregunta es entonces, ¿por qué surge este conflicto? Qué falla en la heurística SLR(1) que produce estos falsos positivos? Evidentemente el conjunto Follow es en ocasiones demasiado grande, y contiene tokens para los cuáles no es válida una operación **reduce** en ese estado particular. Tratemos de rastrear, durante la construcción del autómata, dónde es que se introducen estos tokens inválidos. + +Comenzamos por el estado inicial nuevamente, pero viéndolo paso a paso a medida que se computa la clausura. Comenzamos por el *kernel*: + + I0 = { + S -> .E + ... + } + +En este punto, el único item de este estado indica que esperamos encontrar en la cadena una forma oracional que se reduzca a `E`. Por tanto, añadimos las producciones de `E`: + + I0 = { + S -> .E + E -> .A = A + E -> .i + ... + } + +Hasta aquí no hay problemas, pues ni siquiera hay dos items con la misma parte derecha. Entonces tenemos que adicionar las producciones de `A`: + + I0 = { + S -> .E + E -> .A = A + E -> .i + A -> .i + A + A -> .i + } + +Y aquí es donde podemos tener la primera pista de que viene un conflicto. Tenemos dos items que tienen la misma parte derecha (`E -> .i` y `A -> .i`). Por tanto, tras el próximo **shift** llegaremos a un estado con dos **reduce** a no-terminales distintos. Ahora, recordemos que el conflicto va a suceder porque `$` está en la intersección de los Follow. Sin embargo, veamos por qué motivo aparece `A -> .i` en este estado. Justamente, es por culpa de la producción `E -> .A = A` que tenemos que expandir los items de `A`. Recordemos entonces qué significa este item para nosotros: básicamente representa que a partir de este punto en la cadena de entrada, estamos esperando que aparezca *algo que se pueda reducir* a la forma oracional `A = A`. Por tanto, como esta forma oracional empieza con `A`, debemos expandir sus producciones. + +Pero sí analizamos cuidadosamente el significado del item anterior, veremos que no tiene sentido reducir a este `A` si aparece `$` como *look-ahead*. ¿Por qué? Pues precisamente, el item nos dice que lo que viene en la cadena, si resultara que es correcta, debería reducirse a la forma oracional `A = A`. Por tanto, la primera parte de esa supuesta cadena, que se debería reducir al primer `A` de la forma oracional, solamente sería correcta si justo detrás de ese `A` viniera un token `=`. De lo contrario no podríamos seguir reduciendo el resto de la forma oracional. + +Es decir, en el momento qué por culpa del item `E -> .A = A` nos toca adicionar el item `A -> .i`, lo que estamos esperando es que ese `i` se reduzca a `A` e inmediatamente después venga un `=`. El propio item nos está diciendo eso. Por tanto, si en el siguiente estado resultara que felizmente apareció el token `i` en la pila, antes de reducirlo ingenuamente a `A`, deberíamos verificar si justo detrás viene el `=` que estábamos esperando. De lo contrario, podríamos decir que la reducción no tiene sentido, porque el item "padre" de este item (es decir, `E -> .A = A`) se va a quedar esperando un `=` que no viene en la cadena. + +El problema con la heurística SLR radica justamente en que calculamos el Follow de cualquier no-terminal de forma *global*. Es decir, no tenemos en cuenta qué según las producciones que se vayan aplicando, solamente una parte de ese Follow es la que realmente puede aparecer a continuación. En este caso particular $Follow(A) = \{ =, \$\}$. Pero cada uno de esos tokens está en el Follow por un motivo *distinto*. Justamente `=` aparece en el `Follow(A)` por culpa de la *primera* `A` en la producción `E -> A = A`. Pero `$` aparece por culpa de la *segunda* `A` de esa producción. De cierta forma, es como si tuviéramos *dos instancias* distintas del mismo no-terminal `A`, aquella que aparece delante del token `=` y aquella que aparece detrás. Entonces cuando estamos parseando una cadena, y el autómata pasa al estado `E -> .A = A`, estamos esperando una `A`, pero no cualquier `A`, sino aquella *instancia* de `A` que viene delante del `=`. El error en la heurística SLR es justamente que no puede identificar estas situaciones distintas. Para el autómata SLR toda `A` es la misma `A`, por tanto tiene sentido reducir siempre con el mismo *look-ahead*. + +¿Cómo podemos entonces identificar de forma distinta a cuál de las posibles `A` nos estamos refiriendo? Precisamente, durante la construcción del autómata, cuando el item `E -> .A = A` nos genera un item `A -> .i`, sabemos a "cuál" `A` nos referimos. Es justamente aquella que estaba detrás del punto. Por tanto, podemos en este momento decir qué es lo que puede venir detrás de esa `A` particular si se aplica esta producción particular. Lo que haremos entonces es adicionar a cada item un conjunto de tokens, que nos dirán explícitamente cuándo es que tiene sentido hacer **reduce**. Y este conjunto de tokens lo iremos calculando a medida que se crean los nuevos items, justamente mirando en el item "padre" que lo generó qué es lo que puede venir detrás de cada no-terminal. + +Vamos a introducir entonces el concepto de **item LR(1)**, que no es más que un **item LR(0)** normal junto a token: + +> Sea $G=$ una gramática libre del contexto, un **item LR(1)** es una expresión de la forma $X \rightarrow \alpha \cdot \beta, c$ donde $X \rightarrow \alpha \beta$ es una producción ($\alpha, \beta \in (N \cup T)^*$), y $c \in T$. + +El nuevo token que hemos adicionado a cada item nos servirá para ir rastreando qué terminales pueden aparecer el Follow de la forma oracional que estamos intentando reducir. De modo que un item de la forma $X \rightarrow \alpha \cdot \beta, c$ en un estado del autómata representa que ya hemos reconocido la parte $\alpha$ de la forma oracional, y esperamos reconocer la parte $\beta$, y que una vez reconocida toda esta porción $\beta$, esperamos que venga exactamente un terminal $c$. Por tanto, en algún momento tendremos un item $X \rightarrow \delta \cdot, c$, y entonces la operación de **reduce** la aplicaremos solamente si el siguiente terminal es $c$. A este token asociado a cada item le llamaremos *look-ahead*, y a la parte $X \rightarrow \alpha \cdot \beta$ le llamaremos centro. De modo que un item LR(1) está compuesto por un centro, que es un item LR(0), y un token *look-ahead*. + +A partir de este nuevo tipo de item, vamos a construir un autómata similar al SLR(1), que llamaremos **LR(1) canónico** o simplemente LR(1). Para ello, necesitaremos definir cuál es el item inicial, y cómo se computan nuevos items a partir de los items ya existentes. El item LR(1) inicial es fácil de definir. El centro es idéntico al item inicial del autómata SLR: es decir, $S \rightarrow \cdot E$ (siendo `S` el nuevo símbolo inicial de la gramática aumentada, y `E` el símbolo inicial de la gramática original). Ahora, para definir el token *look-ahead*, volvamos al significado de este item. Básicamente $S \rightarrow \cdot E$ significa que esperamos encontrar una forma oracional que se pueda reducir a `E`, y por tanto lo único que puede venir posteriormente es justamente `$`. De este modo el item LR(1) inicial significamente exactamente que queremos reducir **toda** la cadena a un simbolo `E`. + +> Sea $G=$ una gramática libre del contexto, $S'$ el símbolo inicial de la gramática autmentada, entonces el item LR(1) inicial es $S' \rightarrow \cdot S, \$$. + +Veamos entonces qué sucede con cualquier otro item LR(1). Recordemos que en SLR teníamos dos tipos de items, los *kernel* y los *no-kernel*. Aquí tendremos la misma separación. Si tenemos un item LR(1) $X \rightarrow \alpha \cdot x \beta, c$, donde $x \in T$, la operación **shift** nos generará el item $X \rightarrow es\alpha x \cdot \beta, c$. Dado que todavía estamos reconociendo la parte derecha de esta producción, el *look-ahead* se mantiene igual. Por otro lado, si tenemos $X \rightarrow \alpha \cdot Y \beta, c$ con $Y \in N$, entonces tenemos que computar (además de correr el punto) todos los items con centro $Y \rightarrow \cdot \delta$. La pregunta es entonces cuál es el *look-ahead* correspondiente. Básicamente la pregunta es, si logramos reducir a $\delta$ al $Y$ que estamos esperando, ¿qué puede venir detrás? La respuesta es, en principio, todo terminal en el $First(\beta)$, y *nada más*. + +Ahora, puede suceder que $\beta \rightarrow^* \epsilon$, es decir, que la parte detrás de $Y$ no exista, o que desaparezca en el futuro. En este caso, tendremos que $\epsilon \in First(\beta)$. Pero no tiene sentido alguno decir que detrás de $Y$ esperamos que venga $\epsilon$ (incluso definimos anteriormente que $\epsilon \notin Follow(Y)$ para todo $Y$). Sin embargo, en este caso, si $\beta$ desaparece, entonces lo único que puede venir detrás de $Y$, es justamente el *look-ahead* de $X$. Por ejemplo, para el item $X \rightarrow \alpha \cdot Y, c$ generamos el item $Y \rightarrow \cdot \delta, c$, pues como $Y$ está al final del $X$, le sigue lo mismo que habíamos decidido que seguía a $X$. Podemos generalizar de la siguiente manera, extendiendo los conceptos definidos para SLR: + +> Sea $I$ un conjunto de **items LR(1)** (kernel o no), el conjunto clausura de $I$ se define como $CL(I) = I \cup \{ X \rightarrow .\beta, b\}$ tales que $Y \rightarrow \alpha .X \delta, c \in CL(I)$ y $b \in First(\delta c)$. + +> Sea $I$ un conjunto de **items LR(1)**, se define la función $Goto(I,X) = CL(\{ Y \rightarrow \alpha X. \beta, c | Y \rightarrow \alpha .X \beta, c \in I \})$ + +Para construir el autómata, seguimos el mismo algoritmo que para SLR. La función **Goto** para un conjunto de items (un estado) se define de igual forma como el conjunto de items (estado) que se obtienen de aplicar **Goto** a cada item en el conjunto origen. La función **Clausura** igualmente se define de forma recursiva como la clausura transitiva de cada uno de los items del propio conjunto. De la misma forma, tendremos conflictos **shift-reduce** o **reduce-reduce** en algún estado, si los *look-ahead* de algunas producciones **reduce** coinciden con otras, o con una de las transiciones salientes. + +Pasemos entonces a construir el autómata LR(1) de la gramática anterior: + + S -> E + E -> A = A | i + A -> i + A | i + +Comenzamos por el estado inicial: + + I0 = { + S -> .E, $ + } + +Vamos a añadir entonces las producciones de `E`. Notemos que como en `S -> E` detrás de `E` no viene nada, el *look-ahead* será justamente `$`: + + I0 = { + S -> .E, $ + E -> .A = A, $ + E -> .i, $ + } + +Hasta el momento hemos obtenido un estado inicial equivalente al del autómata SLR correspondiente. Adicionamos entonces las producciones de `A`, y veremos el primer cambio importante. El centro de estos items serán (de forma equivalente al caso SLR), `A -> .i + A` y `A -> .i`. Sin embargo, al calcular el *look-ahead*, aplicando la definición, tenemos que computar $First(=\$)$ que es el token `=`. Luego: + + I0 = { + S -> .E, $ + E -> .A = A, $ + E -> .i, $ + A -> .i + A, = + A -> .i, = + } + +Y ya podemos intuir cómo el autómata LR resolverá el conflicto **reduce-reduce** que teníamos anteriormente, ya que las producciones a reducir en el próximo estado tienen *look-ahead* distinto. Por completitud, continuemos con el resto del autómata. + + I1 = Goto(I0, E) = { + S -> E., $ + } + + I2 = Goto(I0, A) = { + E -> A.= A, $ + } + + I3 = Goto(I0, i) = { + E -> i., $ + A -> i.+ A, = + A -> i., = + } + +Como intuíamos, el estado $I_3$, que anteriormente tenía un conflicto **reduce-reduce**, ahora es válido. Veamos el resto de los estados: + + I4 = Goto(I2, =) = { + E -> A =.A, $ + A -> .i + A, $ + A -> .i, $ + } + + I5 = Goto(I3, +) = { + A -> i +.A, = + A -> .i + A, = + A -> .i, = + } + +Ahora veamos los estados que se derivan de estos. Comenzaremos a notar que aparecen estados muy similares a los anteriores, pero con conjuntos *look-ahead* distintos: + + I6 = Goto(I4, A) = { + E -> A = A., $ + } + + I7 = Goto(I4, i) = { + A -> i.+ A, $ + A -> i., $ + } + + I8 = Goto(I5, A) = { + A -> i + A., = + } + + I9 = Goto(I5, i) = { + A -> i.+ A, = + A -> i., = + } + +Como vemos, $S_7$ y $S_9$ son estados en principio idénticos, excepto porque los *look-ahead* asociados a cada item son distintos. Esta repetición de estados casi iguales será el próximo problema a resolver, pero por el momento continuemos con el autómata: + + I10 = Goto(I7, +) = { + A -> i +.A, $ + A -> .i + A, $ + A -> .i, $ + } + + Goto(I9, +) = S5 + + I11 = Goto(I10, A) = { + A -> i + A., $ + } + + Goto(I10, i) = S7 + +El autómata resultante tiene 12 estados. A modo de comparación, el autómata SLR correspondiente tiene 9 estados. Como ya tenemos práctica, lo mostraremos sin más explicación: + + I0 = { + S -> .E + E -> .A = A + E -> .i + A -> .i + A + A -> .i + } + + I1 = Goto(I0, E) = { + S -> E. + } + + I2 = Goto(I0, A) = { + E -> A.= A + } + + I3 = Goto(I0, i) = { + E -> i. + A -> i.+ A + A -> i. + } + + I4 = Goto(I2, =) = { + E -> A =.A + A -> .i+ A + A -> .i + } + + I5 = Goto(I3, +) = { + A -> i +.A + A -> .i + A + A -> .i + } + + I6 = Goto(I4, A) = { + E -> A = A. + } + + I7 = Goto(I4, i) = { + A -> i.+ A + A -> i. + } + + I8 = Goto(I5, A) = { + A -> i + A. + } + + Goto(I5, i) = I7 + + Goto(I7, +) = I5 + +Los estados adicionales necesarios en LR son justamente aquellos donde existen conflictos. + +## Parsing LALR(1) + +Si observamos el autómata LR(1) nuevamente, notaremos algunos estados que son muy semejantes, y solo se diferencian en los conjuntos de *look-aheads*. En particular, el estado $I_7$ y el estado $I_9$ tienen los mismos centros: + + I7 = Goto(I4, i) = { + A -> i.+ A, $ + A -> i., $ + } + + I9 = Goto(I5, i) = { + A -> i.+ A, = + A -> i., = + } + +Al igual que los estados $I_5$ e $I_10$: + + I5 = Goto(I3, +) = { + A -> i +.A, = + A -> .i + A, = + A -> .i, = + } + + I10 = Goto(I7, +) = { + A -> i +.A, $ + A -> .i + A, $ + A -> .i, $ + } + +Y los estados $I_8$ e $I_11$: + + I8 = Goto(I5, A) = { + A -> i + A., = + } + + I11 = Goto(I10, A) = { + A -> i + A., $ + } + +Intuitivamente, estos son los estados que ayudan a desambiguar el autómata SLR, pues separan en diferentes subconjuntos de terminales lo que antes era el Follow de un no-terminal. De cierta forma este es el precio a pagar por el poder adicional del autómata LR sobre el SLR: es necesario separar en mútiples estados lo que antes era un solo estado, para poder discriminar con exactitud qué tokens activan una reducción. + +Afortunadamente, en ocasiones podemos obtener lo mejor de ambos mundos. ¿Qué sucede si intentamos "compactar" estos estados "duplicados"? Idealmente, si esta compactación no introdujera nuevos conflictos, lograríamos un autómata con menos estados y el mismo poder de reconocimiento. Veamos como podríamos proceder. Tomemos por ejemplo los estados $I_7$ e $I_9$ y definamos un nuevo estado $I_{7,9}$. Para ello simplemente combinamos los *look-ahead* de cada par de items iguales en un conjunto: + + I7-9 = { + A -> i.+ A, =$ + A -> i., =$ + } + +De la misma forma, podemos hacer con los pares de estados restantes: + + I5-10 = { + A -> i +.A, =$ + A -> .i + A, =$ + A -> .i, =$ + } + + I8-11 = { + A -> i + A., =$ + } + +La primera verificación que necesitamos hacer es si estos nuevos estados crean conflictos en sí mismos. Es decir, si al combinar, aparece un conflicto **reduce-reduce** que antes no existía, dado por dos reducciones distintas cuyos *look-ahead* ahora tengan intersección. En este caso vemos que no sucede, pues en los estados donde hay reducciones, afortunadamente son al mismo no-terminal, por tanto no hay ambigüedad. + +Luego tenemos que ver cómo se comporta el autómata si reemplazamos los estados originales por estos nuevos "estados combinados". Para ello, tenemos que ver que sucede con las transiciones entrantes y salientes. En principio, todas las transiciones que iban a parar a alguno de los estados originales, irán a parar al nuevo estado combinado. Veamos entonces qué aristas entrantes tenía cada estado original: + + I7-9 | I7 = Goto(I4, i) = Goto(I10, i) + | I9 = Goto(I5, i) + + I5-10 | I5 = Goto(I3, +) = Goto(I9, +) + | I10 = Goto(I7, +) + + I8-11 | I8 = Goto(I5, A) + | I11 = Goto(I10, A) + +Tenemos entonces que factorizar todas estas aristas entrantes hacia los nuevos estados, y comprobar que no ocurran conflictos. Por ejemplo, como `Goto(I4, i) = I7`, ahora esa arista irá hacia `I7-9`. Por otro lado, como `Goto(I5, i) = I9`, esa arista también irá para `I7-9`. Y en este segundo caso, como en estado de salida también va a ser parte de un estado combinado, realmente lo que sucederá es que tendremos una arista de `I5-10` hacia `I7-9`. Pero para que esto sea posible, necesitamos que la otra arista que salía de `I10` también caiga en el nuevo estado combinado, pues de lo contrario tendríamos una ambigüedad. Afortunadamente, en este caso `Goto(I10, i) = I7`, por lo que no existe conflicto. Luego, procedamos a compactar todas las transiciones entrantes: + + I7-9 = Goto(I4, i) = Goto(I5-10, i) + I5-10 = Goto(I3, +) = Goto(I7-9, +) + I8-11 = Goto(I5-10, A) + +En principio, nos queda ver las aristas salientes de estos estados combinados. En este caso particular todas las aristas salientes ya han sido analizadas, como aristas entrantes de otros estados. En el caso general, es posible que existan aristas salientes de un estado combinado de vayan a parar a estados distintos. Por ejemplo, si hubiera una arista de $I_7$ con un token `c` hacia un estado $I_i$, y otra arista desde $I_9$ con el mismo token `c` hacia otro estado $I_j$, que no fueran combinables (no tuvieran el mismo centro), entonces no sería posible realizar esta compactación. + +Veamos el autómata final que hemos obtenido al combinar los estados con el mismo centro: + + I0 = { + S -> .E, $ + E -> .A = A, $ + E -> .i, $ + A -> .i + A, = + A -> .i, = + } + + I1 = Goto(I0, E) = { + S -> E., $ + } + + I2 = Goto(I0, A) = { + E -> A.= A, $ + } + + I3 = Goto(I0, i) = { + E -> i., $ + A -> i.+ A, = + A -> i., = + } + + I4 = Goto(I2, =) = { + E -> A =.A, $ + A -> .i + A, $ + A -> .i, $ + } + + I5-10 = Goto(I3, +) = Goto(I7-9, +) { + A -> i +.A, =$ + A -> .i + A, =$ + A -> .i, =$ + } + + I6 = Goto(I4, A) = { + E -> A = A., $ + } + + I7-9 = Goto(I4, i) = Goto(I5-10, i) { + A -> i.+ A, =$ + A -> i., =$ + } + + I8-11 = Goto(I5-10, A) = { + A -> i + A., =$ + } + +El nuevo autómata que hemos construido tiene exactamente 9 estados, la misma cantidad que el autómata SLR, y sin embargo no presenta conflictos. Este autómata se denomina LALR, y constituye el resultado más importante en la práctica para la construcción de compiladores, ya que la mayoría de los generadores de parsers autómaticos usados en la industria construyen este tipo de autómatas. Esto se debe a que combina de forma ideal un poder reconocedor muy similar al LR, con una cantidad de estados mucho menor, proporcional al SLR. + +Intuitivamente, el motivo por el que este autómata no presenta conflictos, y el SLR sí, se debe a que en este caso hemos hecho un análisis más riguroso de los Follow primero (construyendo el autómata LR), y solo entonces hemos intentado combinar los estados. Esto fue posible ya que los estados con los mismos centros no eran aquellos donde se producían los conflictos **reduce-reduce** en el autómata SLR. Es decir, al aplicar la técnica LR, y analizar cuidadosamente los Follow, logramos evitar el conflicto en el estado $I_3$, pero luego esa misma técnica nos llevó a crear estados independientes innecesarios. De cierta forma, la técnica LR es demasiado rigurosa, y nos lleva incluso a intentar evitar conflictos que en realidad no van a ocurrir. La técnica LALR entonces reconoce estas situaciones donde tenemos "demasiado rigor" y simplifica el autómata tanto como sea posible. + +Siguiendo esta línea de pensamiento, debería ser posible construir el autómata LALR directamente, sin necesidad de primero construir el LR para luego combinar los estados innecesarios. De hecho, esto es posible, y es lo que hacen los generadores de parsers usados en la práctica. Aunque no presentaremos un algoritmo detallado para esto, podemos ver intuitivamente que los estados se pueden ir combinando "sobre la marcha", a medida que se descubren estados con el mismo centro que otros ya creados, y arreglando las transiciones existentes en caso de ser necesario. + +Un punto de importancia en el autómata LALR, es que no se puede hacer "una parte" de este. Es decir, o bien todos los estados con el mismo centro de combinan, y no aparece ningún conflicto nuevo, o no se combina ninguno y el autómata se queda LR. De modo que no existen "grados" de LALR. + +## Implementación del parser LR + +Veamos entonces como construir un algoritmo de parsing lineal que obtenga el árbol de derivación correspondiente. Recordemos que lo que tenemos hasta el momento es un autómata que nos permite reconocer si el contenido de la pila es un prefijo viable. En principio, en cada iteración, tras realizar un **shift** o un **reduce**, es necesario volver a correr el autómata en todo el contenido de la pila, para determinar en qué estado termina, y poder decidir la próxima operación. Esto es innecesariamente costoso. Intuitivamente, dado que tras una operación **shift** o **reduce** sabemos exactamente como cambia la pila, deberíamos poder "hacer backtrack" en el autómata, y solamente ejecutar la parte necesaria para reconocer el nuevo sufijo de la pila. + +Por ejemplo, supongamos que tenemos un estado del parser $\alpha | c \omega$, y al ejecutar el autómata, terminamos en un estado $I_i$ que indica **shift** con el token `c`. Si $Goto(I_i, c) = I_j$, entonces sabemos que la siguiente iteración terminaremos en el estado $I_j$. Efectivamente, tras un **shift** tendremos un nuevo estado en la pila $\alpha c | \omega$, y como el autómata es determinista, tras reconocer $\alpha$ tendrá que terminar necesariamente en el estado $I_i$. Luego, el token `c` lo envía al estado $I_j$, precisamente porque esa es la definición de la función **Goto**. Por tanto, tras una operación de **shift**, no es necesario volver a correr el autómata en todo el contenido de la pila. Simplemente podemos transitar directamente al estado $Goto(I_i, c)$. + +Veamos que sucede tras una operación **reduce**. Sea $\alpha \beta | \omega$ el estado de la pila antes del **reduce**, y $\alpha X | \omega$ el estado después de reducir $X \rightarrow \beta$. Supongamos que el autómata, tras reconocer $\alpha$, cae en el estado $I_i$. Entonces tras reconocer $\alpha X$ debe caer en el estado $Goto(I_i, X)$ por definición. Por tanto, una vez sacados $|\beta|$ terminales de la pila, solamente necesitamos ser capaces de "recordad" en que estado estaba el autómata cuando reconoció los primeros $|\alpha|$ terminales, y de ahí movernos una sola transición. Para ello, sencillamente almacenaremos en la pila, además de la forma oracional que se está construyendo, también los estados que transita el autómata en cada símbolo (ya sea almacenando pares $$ o con una pila paralela para los estados). Por tanto, cuando extraemos los $|\beta|$ terminales de la pila, en el tope está justamente el estado $I_i$. + +Con estas dos estrategias, podemos demostrar que tenemos un algoritmo de parsing lineal. Definamos entonces de una vez y por todas este algoritmo formalmente. Para ello vamos a construir una tabla, que llamaremos **tabla LR**, y que nos indicará en cada situación qué hacer (al estilo de la **tabla LL**). Mostraremos a continuación la **tabla LR** para el autómata construido anteriormente, y luego veremos paso a paso los detalles sobre su construcción: + +Estado = + i $ E A +------- ------------- -------- -------- ------------- ------- -------- +0 S3 S->E 1 2 +1 OK +2 S4 +3 A->i S5 E->i +4 S7 6 +5 S9 8 +6 E -> A = A +7 S10 A -> i +8 A -> i + A +9 A -> i S5 +10 S7 11 +11 A -> i + A +------- ------------- -------- -------- ------------- ------- -------- + +La tabla LR contiene una fila por cada estado del autómata, y una columna por cada símbolo (terminales y no-terminales). Usaremos la notación $T[i,x]$ para referirnos a la entrada asociada al símbolo $x$ en el estado $I_i$: + +* Si $S \rightarrow E \cdot, \$$ pertenece al estado $I_i$, entonces la entrada $T[i,\$] = OK$. +* Si $Goto(I_i, X) = I_j$:t + * Si $X \in N$, entonces $T[i,X] = j$. + * Si $X \in T$, entonces $T[i,X] = S_j$ (**shift**): +* Si el item $Y \rightarrow \beta \cdot, c$ está en el estado $I_i$, entonces $T[i,c] = Y \rightarrow \beta$ (**reduce**). + +Para usar la tabla, veamos qué significa cada posible valor en una entrada. Sea $S = \alpha | c \omega$ el estado de la pila de símbolos, e $I_i$ el estado del autómata en el tope de la pila de estados (asumiendo una implementación basada en dos pilas paralelas). Buscamos entonces la entrada $T[i,c]$, y según su valor realizamos la siguiente operación: + +* Si $T[i,c] = OK$, entonces terminamos de parsear y la cadena se reconoce. +* Si $T[i,c] = S_j$, entonces hacemos **shift**, la pila de símbolos se convierte en $\alpha c | \omega$, y ponemos el estado $I_j$ en el tope de la pila de estados. +* Si $T[i,c] = X \rightarrow \delta$, entonces se garantiza que $\alpha = \beta \delta$. Extraemos $|\delta|$ elementos de la pila de símbolos **y** de la pila de estados. Sea $I_k$ el estado que queda en el tope de la pila de estados; colocamos a $X$ en el tope de la símbolos y colocamos $T[k,X]$ en el tope de la pila de estados. +* En cualquier otro caso, se ha encontrado un error. + +Para entender por qué el algoritmo descrito anteriormente funciona, tratemos de interpretar qué significa cada entrada en la tabla. Una entrada de la forma $S_j$ significa que con el token correspondiente existe una transición hacia el estado $I_j$. Por tanto, la operación a realizar es **shift**, y como ya hemos visto anteriormente, en la pila de estados sabemos que el siguiente estado hacia el que transitar será justamente $j$. Una entrada de la forma $X \rightarrow \beta$ significa que existe un item **reduce** con el token correspondiente de *look-ahead*. Por lo tanto se realiza la operación de **reduce**. Como vimos anteriormente, en el tope de la pila de estados quedará el estado $I_j$ que habíamos transitado justo antes de reconocer la producción reducida. Por tanto, de ese estado anterior, el nuevo estado al que transitaremos es justamente $T[j,X]$. + +El único punto que nos queda por discutir, es cómo se construye el árbol de derivación. Esbozaremos un algoritmo para esto, que ejemplificaremos más adelante. Dado que la derivación se construye de abajo hacia arriba, intuitivamente puede verse que construiremos el árbol empezando por las hojas. La idea general consiste en mantener una tercera pila donde se irán acumulando sub-árboles de derivación. Cada vez que se haga una operación **reduce** $X \rightarrow \beta$, tendremos en el tope de esta pila $|\beta$ sub-árboles de derivación, que agruparemos bajo una nueva raíz $X$. Al finalizar el reconocimiento, en la pila quedará solamente un árbol, que será la derivación de toda la cadena. + +Veamos ahora un ejemplo de cómo funciona el algoritmo de parsing bottom-up con la cadena `i = i + i`, usando la tabla definida anteriormente. Ilustraremos la ejecución del algoritmo, representando el estado de la pila de símbolos de la forma usual, y además representando las dos pilas correspondientes a los estados y los sub-árboles de derivación. Para representar un árbol, usaremos la notación $X(t_1,t_2,\ldots,t_n)$, donde $X$ es el símbolo de la raíz, y $t_i$ es una hoja, o un árbol a su vez. Comenzamos entonces con todas las pilas en su estado inicial: + + Symbols :: |i = i + i $ + States :: 0| + Trees :: | + +Consultamos la tabla. En el estado 0, con *look-ahead* `i`, la operación es **shift 3**. Notemos cómo en este estado inicial, todos los demás token darían error. Colocamos el terminal, el estado, y el árbol recién creado en el tope de las respectivas pilas: + + Symbols :: i|= i + i $ + States :: 0 3| + Trees :: i| + +Nos encontramos ahora en el estado 3, con *look-ahead* `=`, la operación es **reduce** `A -> i`. Entonces sacamos el token `i` de la pila y lo reemplazamos por `A`. El estado 3 también se saca y se reemplaza por $Goto(0, A) = 2$ (0 es el estado que queda justo debajo de 3 en la pila). El árbol $i$ se ubica como único hijo del nuevo árbol $A$ creado: + + Symbols :: A|= i + i $ + States :: 0 2| + Trees :: A(i)| + +Consultamos de nuevo la tabla, $T[2,=]$ es **shift 4**: + + Symbols :: A =|i + i $ + States :: 0 2 4| + Trees :: A(i) =| + +Consultamos de nuevo, $T[4,i]$ es **shift 7**. En la pila de árboles se nos han ido acumulando sub-árboles distintos, que serán mezclados en el futuro: + + Symbols :: A = i|+ i $ + States :: 0 2 4 7| + Trees :: A(i) = i| + +Ahora $T[7,+]$ nos dice **shift 10**: + + Symbols :: A = i +|i $ + States :: 0 2 4 7 10| + Trees :: A(i) = i +| + +Por último, $T[10,i]$ nos dice nuevamente **shift 7**: + + Symbols :: A = i + i|$ + States :: 0 2 4 7 10 7| + Trees :: A(i) = i + i| + +Volvemos entonces al estado $I_7$, pero ahora con *look-ahead* `$` la operación indicada es **reduce** `A -> i`. El nuevo estado será $Goto(10,A) = 11$. + + Symbols :: A = i + A|$ + States :: 0 2 4 7 10 11| + Trees :: A(i) = i + A(i)| + +Ahora $T[11,$]$ también nos indica **reduce** pero en este caso en `A -> i + A`. Vamos a sacar entonces 3 elementos de cada pila. En la pila de símbolos, sustituímos `i + A` por `A`. En la pila de estados, sacamos los tres últimos elementos, y ponemos $Goto(4, A) = 6$. En la pila de árboles, sacamos los tres árboles del tope y creamos un nuevo árbol $A$ con esos tres como hijos: + + Symbols :: A = A|$ + States :: 0 2 4 6| + Trees :: A(i) = A(i,+,A(i))| + +Hemos dado un gran salto de fé, pues al sacar los últimos tres estados, hemos confiado en que la pila de estados nos recordará dónde estaba el autómata justo antes de hacer el primer **shift** que dio paso a toda la forma oracional `i + A`. Continuemos entonces con $T[6,\$]$ que nos dice justo lo que esperábamos: **reduce** `E -> A = A`. Repetimos toda la operación de reducción que ya conocemos, siendo $Goto(0,E) = 1$ el último estado que tendremos que analizar: + + Symbols :: E|$ + States :: 0 1| + Trees :: E(A(i),=,A(i,+,A(i)))| + +Finalmente, $T[1,E]$ nos dice que la cadena ha sido parseada. En el tope de la pila de símbolos queda el símbolo inicial, y en la pila de árboles hay un solo árbol que contiene la derivación que hemos construido. Honestamente, en una implementación computacional concreta la pila de símbolos es innecesaria, pues todas las decisiones se toman mirando solamente la pila de estados, y el resultado necesario se computa en la pila de árboles. De cierta forma, esta pila de árboles es un *upgrade* de la pila de símbolos. Hemos hecho la distinción en este ejemplo por cuestiones puramente didácticas, pero en la práctica, la pila de símbolos no se usa. + +## Comparaciones entre LL, SLR, LR y LALR + +Hemos visto hasta el momento los dos paradigmas fundamentales para el parsing determinista de gramáticas libres del contexto. Hagamos entonces una reflexión final sobre los resultados que hemos obtenido, y las herramientas que hemos desarrollado. + +El parser LL es posiblemente el más sencillo de todos los parsers que es útil. En muchos contextos donde se tiene que diseñar un lenguaje bien sencillo (por ejemplo, un DSL integrado en un sistema más complejo), este parser puede brindar una solución fácil y eficiente. La mayor ventaja es que se puede escribir directamente, sin necesidad de usar un generador de parser. Los conjuntos First y Follow se computan a mano, y luego se escriben cada uno de los métodos recursivos asociados a las producciones. Para cualquier lenguaje de complejidad algo mayor, recurriremos entonces a construir un parser LR. + +De manera general, el autómata SLR tiene una cantidad considerablemente menor de estados que el autómata LR correspondiente. En los casos donde la gramática es SLR(1) es preferible usar dicho autómata. Desgraciadamente, la mayoría de las construcciones sintácticas de interés para los lenguajes de programación usuales tienen gramáticas "naturales" que no son SLR, pero sí LR, y generalmente LALR. Por este motivo, el parser LR(1) es, en la práctica, el más usado. Su mayor desventaja radica en el elevado número de estados, que dificultan su almacenamiento. Este problema era especialmente complejo en el año 1965, cuando Donald Knuth propuso este parser. Por tal motivo, aunque teóricamente es una solución adecuada, en la práctica no se usó hasta que en 1969 James DeRemer propuso el parser LALR, que reduce considerablemente la cantidad de estados hasta un nivel comparable con el SLR, sin perder prácticamente en expresividad con respecto con al LR. Más adelante en 1971 el propio DeRemer propondría el SLR como una variante más sencilla de construir algo parecido al LALR de forma más sencilla. + +De modo que, en una situación real, la primera decisión podría ser intentar directamente construir un parser LALR. Si esto funciona, no hay nada más que hacer. En caso contrario, deberíamos probar entonces a construir un parser LR, aunque tenga una cantidad mucho mayor de estados. En el caso peor en que esto no sea posible, tendremos que modificar la gramática. En la práctica esto no sucede comúnmente. Aunque es cierto que es fácil encontrar lenguajes didácticos que no sean LR y sean bien pequeños, los lenguajes de programación reales tienen construcciones que generalmente sí son LR. Incluso en los casos en que esto no sucede, veremos más adelante que es posible "pasar" algunos de los problemas del lenguaje para la fase semántica, y simplificar la gramática, haciéndola LR. + +Desde el punto de vista teórico, tenemos una jerarquía de gramáticas que se comporta de la siguiente forma: + + +------------------+ + | LR | + | +------+ | + | | LL | | + | +---|------|---+ | + | | | LALR | | | + | | +-|------|-+ | | + | | | | SLR | | | | + | | +-|------|-+ | | + | +---|------|---+ | + | +------+ | + +------------------+ + +Es decir, las gramáticas LR son un conjunto estrictamente superior a las gramáticas LL, SLR y LALR. Entre las gramáticas SLR, LALR y LR hay una relación de inclusión que es un orden total. Sin embargo, aunque las gramáticas LL están estrictamente incluidas en las LR, existen gramáticas LL que no son ni SLR ni LALR. + +Desde el punto de vista de la implementación, los parsers SLR, LALR y LR son idénticos. Solamente se diferencian en la forma en que se construye el autómata, que en última instancia determina la tabla obtenida. De la tabla en adelante el algoritmo de parsing es el mismo que hemos visto. De modo que, en una implementación concreta, es posible desacoplar el mecanismo que genera la tabla, del mecanismo que la ejecuta, y reutilizar toda la segunda parte para cualquiera de los tres tipos de parsers. + +Otra cuestión interesante es qué sucede con los errores de parsing. Knuth demostró que el autómata LR reconoce los errores de parsing lo antes posible, para cualquier clase de parser determinista. Esto quiere decir que con la misma cadena (incorrecta) de entrada, ningún algoritmo de parsing podrá darse cuenta de que la cadena es errónea antes que el algoritmo LR. De hecho, los parsers LALR y SLR son más permisivos. Dada una cadena incorrecta, es posible que el parser SLR o LALR haga algunas reducciones de más, antes de darse cuenta de que la cadena es inválida. Al final ninguno de estos parsers deja pasar incorrectamente una cadena inválida, por supuesto. Pero reconocer un error lo antes posible, además de la ventaja en eficiencia, es también muy conveniente para brindar al programar un mensaje de error lo más acertado posible. + +Cabe preguntarse entonces si al inventar el autómata LR hemos definitivamente terminado con el problema de parsing. Pues resulta que la respuesta teórica para esta pregunta es **sí**. En 1965 Knuth demostró que para todo lenguaje libre del contexto determinista tiene que existir una gramática LR(k). Los lenguajes libres del contexto deterministas son aquellos tales que existe un algoritmo de parsing lineal en la longitud de la cadena en caso peor. Por otro lado, toda gramática LR(k) puede ser convertida a LR(1), con la adición de nuevos no-terminales y producciones. De modo que tenemos un resultado teórico que dice: si un lenguaje puede ser parseado en tiempo lineal, entonces puede ser parseado con un parser LR(1). Aquellos lenguajes libres del contexto que no son LR(1) tienen que ser por necesidad ambiguos, o al menos es imposible diseñar un algoritmo de parsing con tiempo lineal. De cierta forma, podemos decir que hemos terminado, pues todo lenguaje "sensato" es LR(1). + +Este resultado es de hecho impresionante, pero la historia no acaba ahí. Incluso aunque teóricamente LR(1) es suficiente, en la práctica hay lenguajes deterministas cuyas gramáticas LR(1) son tan complicadas, que es preferible usar una gramática más flexible, incluso incluyendo algo de ambiguedad que pueda ser resuelto en una fase superior. Afortunadamente, el problema de encontrar un árbol de derivación para cualquier gramática libre del contexto tiene solución con caso peor $O(n^3)$ con respecto a la longitud de la cadena. Es decir, existen parsers generales que pueden reconocer cualquier lenguaje libre del contexto, *incluso lenguajes ambiguos*, y en estos casos se pueden obtener **todos** los árboles de derivación que existen. En la práctica sin embargo, para diseñar lenguajes de programación, queremos parsers lineales por motivos de eficiencia. Estos parsers más generales se emplean sobre todo en tareas de procesamiento de lenguaje natural (p.e. traducción automática). diff --git a/doc/content/chap4.pmd b/doc/content/chap4.pmd new file mode 100644 index 000000000..26245d6ad --- /dev/null +++ b/doc/content/chap4.pmd @@ -0,0 +1,596 @@ +--- +previous-chapter: chap3 +next-chapter: chap5 +--- + +# Análisis Semántico + +```python echo=False +import sys +import os + +sys.path.append(os.path.abspath(os.curdir)) + +from source.trees import Tree as T +``` + +En la mayoría de los lenguajes de programación de tercera generación existe el concepto de variable, que en última instancia se mapea a una región de la memoria donde se almacena un valor. Una de las reglas básicas del uso de variables en casi todos los lenguajes tiene que ver con la declaración y/o inicialización de una variable antes de su uso. Por ejemplo, en los lenguajes tipo C (C++, C#, Java), tenemos la siguiente construcción: + +```cpp +int x = 5; +int y = 10; +// .... +int z = x + y; +``` + +Desde el punto de vista sintáctico, podemos pensar que un fragmento de la gramática que genera este lenguaje será algo como: + + := "=" ";" | ... + +Una gramática como esta será incapaz de diferenciar situaciones como la anterior, de situaciones como la siguiente: + +```cpp +int x = 5; +int y = 10; +// .... +int z = p + q; +``` + +Donde las variables `p` y `q` no aparecen anteriormente en ninguna parte del método correspondiente. En la práctica es virtualmente imposible diseñar una gramática que tenga en cuenta que el identificador `p` tiene que haber sido usado en la parte derecha de una asignación antes de que aparezca en la parte izquierda. + +Peor aún es el problema de determinar qué operaciones son válidas para un tipo determinado. Por ejemplo, impedir el uso del operador `+` entre una variable de tipo `int` y una de tipo `bool`. Incluso más complejo es verificar la consistencia de una invocación `x.F()`. En este caso es necesario saber de qué tipo `T` es `x` para determinar si existe un método `F` declarado en la clase `T`, o peor aún, en algún padre de la clase `T`. + +Un ejemplo aún más complicado desde el punto de vista sintáctico es validar si en una invocación `F(a,b,c)` la cantidad de parámetros es correcta, y si los tipos asociados a las expresiones `a`, `b` y `c` son compatibles a los tipos declarados en los parámetros formales de la función (iguales, herederos o existe una conversión implícita). Por ejemplo, distinguir en el fragmento de programa siguiente, que el método `G` es correcto, pero ni `H` ni `I` son correctos: + +```cpp +void F(int a, int b) { + // ... +} + +void G() { + F(1, 2); +} + +void H() { + F(1, "2"); +} + +void I() { + F(1, 2, 3); +} +``` + +Podemos pensar que la gramática "natural" para la declaración e invocación de funciones tiene la forma siguiente: + + := "(" ")" "{" "}" + := | "," | epsilon + := + + := "(" ")" + := | "," | epsilon + := ... + +En esta gramática (o variantes similares) no existe ninguna diferencia que permita distinguir la invocación hecha en `G` de la invocación hecha en `H`. +Intuitivamente no podemos expresar en una gramática libre del contexto las dependencias y relaciones entre los tipos, números de argumentos, y ámbitos de variables, dado que estas relaciones son intrínsicamente *dependientes del contexto*. Esto se debe a que dichas relaciones se ven expresadas, en principio, a todo lo largo del programa. La distancia entre una declaración de variable o función y su uso puede ser arbitrariamente larga. El orden en que las declaraciones y los usos se entrelazan es también arbritario. Por lo tanto, en principio, no deberíamos ser capaces de encontrar gramáticas libres del contexto que nos permitan expresar estas restricciones. + +De forma general, el problema de reconocer si una cadena pertenece a cierto lenguaje, podemos verlo como el problema de determinar si dicha cadena cumple una serie de predicados lógicos. Por ejemplo, el lenguaje $a^n b^n$ está formado por las cadenas $\omega = s_1 s_2 \ldots s_n$ que cumplen los predicados siguientes: + +* $s_i = a$ o $s_i = b$ (el alfabeto es $\{a,b\}$) +* Si $j > i$ y $s_i = b$ entonces $s_j = b$ (todas las $b$ aparecen luego de todas las $a$) +* $|\{s_i | s_i = a\}| = |\{s_i | s_i = b\}|$ (la cantidad de $a$ y $b$ es la misma) + +Para muchas clases de predicados, podemos construir gramáticas que generan los lenguajes correspondientes. A veces, la intersección de estos lenguajes tiene una estructura tal que aún podemos seguir construyendo gramáticas para el lenguaje final. En otras ocasiones, la intersección de varios predicados nos da un lenguaje tal que, aunque somos capaces de reconocer las partes constituyentes, no podemos reconocer el lenguaje como un todo con gramáticas del mismo poder expresivo. + +Consideremos entonces un lenguaje de programación determinado para el que queremos construir un compilador. Una de las tareas de este compilador es determinar qué cadenas (programas) son válidas en el lenguaje. Podemos pensar en la gran variedad de predicados que se aplican en estos casos. Por un lado, están todas las reglas que podemos llamar "sintácticas": los métodos empiezan por un identificador y una lista de argumentos entre paréntesis, las instrucciones terminan en un símbolo "punto y coma (;)", etc. Por otro lado, tenemos todas estas reglas que no son sintácticas: la consistencia en el uso de los tipos, que cierta función debe devolver un valor por todos los posibles caminos de ejecución, que las variables deben inicializarse antes de usarse en expresiones. Podemos llamar a estas reglas, "semánticas", porque de cierta forma nos indican cuál es el significado "real" del lenguaje. + +Por ejemplo, en la instrucción `int x = 5;` tenemos por un lado el conjunto de reglas que determinan la forma de la instrucción (primero el tipo, luego un identificador, luego un igual, luego una expresión), y las que determinan el significado de la instrucción (almacenar un valor `5` en la zona de memoria asociada a la variable `x`). Podemos entonces imaginar que dividimos todos los predicados que definen los programas válidos en dos conjuntos: aquellos para los que podemos construir una gramática que los reconozca, y los que no. Los primeros serán justamente los *predicados sintácticos*, y los segundos, por analogía, los llamaremos *predicados semánticos*. Para el primer conjunto, tenemos un mecanismo formal que nos permite describirlos: las **gramáticas libres del contexto**. Para el segundo conjunto, desarrollaremos en este capítulo otro mecanismo formal similar, que nos permitirá describir de forma unívoca cuál es el "significado" de un programa. + +Justamente, la fase de análisis sintáctico se encarga de validar que los predicados sintácticos se cumplen (y además construir un árbol de derivación). La fase de **análisis semántico**, que comenzaremos a estudiar en este capítulo, se encarga entonces de validar que los predicados semánticos se cumplan (y a su vez construir otras estructuras de datos que veremos más adelante). + +Hemos visto que en la fase semántica el poder de las gramáticas libres del contexto es insuficiente. Además, los ejemplos de problemas semánticos que hemos presentado nos muestran la extrema dificultad de expresar estas reglas, incluso con gramáticas dependientes del contexto (para las que además no tenemos mecanismos reconocedores eficientes). Tenemos entonces que cambiar de paradigma. + +Recordemos el problema a resolver: verificar los predicados semánticos (que aun no hemos definido completamente), una vez tenemos la seguridad de que la sintaxis es correcta. Recordemos entonces los árboles de derivación, que representan en una estructura computacionalmente cómoda de manipular el conjunto de producciones y el orden en que son aplicadas para producir la oración correspondiente. Este árbol de derivación a menudo se denomina árbol de sintaxis concreta, pues representa exactamente todos los elementos de la sintaxis descritos en la gramática. Intuitivamente, este árbol de derivación contiene todo el contexto del programa, en una estructura conveniente para ser explorada. ¿Y si intentáramos resolver los predicados semánticos, justamente viéndolos como predicados sobre el árbol de derivación, en vez de sobre la cadena de entrada? ¿Dado que tenemos toda cadena representa en una forma que nos expone toda la estructura sintáctica, no debería ser más fácil detectar aquí todos estos predicados que pueden, en principio, depender de *toda* la estructura global de la cadena? + +Veamos como podemos reescribir algunos de estos predicados en forma de predicados sobre el árbol. Por ejemplo, la regla de que toda variable debe haber sido declarada antes de usarse. Pensemos en un programa arbitrario de C, por ejemplo: + +```cpp +int x = 5; +//... +int y = x + 1; +``` + +Pudiéramos pensar en un posible árbol de derivación para este programa (para una gramática correcta del lenguaje C), donde habría necesariamente un subárbol con la forma: + +```python echo=False, results="plain" +T("", + T(""), + T(""), + T("="), + T("", + T("int") + ) +).print(float=False, width="40%") +``` + +Y por otro lado, tendríamos un subárbol con la forma: + +```python echo=False, results="plain" +T("", + T(""), + T(""), + T("="), + T("", + T("", + T("") + ), + T("+"), + T("", + T("") + ) + ) +).print(float=False, width="50%") +``` + +Y ambos subárboles serían hijos de algún nodo que representa a la función correspondiente. Entonces podemos pensar en una estrategia para determinar si todas las variables son declaradas antes de su uso. En un recorrido en pre-orden por dicho árbol, podemos ir recolectando todas las declaraciones hechas en cierta estructura de datos, y luego cada vez que nos encontremos una variable referenciada en parte izquierda de una expresión, ¡simplemente consultamos dicha estructura y verificamos la existencia de una variable con dicho nombre, y de paso la consistencia de los tipos! De forma similar podemos pensar en la verificación de la cantidad de argumentos usados en una función y sus tipos. + +## Árboles de Sintaxis Abstracta + +En general, una vez tenemos el árbol de derivación, tenemos suficiente información sobre la cadena para reconocer cuáles son todas las variables, métodos, invocaciones, los tipos de cada expresión, etc. El árbol de derivación justamente nos asocia cada token de la cadena a su **función sintáctica**. Nos dice, por ejemplo, que el identificador `x` es el nombre de una variable, mientras que el identificador `printf` pudiera ser el nombre de una función. Además, nos dice cuando este identificador `x` aparece por primera vez, y mejor aún, cuándo aparece en parte derecha o en parte izquierda de una expresión. Tenemos entonces todo el poder expresivo de nuestros algoritmos y estructuras de datos (recorridos de árboles, diccionarios y tablas hash, etc.) para diseñar mecanismos de validación semántica. ¡Justamente es por este motivo que construimos el árbol de derivación en primer lugar! + +Sin embargo, antes de que lanzarnos a diseñar algoritmos de validación semántica, revisemos nuestro árbol de derivación, y notaremos que su estructura no es exactamente idónea para esta tarea. Tomemos por ejemplo la siguiente gramática, que genera un lenguaje de expresiones aritméticas simples: + + E = T + E | T + T = int * T | int | (E) + +Y la cadena siguiente: + + 2 * (3 + 5) + +Como sabemos, esta cadena realmente como secuencia de tokens es: + + int * ( int + int ) + +De momento no nos preocuparemos por el valor concreto del número almacenado en cada token. Como sabemos del análisis lexicográfico, el lexer asocia a cada token además de la clase correspondiente, el fragmento de cadena original que lo forma. Cuando sea conveniente, podemos ver la cadena anterior como: + + int{2} * ( int{3} + int{5} ) + +Donde indicamos explícitamente el **lexema**. Durante el análisis sińtáctico hemos obviado este detalle pues solo nos interesaban los símbolos que aparecen en la gramática. Más adelante volveremos a incluir en nuestro análisis el valor concreto de cada token, que en última instancia constituyen los datos del programa a compilar. + +Por el momento, concentrémonos nuevamente en la cadena a parsear. Esta cadena es generada **de forma única** por el siguiente árbol de derivación: + +```python echo=False, results="plain" +T("E", + T("T", + T("int"), + T("*"), + T("T", + T("("), + T("E", + T("T", + T("int")), + T("+"), + T("E", + T("T", + T("int") + ))), + T(")"))) +).print(float=False, width="40%") +``` + +Este árbol de derivación efectivamente codifica todas las operaciones necesarias a realizar para **evaluar** la expresión (que es en última instancia el problema a resolver). Sin embargo, este árbol representa con demasiado detalle la expresión. Supongamos que queremos diseñar una jerarquía de clases para representar este árbol. Dicha jerarquía tendría varias clases innecesarias, como aquellas que representan a los nodos `(` y `)`. Por otro lado, la estructura del árbol es poco eficiente para representar la expresión, pues hay varios nodos que son redundantes. Por ejemplo, el nodo raíz `E` no nos da ninguna información sobre el tipo concreto de la expresión. De forma general podemos reconocer dos tipos de elementos innecesarios: + +* Nodos que representan elementos sintácticos innecesarios (e.j. los paréntesis) +* Nodos que derivan en un solo hijo (e.j. `E -> T`) + +Los elementos sintácticos innecesarios, como los paréntesis, se emplean en la gramática para representar la prioridad entre sub-expresiones. Sin embargo, una vez construído el árbol de derivación, la prioridad entre las sub-expresiones queda explícitamente descrita en la propia estructura del árbol. Por otro lado, los nodos que derivan en un solo nodo hijo, tales como `E -> T`, son necesarios desde el punto de vista de la gramática para resolver las ambigüedades, pero una vez que se construye el árbol de derivación, no aportan ninguna información adicional. + +Intentemos eliminar estos elementos innecesarios en el árbol de derivación anterior: + +```python echo=False, results="plain" +T("T", + T("int"), + T("*"), + T("E", + T("int"), + T("+"), + T("int")) +).print(float=False, width="35%") +``` + +Este árbol representa exactamente la misma expresión aritmética, y quedan explícitamente descritos el orden y el tipo de las operaciones. Una vez llegado a este punto, podemos notar que hay otro elemento innecesario en el árbol. Si nos fijamos con atención, veremos que el nodo asociado a un operador (`*` o `+`) siempre estará como hijo de exactamente el mismo tipo de nodo (`T` o `E`) respectivamente. Este hecho se desprende directamente de la gramática, pues el terminal `*` solo se genera por `T` y el terminal `+` solo se genera por `E`. Por tanto, ambos nodos respectivos (`T` y `*` o `E` y `+`) siempre aparecerán juntos, y por tanto es redundante tener ambos. + +Pensemos ahora en la jerarquía de clases que representa este árbol, y un posible algoritmo recursivo de evaluación. Una vez en el nodo `T`, evaluados recursivamente las expresiones izquierda y derecha, ¿qué operación es necesario aplicar? Evidentemente, dependerá del nodo que representa la operación. Pero este nodo (`*` o `+`) siempre es un terminal, por lo tanto, nunca será necesario "bajar" recursivamente para descubrir que tipo de operación hay que hacer en un nodo `T` o `E`. Podemos entonces conformarnos con un árbol donde la operación a realizar esté explícita en el nodo padre (`T` o `E`) y no como un hijo adicional: + +```python echo=False, results="plain" +T("*", + T("int"), + T("+", + T("int"), + T("int")) +).print(float=False, width="25%") +``` + +Intuitivamente, el árbol anterior es capaz de representar con todo el detalle necesario la semántica de la expresión a evaluar, y no tiene ningún elemento innecesario. + +A este tipo de estructura se le denomina **árbol de sintaxis abstracta (AST)**, precisamente porque representa solamente la porción de sintaxis necesaria para evaluar la expresión o programa reconocido. En el AST solamente existen nodos por cada tipo de elemento semántico diferente, es decir, por cada significado distinto. + +Por ejemplo, en nuestro lenguaje de expresiones aritméticas, existen tres tipos de "entidades" o conceptos diferentes: + +* un número, +* una operación de suma, y +* una operación de multiplicación. + +De modo que si el árbol de sintaxis concreta (o árbol de derivación) tiene un tipo de nodo por cada tipo de **función sintáctica** diferente, entonces un árbol de sintaxis abstracta tiene un tipo de nodo por cada tipo de **función semántica** distina. Las diferentes funciones sintácticas se obtienen directamente de la gramática, y por tanto están muy influenciadas por el tipo de *parser* que se use. Las funciones semánticas, por otro lado, se diseñan a partir de la funcionalidad que se quiere obtener en el lenguaje, por lo que se tiene generalmente mayor libertad creativa. + +## Diseño de un AST + +A modo de ejemplo, vamos a definir un lenguaje muy sencillo, para el que diseñaremos un árbol de sintaxis abstracta. Este lenguaje será sobre el dominio de las expresiones aritméticas. Nos permitirá operar con variables y funciones predefinidas, así como definir nuevas funciones. Comenzaremos por listar de manera informal las características que queremos obtener de este lenguaje, y veremos luego como formalizar cada una. + +Veamos primero las reglas **sintácticas**: + +* El lenguaje tiene tres tipos de instrucciones: `let`, `def` y `print`: + - `let = ` define una variable denominada `` y le asigna el valor de `` + - `def (, , ...) -> ` define una nueva función `` con los argumentos `` + - `print ` imprime el valor de una expresión +* Las expresiones pueden ser de varios tipos: + - Expresiones ariméticas + - Invocación de funciones predefinidas (`sin`, `cos`, `pow`, ...) + - Invocación de funciones definidas en el programa + +Formalizar estas características sintácticas es relativamente fácil con las herramientas que ya tenemos. Simplemente definiremos una gramática para ello: + + := + := ";" + | ";" + := + | + | + := "let" ID "=" + := "def" ID "(" ")" "->" + := "print" + := ID + | ID "," + := + + | - + | + := * + | / + | + := + | "(" ")" + := NUMBER + | ID + | + := ID "(" ")" + := + | "," + +La gramática anterior es bastante "natural", en el sentido de que no contiene reglas "extrañas" para resolver, por ejemplo, los problemas de ambigüedad típicos de las gramáticas LL(1). Este es el tipo de gramáticas que usualmente queremos diseñar para transmitir a otros lectores las reglas sintácticas del lenguaje. Luego, para una implementación concreta de un parser, es posible (y altamente probable), que tengamos que redefinir la gramática añadiendo producciones para convertirla en LL o LR, según el caso. En cualquier modo, como ya sabemos resolver ese problema, nos conformaremos con pensar que alguien nos dará un parser para esta gramática. + +Definamos ahora informalmente las reglas **semánticas** de nuestro lenguaje: + +* Una variable solo puede ser definida una vez en todo el programa. +* Los nombres de variables y funciones no comparten el mismo ámbito (pueden existir una variable y una función llamadas igual). +* No se pueden redefinir las funciones predefinidas. +* Una función puede tener distintas definiciones siempre que tengan distinta cantidad de argumentos (es decir, funciones del mismo nombre pero con cantidad de argumentos distintos se consideran funciones distintas). +* Toda variable y función tiene que haber sido definida antes de ser usada en una expresión (salvo las funciones pre-definidas). +* Todos los argumentos definidos en una misma función tienen que ser diferentes entre sí, aunque pueden ser iguales a variables definidas globalmente o a argumentos definidos en otras funciones. +* En el cuerpo de una función, los nombres de los argumentos ocultan los nombres de variables iguales. + +> **Nota**: Una consecuencia interesante de estas reglas es que no permiten funciones recursivas... + +Como vemos, todas estas reglas son de naturaleza dependiente del contexto, pues su alcance puede ser en principio todo el programa. Por lo tanto, no tenemos forma de expresar estas reglas en una gramática libre del contexto. Sin embargo, una vez tengamos el árbol de sintaxis abstracta de un programa concreto, veremos que es relativamente fácil verificar cada una de estas reglas. + +Para diseñar el AST de este lenguaje, pensemos en las diferentes funciones semánticas que tiene nuestro programa. Veremos que en muchos casos tenemos un paralelo directo entre un nodo del AST y un símbolo de la gramática, pero en otros casos existirán símbolos que no tienen una función semántica (como los terminales `let`, `def` y `print`) y existirán funciones semánticas (clases de nodos del AST) que no corresponden a ningún símbolo de la gramática. + +Comencemos entonces por el inicio. De forma general es convieniente diseñar una jerarquía de clases con una raíz `Node` (o de nombre similar) que nos representa cualquier nodo del AST. Agrupar todos los nodos del AST en una jerarquía común nos permite definir funciones abstractas sobre todos los nodos (que usaremos para el chequeo semántico más adelante). Por tanto, comenzamos por ahí: + +```cs +public abstract class Node { + //... +} +``` + +A diferencia del árbol de derivación, en esta clase `Node` no hemos puesto explícitamente una propiedad `Children` ni nada similar. Esto se debe a que en el AST en principio cada hijo de un nodo tiene una función semántica propia. Por tanto, en vez de tener una lista de hijos general, es preferible en cada subclase defnir exactamente que nodos (y de qué tipo) son los hijos esperados. De modo que no tendremos un "árbol" en el sentido puro como estructura de datos, sino una colección de clases relacionadas entre sí, cuya estructura en memoria será un árbol. + +La primera función semántica que necesitamos es aquella que nos represente a nuestro programa. Como hemos visto en la gramática, un programa simplemente es una colección de instrucciones (*statements*), por lo tanto, necesitamos también definir esta función semántica. + +```cs +public class Program { + public List Statements; +} + +public abstract class Statement { + //... +} +``` + +Notar que hemos definido a `Program` como una clase concreta, pero a `Statement` como a una clase abstracta. Esto se debe a que tenemos diversos tipos de instrucciones concretas, pero la instrucción "base" en sí no es realmente una función semántica propia. Una regla más o menos común es que cuando un no-terminal deriva en más de una producción, cada una de esas producciones puede corresponder a una función semántica distinta. Sin embargo, en otros casos, un no-terminal deriva en más de una producción por motivos puramente sintácticos, como en el caso de ``, cuya única función es describir una lista de instrucciones. En el AST, no tiene mucho sentido tener un nodo particular para una lista de instrucciones, y por tanto en `Program` tenemos esta lista de forma explícita. + +Veamos entonces los tres tipos concretos de instrucciones: + +```cs +public class LetVar : Statement { + public string Identifier; + public Expression Expr; +} + +public class DefFunc : Statement { + public string Identifier; + public List Arguments; + public Expression Expr; +} + +public Print : Statement { + public Expression Expr; +} +``` + +El motivo por el que estos nodos son herederos de `Statement` es justamente para poder definir en `Program` una lista de diferentes tipos de instrucciones. De modo que estamos la herencia solamente para definir estructura, y no para aprovecharnos del polimorfismo (ya que no tenemos comportamiento en los nodos). Esto cambiará más adelante cuando nos interesemos por la verificación semántica. + +Vamos a definir la parte de la jerarquía que representa las expresiones en sí. En la gramática tenemos los no-terminales ``, ``, `` y `` que nos sirven para definir la prioridad de los operadores. Sin embargo, desde el punto de vista semántico, todos estos no-terminales juegan el mismo papel. Por ejemplo, las expresiones binarias, desde el punto de vista semántico, son prácticamente idénticas. La única diferencia es el operador concreto a aplicar. De modo que podemos tener **una única clase** de expresión binaria: + +```cs +public enum Operator { Add, Sub, Mult, Div } + +public abstract class Expression : Node { + //... +} + +public class BinaryExpr : Expression { + public Operator Op; + public Expression Left; + public Expression Right; +} +``` + +Este diseño puede parecer a algunos "anti-orientado-a-objetos", pues no estamos definiendo una clase por cada tipo de expresión binaria. La discusión de cuál diseño es mejor es mucho más compleja que lo que podemos abordar en este párrafo. Solamente diremos algo a favor de este enfoque, y es que, al menos de momento, si tuviéramos una clase `MultNode` y una clase `AddNode`, estas serían exactamente iguales. Por lo tanto, como no tenemos comportamiento **ni** estructura distintos en ambas clases, no tiene sentido, al menos de momento, tener una clase por cada tipo de operador. Más adelante revisaremos esta hipótesis y tendremos una discusión más profunda al respecto. + +Nos quedan entonces tres tipos de expresiones: constante numérica, variable y llamada a una función. Para cada una de estas tendremos una clase distinta, pues tienen estructura diferente: + +```cs +public class FuncCall : Expression { + public string Identifier; + public List Args; +} + +public class Variable : Expression { + public string Identifier; +} + +public class Number : Expression { + public string Value; +} +``` + +Hemos definido la clase `Number` con un valor de tipo `string`, ya que, en principio, no es hasta el chequeo semántico que nos interesa saber el valor concreto del número que este token representa. Por lo tanto, podemos pensar que ni el *lexer* ni el *parser* se interesarán por obtener este valor. + +Y en este punto hemos terminado con nuestro árbol de sintaxis abstracta. Tenemos un total de 11 clases, de las cuáles 3 son abstractas y 8 son concretas. En la gramática tenemos un total de 25 producciones, que en principio son 25 funciones sintácticas diferentes. Algunas de ellas son listas, y por tanto no tienen función semántica asociada. Otras, como en el caso de las expresiones, están para desambigüar y establecer el orden operacional, por lo que tampoco tienen una función semántica asociada. En lenguajes más complejos, podemos tener también varias producciones que simplemente sean formas sintácticas diferentes de expresar la misma función semántica (e.j. **if** con **else** e **if** sin **else**). + +Nos queda pendiente la tarea de obtener el AST a partir del árbol de derivación (que es la salida que realmente nos da el *parser*). De momento vamos a asumir que este algoritmo existe, y nos concentraremos en los tipos de análisis que podemos hacer sobre el AST una vez construido. Más adelante veremos un mecanismo formal que nos permite expresar como se construye el AST a partir del árbol de derivación, y un algoritmo para ello. + +## Validando las reglas semánticas + +Volvamos a la tarea que dio origen a toda esta discusión del AST: validar el cumplimiento de las reglas semánticas. Recordemos nuevamente estas reglas: + +* Una variable solo puede ser definida una vez en todo el programa. +* Los nombres de variables y funciones no comparten el mismo ámbito (pueden existir una variable y una función llamadas igual). +* No se pueden redefinir las funciones predefinidas. +* Una función puede tener distintas definiciones siempre que tengan distinta cantidad de argumentos (es decir, funciones del mismo nombre pero con cantidad de argumentos distintos se consideran funciones distintas). +* Toda variable y función tiene que haber sido definida antes de ser usada en una expresión (salvo las funciones pre-definidas). +* Todos los argumentos definidos en una misma función tienen que ser diferentes entre sí, aunque pueden ser iguales a variables definidas globalmente o a argumentos definidos en otras funciones. +* En el cuerpo de una función, los nombres de los argumentos ocultan los nombres de variables iguales. + +En esta sección vamos a presentar una solución *ad-hoc* para estos problemas, en el caso particular del lenguaje que hemos definido. Más adelante formalizaremos esta estrategia de solución y mostraremos como extenderla a lenguajes más generales. + +De manera general, el enfoque que usaremos será el siguiente. Cada regla semántica realmente se aplica solo a algunos tipos de nodos, pero para cada tipo de nodo podemos determinar qué reglas se aplican. Vamos a definir entonces un método `Validate()` en cada nodo, que nos dirá si dicho nodo es correcto. Por supuesto, ya podemos intuir que la implementación concreta de este método en un nodo dependerá recursivamente de los nodos hijos. + +Por otro lado, notemos que la mayoría de las reglas semánticas nos hablan sobre las definiciones y uso de las variables y funciones. De hecho, por este motivo es justamente que dichas reglas son dependientes del contexto. De modo que, intuitivamente, en cada nodo necesitaremos tener acceso a este "contexto", donde pueden estar definidas las funciones y variables que su usan en dicho nodo. Dado que tenemos todo el AST construido, cabe pensar que dicho contexto se puede calcular en un recorrido sobre el árbol. De hecho, como veremos, en el mismo recorrido que vamos validando las reglas semánticas, iremos construyendo el contexto correspondiente. Vamos entonces a diseñar una estructura de datos que nos represente dicho contexto. En esta estructura tenemos que almacenar las funciones y variables definidas (en el caso de las funciones con la cantidad de argumentos), y poder consultar en todo momento qué es lo definido. Supongamos entonces que tenemos una implementación de la siguiente **interface**: + +```cs +public interface IContext { + bool IsDefined(string variable); + bool IsDefined(string function, int args); + bool Define(string variable); + bool Define(string function, string[] args); +} +``` + +Agregamos entonces el método siguiente: + +```cs +public abstract class Node { + public abstract bool Validate(IContext context); +} +``` + +Veamos entonces como se implementa esta validación en los nodos concretos. En el caso de `Program` es muy sencillo, el programa está correcto solo si cada una de las instrucciones que lo componen se valida correctamente: + +```cs +public class Program : Node { + public List Statements; + + public override bool Validate(IContext context) { + foreach(var st in Statements) { + if (!st.Validate(context)) { + return false; + } + + return true; + } + } +} +``` + +Pasemos entonces a la validación de las expresiones, cuyas regla semántica fundamental es que todos los identificadores usados tienen que haber sido definidos antes. En el caso de las expresiones binarias es muy sencillo: + +```cs +public class BinaryExpr : Expression { + public Operator Op; + public Expression Left; + public Expression Right; + + public override bool Validate(IContext context) { + return Left.Validate(context) && Right.Validate(context); + } +} +``` + +Ahora, en el caso de las expresiones atómicas es donde realmente sucede lo importante. Comezamos por el caso más sencillo: + +```cs +public class Number : Expression { + public string Value; + + public override bool Validate(IContext context) { + return true; + } +} +``` + +Veamos entonces el caso del nodo `Variable`. Este nodo nos representa una variable siendo usada como parte de una expresión, por lo tanto, como dice la regla semántica, tiene que haber sido definida antes: + +```cs +public class Variable : Expression { + public string Identifier; + + public override bool Validate(IContext context) { + return context.IsDefined(Identifier); + } +} +``` + +Por último, para el caso de una función, la validación es muy similar, pero teniendo en cuenta la cantidad de argumentos. Además, dado que una invocación a función define recursivamente un conjunto de expresiones para los valores de cada argumento, es necesario validar cada una: + +```cs +public class FuncCall : Expression { + public string Identifier; + public List Args; + + public override bool Validate(IContext context) { + foreach(var expr in Args) { + if (!expr.Validate(context)) { + return false; + } + } + + return context.IsDefined(Identifier, Args.Count); + } +} +``` + +Veamos finalmente la implementación de los nodos `LetVar` y `DefFunc`. Es justamente en estos nodos donde se definen nuevas variables y funciones, por lo que en el momento de validar estos nodos, es donde realmente se calcula este "contexto" del que tanto hemos hablado. El caso de la definición de variable es el más sencillo, así que comenzaremos por ahí: + +```cs +public class LetVar : Statement { + public string Identifier; + public Expression Expr; + + public override bool Validate(IContext context) { + if (!Expr.Validate(context)) { + return false; + } + + if (!context.Define(Identifier)) { + return false; + } + + return true; + } +} +``` + +El caso de la definición de función es mucho más interesante. Por un lado es necesario validar que no exista una función con el mismo nombre y la misma cantidad de argumentos, lo que es sencillo. Por otro lado, es necesario validar recursivamente el cuerpo de la función. El problema aquí es que en el cuerpo de la función permitimos no solo usar las variables definidas globalmente, sino además *los argumentos* de la propia función. Es decir, durante la validación del cuerpo de la función, existen unas variables "especiales", que son justamente los argumentos, cuyos nombres sí pueden coincidir con los nombres de variables definidas anteriormente, pero no entre sí. + +Una solución rápida a este problema consiste en simplemente definir los argumentos cuyos identificadores sean nuevos (es decir, que no coincidan con una variable global), y al final de la validación, "des-definir" estos argumentos. Por un lado, esto implica adicionar un mecanismo para "des-definir", que es una operación que realmente no tiene un significado real en nuestra semántica. Además, es necesario llevar la cuenta de cuáles fueron los argumentos que se adicionaron al contexto para quitar solamente esos. Pero más importante que todos esos motivos, es el hecho de aunque un argumento tiene el mismo nombre de una variable en realidad es una variable distinta. Como ahora no estamos almacenando en el contexto nada adicional asociado a las variables, realmente esto no importa. Pero en el momento en que para cada variable querramos almacenar algo adicional, tenemos que hacer esta distinción. Por ejemplo, en algún momento vamos a querer ejecutar nuestro programa, y tendremos que asociar a cada variable y argumento un valor numérico concreto. + +Una solución mucho más elegante y extensible es introduciendo un nuevo concepto que llamaremos **ámbito** (*scope* en inglés). De manera general, un ámbito es una región de un programa donde están definidos ciertos símbolos (variables, funciones, etc.). Definimos entonces que entre ámbitos distintos puede haber coincidencias de nombres de símbolos, pero dentro del mismo ámbito no. Por ejemplo, podemos tener un ámbito distinto para cada función (básicamente una instancia de `IContext` distinta), y de esta forma nunca tendremos que preocuparnos por la colisión de nombres entre argumentos en diferentes funciones. + +Ahora, el otro problema a resolver, es que en el cuerpo de una función sí pueden aparecer referencias a variables definidas fuera de la función. De modo que nos sirve simplemente crear un nuevo `IContext` vacío y definir todos los argumentos ahí. Necesitamos que este `IContext` pueda resolver no solo lo que tiene definido explícitamente, sino todo aquello definido "afuera". Decimos entonces que este nuevo ámbito es "hijo" del ámbito global, de modo que puede sobre-escribir algunos símbolos, pero sigue teniendo acceso a todo lo definido anteriormente. + +En el caso actual solamente vamos a tener un ámbito global, y luego un ámbito por cada función; pero en lenguajes más complejos, es posible definir tantos ámbitos anidados como se desee (por ejemplo, en C# cada instrucción **for** crea un nuevo ámbito más interno). De modo que en general podemos pensar en los ámbitos también como una estructura árborea, donde existe un ámbito global, y luego se van creando ámbitos "hijo" según sea necesario. Este patrón de diseño es muy común en la mayoría de los lenguajes de programación existentes, por lo que vale la pena presentarlo aquí. Desde el punto de vista de diseño, simplemente necesitamos adicionar un método a nuestra **interface**: + +```cs +public interface IContext { + bool IsDefined(string variable); + bool IsDefined(string function, int args); + bool Define(string variable); + bool Define(string function, string[] args); + + IContext CreateChildContext(); // <- esto es lo nuevo +} +``` + +Sin embargo, desde el punto de implementación, ahora los métodos `IsDefined` deben modificarse para buscar no solo en el diccionario de símbolos del ámbito actual, sino recursivamente en el ámbito padre. Aunque esta implementación es sencilla, no es del todo trivial, por lo que vamos a mostrar una posible solución: + +```cs +public class Context : IContext { + IContext parent; + HashSet variables = new ... + Dictionary functions = new ... + + bool IsDefined(string variable) { + return variables.Contains(variables) || + (parent != null && parent.IsDefined(variable)); + } + + bool IsDefined(string function, int args) { + if (functions.ContainsKey(function) && + functions[function].Length == args) { + return true; + } + + return parent != null && parent.IsDefined(function, args); + } + + bool Define(string variable) { + return variables.Add(variable); + } + + bool Define(string function, string[] args) { + if (functions.ContainsKey(function) && + functions[function].Length == args) { + return false; + } + + functions[function] = args; + return true; + } + + IContext CreateChildContext() { + return new Context() { parent = this }; + } +} +``` + +Nuestra implementación de contexto nos garantiza que no es posible definir la misma variable o la misma función (con igual cantidad de argumentos) en un mismo contexto, pero sí nos permite sobreescribir los símbolos existentes en el contexto padre. Varios autores llaman a esta estructura de datos **tabla de símbolos**, ya que almacena todos los símbolos definidos en el programa. Nosotros le llamamos **contexto**, pues consideramos que es un nombre más general que da la idea de que en esta estructura se almacena la información dependiente del contexto que es útil para cada elemento semántico del programa. + +Haciendo uso de esta estructura, podemos entonces finalmente implementar la validación del nodo `DefFunc`: + +```cs +public class DefFunc : Expression { + public string Identifier; + public List Args; + public Expression Body; + + public override bool Validate(IContext context) { + var innerContext = context.CreateChildContext(); + + foreach(var arg in Args) { + innerContext.Define(arg); + } + + if (!Body.Validate(innerContext)) { + return false; + } + + if (!context.Define(Identifier, Args.ToArray())) { + return false; + } + + return true; + } +} +``` + +En este punto, ya tenemos toda la semántica de nuestro lenguaje validada, y solamente quedaría el problema de realmente ejecutar las instrucciones existentes. Siguiendo el mismo enfoque visto hasta ahora, podemos pensar en una solución que vaya recursivamente evaluando cada expresión, y almacenando en una especie de "contexto de ejecución" los valores de las expresiones definidas hasta el momento. Dado que no es posible redefinir variables, es totalmente válido calcular el valor de una variable tan pronto como se define, y almacenarlo. Para el caso de las funciones, lo más conveniente es almacenar directamente la expresión que se refiere al cuerpo de la función, para poder ejecutarla cuando sea necesario. En ese caso, un problema interesante de resolver es qué los argumentos de la función se definen en el nodo `DefFunc`, pero los valores que tendrán realmente solo se conocen en algún nodo `FuncCall`. Por lo tanto, en cada invocación, es necesario poder acceder al nodo `DefFunc` correspondiente para poder asignar los valores concretos que en esa invocación serán usados. Dejamos como sugerencia intentar implementar este mecanismo de evaluación. diff --git a/doc/content/chap5.pmd b/doc/content/chap5.pmd new file mode 100644 index 000000000..b604a7710 --- /dev/null +++ b/doc/content/chap5.pmd @@ -0,0 +1,808 @@ +--- +previous-chapter: chap4 +next-chapter: chap6 +--- + +# Gramáticas Atributadas + +Hasta el momento hemos visto como obtener un árbol de derivación de un lenguaje, y luego hemos presentado el árbol de sintaxis abstracta como una descripción más cómoda para realizar análisis semántico. Sin embargo, todavía no tenemos un mecanismo para construir un árbol de sintaxis abstracta a partir de un árbol de derivación. En principio, podemos pensar en estrategias *ad-hoc*, y para cada gramática particular escribir un algoritmo que construye el AST. De forma general estos algoritmos serán estrategias recursivas que irán recorriendo el árbol de derivación y computando fragmentos del AST a partir de los fragmentos obtenidos en los nodos hijos. En este capítulo veremos un esquema formal para describir esta clase de algoritmos, que además nos permitirá resolver varios problemas dependientes del contexto de forma elegante y sencilla. + +## Construyendo un AST + +Empecemos por mostrar, de forma intuitiva, como construir un AST para un árbol de derivación de una gramática conocida. Usaremos la gramática de expresiones aritméticas tan gastada: + + E -> E + T + | E - T + | T + + T -> T * F + | T / F + | F + + F -> ( E ) + | i + +Una posible jerarquía para el AST de esta gramática es la siguiente: + +```cs +public enum Op { Add, Sub, Mult, Div } + +public abstract class Expression : { + +} + +public class BinaryExpr : Expression { + public Op Operator; + public Expression Left; + public Expression Right +} + +public class Number : Expression { + public float Value; +} +``` + +Supongamos entonces que tenemos un árbol de derivación para una cadena particular. Recordemos que un árbol de derivación es una estructura donde en cada nodo hay un símbolo, y los hijos de dicho nodo coinciden exactamente con los símbolos de la parte derecha de la producción aplicada. Una posible definición de un árbol de derivación para esta gramática particular sería: + +```cs +public enum Symbol { E, T, add, sub, mult, div, i, left, right } + +public class Node { + public Symbol Symbol; + public List Children = new ... +} +``` + +Supongamos entonces que tenemos un algoritmo de parsing que nos devuelve este árbol de derivación (LR en este caso, dado la gramática que hemos definido). Queremos entonces adicionar un método `GetAST()` en la clase `Node` que nos devuelve un objeto de tipo `Expression`. + +```cs +public class Node { + // ... + + public Expression GetAST() { + // ... + } +} +``` + +De forma general hay 3 patrones distintos en la gramática que nos generan nodos semánticamente distintos en el árbol de derivación: + +* las producciones que derivan en una expresión binaria; +* las producciones que derivan en un solo no-terminal, incluyendo `F -> ( E )`; y +* el símbolo `i` que es el único terminal con una función semántica asociada. + +Cada uno de estos tipos de producciones genera un nodo particular del AST. Por lo tanto, nuestro código consiste en identificar en qué caso nos encontrarmos, y construir el nodo correspondiente. + +Si la producción es de la forma $X \to Y o Z$, donde $X$, $Y$ y $Z$ son símbolos y $o$ es un operador, creamos un nuevo nodo `BinaryExpr` con el operador adecuado, y los hijos se convierten recursivamente en las expresiones izquierda y derecha: + +```cs +public Expression GetAST() { + // X -> Y o Z + if (Children.Count == 3 && Children[1].Symbol >= 2) { + return new BinaryExpr() { + Left = Children[0].GetAST(), + Op = GetOperator(Children[1]), + Right = Children[2].GetAST() + }; + } +} +``` + +Si la producción es de la forma $X \to Y$, simplemente devolvemos la expresión hija. Notemos que en este caso el resultado que se produce es una "compactación" del árbol de derivación, eliminando las producciones de un solo símbolo: + +```cs +public Expression GetAST() { + // ... + // X -> Y + else if (Children.Count == 1) { + return Children[0].GetAST(); + } +} +``` + +Si la producción es particularmente `F -> ( E )` también devolvemos la expresión hija: + +```cs +public Expression GetAST() { + // ... + // F -> ( E ) + else if (Children.Count == 3 && Children[1].Symbol == Symbol.E) { + return Children[1].GetAST(); + } +} +``` + +Finalmente, cuando el nodo actual del árbol de derivación es una hoja, tiene que ser un nodo `i` y se crea la expresión unaria `Number`: + +```cs +public Expression GetAST() { + // ... + // i + else if (Children.Count == 0 && Symbol == Symbol.i) { + return new Number() { Value = /* valor del token */ }; + } + + throw new InvalidParseTreeException("xP"); +} +``` + +## Reglas y atributos semánticos + +Veamos nuevamente la implementación que hemos hecho para nuestra gramática de expresiones. De forma general, lo que hemos hecho ha sido intentar identificar qué producción concreta está representada en cada nodo, y según el caso, aplicar una regla que nos permite construir el fragmento de AST. Vamos a intentar generalizar este concepto de asociar reglas a producciones. Para ello, adicionaremos a cada símbolo de la gramática un conjunto de atributos, y a cada producción un conjunto de reglas que describen cómo se computan dichos atributos. Llamaremos a estas gramáticas: **gramáticas atributadas**: + +Una **gramática atributada** es una tupla $$, donde: + +* $G = $ es una gramática libre del contexto, +* $A$ es un conjunto de atributos de la forma $X \cdot a$ + donde $X \in N \cup T$ y $a$ es un identificador único entre todos los atributos del mismo símbolo, y +* $R$ es un conjunto de reglas de la forma $$ donde $p_i \in P$ es una producción $X \to Y_1, \ldots, Y_n$, y $r_i$ es una regla de la forma: + 1. $X \cdot a = f(Y_1 \cdot a_1, \ldots, Y_n \cdot a_n)$, o + 2. $Y_i \cdot a = f(X \cdot a_0, Y_1 \cdot a_1, \ldots, Y_n \cdot a_n)$. + + En el primer caso decimos que $a$ es un **atributo sintetizado**, y en el segundo caso, un **atributo heredado**. + + +Hablemos ahora sobre la notación. Aunque en la definición formal hemos especificado los atributos y reglas como elementos adicionales a la gramática, desde el punto de vista notacional es conveniente especificar las reglas y los atributos directamente asociados a la producción que corresponden: + + X -> YZ { X.a = f(Y.a, Z.a) } + +De este modo, tenemos una notación compacta, donde se puede reconocer a simple vista la gramática, los atributos, y las reglas. Por convenio llamamos a estas reglas, **reglas semánticas**, pues nos permiten definir de cierta forma la *función semántica* de cada producción. Consideraremos que los terminales tienen un conjunto de atributos cuyos valores son suministrados por el *lexer*. Cuando tenemos más de un símbolo con el mismo nombre, pondremos índices, por ejemplo: + +$X \to cX \{ X_0 \cdot a = f(X_1 \cdot a_1, c \cdot a_2 ) \}$ + +En realidad es necesario definir algunas restricciones adicionales sobre las reglas para que una gramática atributada sea consistente. En particular, necesitamos que no existan definiciones contradictorias de los atributos (es decir, no haya más de una regla que defina el mismo atributo en la misma producción, y que todo atributo sea o bien sintetizado, o bien heredado), y que todos los atributos estén bien definidos en cualquier árbol de derivación. A este último problema nos dedicaremos más adelante cuando nos preocupemos por la evaluación de los atributos. De momento simplemente digamos que necesitamos definir las reglas de forma que sean consistentes y completas. + +En esta definición no hemos especificado de qué naturaleza son los atributos o las reglas. De forma general, asumimos que los atributos son de tipos que sean convenientes computacionalmente: numéricos, conjuntos, diccionarios, listas, o incluso tipos complejos en un entorno orientado a objetos. Las reglas las consideraremos en general como funciones computables en algún sistema de cómputo. Cuando solo nos interese definir formalmente un lenguaje, emplearemos una notación matemática y funciones puras (sin efectos colaterales). + +Veamos entonces cómo redefinir la gramática de expresiones vista anteriormente para computar el AST. Usaremos la misma notación para definir árboles que hemos visto en la sección de *parsing* LR: un nodo de tipo $T$ cuyos hijos son los árboles $t_1, \ldots, t_n$ lo representaremos como $T(t_1, \ldots, t_n)$. Es decir, representaremos un árbol según el **recorrido en pre-orden** de sus nodos. Particularmente en esta gramática, usaremos las siguiente notación: + +* Un nodo terminal de tipo `Number` lo representaremos mediante el símbolo `n`. +* Un nodo no-terminal de tipo `BinaryExpr` lo representaremos según el tipo del operador, como `exp(op, e1, e2)` + +Definiremos un atributo de nombre `ast` en cada símbolo, que almacenará el árbol de sintaxis abstracta. La gramática nos quedaría entonces: + + E -> E + T { E0.ast = exp(+, E1.ast, T.ast) } + | E - T { E0.ast = exp(-, E1.ast, T.ast) } + | T { E0.ast = T.ast } + + T -> T * F { T0.ast = exp(*, T1.ast, F.ast) } + | T / F { T0.ast = exp(/, T1.ast, F.ast) } + | F { T0.ast = F.ast } + + F -> ( E ) { F.ast = E.ast } + | i { F.ast = n } + +Puede parecer que no hemos logrado mucho, más allá de formalizar en una notación una idea que ya sabíamos manejar. Y de alguna manera es cierto, lo que hemos hecho ha sido simplemente formalizar en una notación la idea intuitiva de cómo construir a partir de un árbol de derivación una representación más conveniente. La ventaja de tener esta notación formalizada, además de permitirnos razonar y comunicarnos al respecto, es que hemos simplificado considerablemente la cantidad de "código" a escribir para construir el AST. Hemos quitado del medio toda la sintaxis superflua de definición de métodos, parámetros, variables temporales, etc, y solamente hemos puesto en cada producción exactamente la "línea de código" que iría dentro del `if` correspondiente. De hecho, esta notación es tan conveniente, que la mayoría de los generadores de *parsers* usan una sintaxis similar para describir justamente cómo se construye el AST, y generan todo el engranaje de métodos recursivos, variables, paso de parámetros y demás que son necesarios para hacer funcionar este mecanismo. + +## Resolviendo dependencias del contexto + +En nuestra definición de gramática atributada no hemos dicho nada del AST. Aunque en la práctica usamos los atributos la mayoría de las veces para construir el AST, y luego resolver los problemas dependientes del contexto sobre el AST, en ocasiones es conveniente resolver algunos de estos problemas directamente empleando el mecanismo de gramática atributada. Esto tiene sentido sobre todo si estamos construyendo lenguajes pequeños, con pocas reglas semánticas y no queremos diseñar una jerarquía de AST independiente. + +Por ejemplo, tomemos el lenguaje dependiente del contexto canónico $L = a^n b^n c^n$, y veamos como podemos describir mediante una gramática atributada los predicados semánticos que definen este lenguaje. Comenzamos por la gramática: + + S -> ABC + A -> aA | epsilon + B -> bB | epsilon + C -> cC | epsilon + +Como convenio, vamos a definir un atributos `S.ok` cuyo valor será `true` si y solo si la cadena reconocida pertenece al lenguaje. En cada no terminal vamos a definir un atributo `cnt` que almacenará la cantidad de veces que este no terminal ha derivado en el terminal correspondiente. De modo que en cada producción de `A`, `B` o `C`, iremos "contando" la cantidad de `a`, `b` o `c` que se van produciendo, y luego en `S` determinaremos si la cadena es correcta. Vamos a usar para la definición de las reglas una notación más parecida a un lenguaje de programación convencional: + + S -> ABC { S.ok = (A.cnt == B.cnt && B.cnt == C.cnt) } + A -> aA { A0.cnt = 1 + A1.cnt } + | epsilon { A.cnt = 0 } + B -> bB { B0.cnt = 1 + B1.cnt } + | epsilon { B.cnt = 0 } + C -> cC { C0.cnt = 1 + C1.cnt } + | epsilon { C.cnt = 0 } + +En este punto hemos definido una gramática con atributos que reconoce todas las cadenas de la forma $a^*b^*c^*$, pero para las cuales el valor del atributo `S.ok` es `true` solamente en las cadenas exactamente de la forma $a^n b^n c^n$. La forma de resolverlo ha sido definir una gramática libre del contexto, y hemos adicionado la dependencia del contexto en forma de reglas semánticas. Si observamos la gramática definida, notaremos que nos hemos conformado con reconocer solamente la parte regular del lenguaje, y hemos dejado todo el resto del problema a las reglas semánticas. Un enfoque alternativo consiste en intentar resolver en el análisis sintáctico tanto como sea posible. + +Por ejemplo, podemos reconocer $a^n b^n c^*$, en la gramática, y luego solamente verificar la correspondencia entre la cantidad de `b` y la cantidad de `c`. Comencemos por definir una gramática libre del contexto para esto: + + S -> XC + X -> aXb | epsilon + C -> cC | epsilon + +Almacenaremos entonces en `X.cnt` la cantidad de `b` que aparecen, y luego lo compararemos con `C.cnt`: + + S -> XC { S.ok = (X.cnt == B.cnt) } + X -> aXb { X0.cnt = 1 + X1.cnt } + | epsilon { X.cnt = 0 } + C -> cC { C0.cnt = 1 + C1.cnt } + | epsilon { C.cnt = 0 } + +La pregunta es por supuesto, entre estas dos alternativas, cuál es mejor. Y como casi siempre la respuesta será que depende de qué queremos lograr. Por un lado, una gramática más simple es más fácil de leer y entender, y (en ocasiones) más fácil de parsear. En ese caso la mayor carga queda en la fase semántica, que generalmente es más compleja y tiene un costo computacional mayor. Por otro lado, si la gramática es más compleja, pero captura una mayor cantidad de propiedades del lenguaje, es posible reconocer una mayor cantidad de errores en la fase sintáctica, y probablemente se obtenga un compilador más eficiente. Sin embargo, estas gramáticas son más complejas, y por tanto más difíciles de entender. + +Otro factor a tener en cuenta, desde el punto de vista de la ingeniería de software, es la *mantenibilidad* del compilador. En general, es más difícil hacer cambios en las primeras fases, pues es más probable que un cambio en la gramática o en el *lexer* provoquen una disrupción en las fases siguientes. En cambio, por la propia naturaleza de la programación orientada a objetos, con un buen diseño es posible lograr que los cambios en la fase semántica sean lo menos disruptores posibles. Por este motivo, es conveniente definir bien temprano una gramática lo más sencilla posible que englobe todas las propiedades sintácticas del lenguaje en cuestión, y dejar para la fase semántica toda propiedad cuyo significado o implementación tenga una alta probabilidad de variar. + +## Computando el valor de los atributos + +Una vez definida una gramática atributada, nos queda pendiente el problema de cómo evaluar las reglas semánticas para asignar el valor correcto a los atributos. Como es de esperar, esta evaluación la vamos a realizar una vez construido el árbol de derivación de una cadena particular. De forma general, podemos tener en cualquier nodo tanto atributos sintetizados como atributos heredados. Necesitamos entonces encontrar un orden para evaluar los atributos que garantice que siempre sea posible evaluar las reglas correspondientes. Para esto, necesitamos saber las *dependencias* de cada atributo en una regla particular, es decir, cuales son los otros atributos que es necesario haber evaluado antes. Intuitivamente, estas dependencias son justamente los atributos usados dentro de la función $f$ en la regla semántica. + +Tomemos entonces a modo de ejemplo la cadena `aabbcc` y veamos un árbol de derivación para la gramática atributada definida anteriormente: + +```tree + S + / | \ + A B C + /| / \ |\ + a A b B c C + /| /| /| + a A b B c C + | | | + e e e +``` + +Vamos entonces a construir sobre este árbol de derivación un *grafo de dependencia* de los atributos asociados. Este grafo se construye de la siguiente forma: + +* Los nodos son los atributos de cada símbolo en cada nodo del árbol de derivación +* Existe una arista dirigida entre un par de nodos $v \to w$ del grafo de dependencia, si los atributos correspondientes participan en una regla semántica definida en la producción asociada al nodo del árbol de derivación donde aparece $w$, de la forma $w = f(\ldots, v, \ldots)$. Es decir, si el atributo $w$ *depende* del atributo $v$. + +Veamos entonces como quedaría el árbol anterior, una vez señaladas las dependencias entre los atributos. Para simplificar la notación, vamos a representar solamente las aristas del grafo de dependencias, y no las del árbol de derivación en sí.: + + --> S.ok <-- + | ^ | + | | | + A.cnt B.cnt C.cnt + ^ ^ ^ + | | | + a A.cnt b B.cnt c C.cnt + ^ ^ ^ + | | | + a A.cnt b B.cnt c C.cnt + + e e e + +La propiedad más interesante de este grafo de dependencias es que nos dice, en primer lugar, si existe una forma de evaluar los atributos, y en caso de ser posible, nos da un orden para la evaluación. Si existe algún ciclo en este grafo de dependencias, evidentemente no podremos evaluar los atributos que participan en el ciclo. Por lo tanto, decimos que la gramática es evaluable si y solo si el grafo de dependencias es acíclico, es decir, un DAG. En este caso, la evaluación se realiza siguiendo algún *orden topológico* del grafo de dependencia. + +En el caso anterior, nuestro grafo de dependencias es justamente un árbol, donde todas las aristas están orientadas de un hijo a un padre en el AST. Esto sucede cada vez que en una gramática todos los atributos son *sintetizados*. Evidentemente, en este caso es posible evaluar siempre los atributos de un nodo padre, una vez evaluados todos los atributos de los hijos. A este tipo de gramática les llamaremos **gramáticas s-atributadas** (la *s* viene de *sintetizado*). Este tipo de gramáticas son las más sencillas de evaluar, y también las más comunes. En general cuando estamos definiendo el AST nos saldrán casi siempre atributos sintetizados, pues como lo que queremos construir es un árbol, es natural que definamos los atributos en este orden. La buena noticia con las gramáticas s-atributadas, es que siempre es posible evaluar los atributos (en todo árbol de derivación), y esto siempre será con un recorrido en post-orden. Formalmente: + +> Una gramática atributada es **s-atributada** si y solo si, para toda regla $r_i$ asociada a una producción $X \to Y_1, \ldots, Y_n$, se cumple que $r_i$ es de la forma $X \cdot a = f(Y_1 \cdot a_1, \ldots, Y_n \cdot a_n)$. + +Para evaluar los atributos en una gramática s-atributada, podemos seguir una estrategia como la siguiente. Asumiremos que durante la construcción del árbol de derivación, el *parser* introduce en cada nodo una lista de todas las reglas semánticas asociadas a dicha producción, y que los atributos están definidos en cada símbolo. + +```cs +public class Node { + public Symbol Symbol; + public List Children; + public List Rules; + + public void EvaluateSynthesized() { + foreach(var node in Children) + node.EvaluateSynthesized(); + + foreach(var rule in Rules) + rule.evaluate(Symbol, Children); + } +} +``` + +Veamos entonces otro caso un poco más general, donde también podemos decir de antemano que la gramática es evaluable. Este es el caso cuando todo atributo es, o bien sintetizado, o si es heredado, solo depende de atributos de símbolos que le anteceden en la producción. Es decir, si tenemos una regla $Y_i \cdot a_i = f(X \cdot a, Y_1 \cdot a_1, \ldots, Y_{i-1} \cdot a_{i-1})$. A estas gramáticas las llamaremos **gramáticas l-atributadas** (donde *l* viene de *left*), ya que todo atributo depende solo de atributos que se evalúan antes en el pre-orden. En este caso, también podemos siempre evaluar la gramática haciendo un recorrido en profundidad, aunque es un poco más complicado que para el caso anterior. En cada llamado recursivo, primero evaluaremos los atributos heredados, pues solo dependen de atributos en los hermanos anteriores y el padre. Luego descendemos recursivamente en cada hijo, y al retornar, evaluamos los atributos sintetizados en el nodo actual. Formalizando: + +> Una gramática atributada es **l-atributada** si y solo si toda regla $r_i$ asociada a una producción $X \to Y_1, \ldots, Y_n$ es de una de las siguientes formas: +> 1. $X \cdot a = f(Y_1 \cdot a_1, \ldots, Y_n \cdot a_n)$, ó +> 2. $Y_i \cdot a_i = f(X \cdot a, Y_1 \cdot a_1, \ldots, Y_{i-1} \cdot a_{i-1})$. + +Y un ejemplo de cómo evaluar los atributos, suponiendo que el *parser* es capaz de suministrar en par de listas separadas aquellas reglas que sintetizan atributos de las que los heredan. Supongamos que cada nodo recibe además una referencia al nodo padre en el árbol de derivación (para poder acceder a los hermanos). En el nodo raíz simplemente pasaremos `null` como padre: + +```cs +public class Node { + public Symbol Symbol; + public List Children; + public List SyntethicRules; + public List InheritedRules; + + private void EvaluateInherited(Node parent) { + foreach(var rule in InheritedRules) + rule.evaluate(Symbol, parent, parent.Children); + + foreach(var node in Children) + node.EvaluateInherited(this); + + foreach(var rule in SyntheticRules) + rule.evaluate(Symbol, Children); + } +} +``` + +## Evaluando atributos durante el proceso de *parsing* descendente + +Cabe preguntarnos entonces sino es posible evaluar las reglas semánticas a medida que se realiza el proceso de parsing. Intuitivamente, al menos para las gramáticas s-atributadas y l-atributadas esto debe ser posible, pues existe un orden claro de dependencia entre los atributos. Por supuesto, esto dependerá también del algoritmo de *parsing* empleado. + +Por ejemplo, para gramáticas LL, si estamos empleando un algoritmo recursivo descendente, el orden en que se construye el árbol de derivación es exactamente el mismo que el orden de evaluación de una gramática l-atributada. Tomemos como ejemplo la gramática LL(1) de expresiones aritméticas que hemos visto anteriormente: + + E -> T X + T -> i Y | ( E ) + X -> + E | - E | epsilon + Y -> * T | / T | epsilon + + Como hemos visto anteriormente, los árboles de derivación que salen de esta gramática son bastante complicados. Vamos a intentar escribir un conjunto de reglas semánticas que nos calculen directamente el valor de la expresión durante el proceso de parsing. El problema radica en que cuando tenemos la producción `E -> T X`, no sabemos en este punto si la operación a realizar es una suma o una resta. Es solo cuando vemos la producción en que derivó `X` que podemos decidir que operación hacer. Sin embargo, en la producción `X -> + E`, por ejemplo, ya no tenemos el valor de `T` disponible para hacer el cálculo. De modo que tenemos que "pasar" el valor de `T` a `X` en la producción `E -> T X`, para que luego `X` pueda decidir que hacer con este valor. + + Vamos a definir entonces 3 atributos diferentes, de tipo numérico. En primer lugar, el atributo `i.val`, suministrado por el *lexer*, que contiene el valor numérico del token. Tendremos además los atributos `E.sval`, `T.sval`, `X.sval` y `Y.sval`, que son respectivamente los valores de las expresiones aritméticas representadas en cada caso. Los hemos llamado con el prefijo `s` justamente porque estos atributos serán *sintetizados*. Finalmente, vamos a tener los atributos `X.hval` y `Y.hval` que contendrán los valores de las expresiones a la izquierda de `X` o `Y` y son atributos *heredados*. + + Una vez definidos estos atributos, veamos algunas ideas sobre cómo computarlos. Algunos casos bases son fáciles, por ejemplo para `T -> ( E )` simplemente tenemos que "subir" el valor de `E.sval` a `T.sval`. Por otro lado, tomemos por ejemplo la producción `E -> T X`. Sabemos que en `T` tenemos un atributo sintetizado con el valor numérico de lo que sea que haya sido reconocido como `T` por ese lado. Sin embargo, aún no sabemos si sumarlo o restarlo con lo que resta. La estrategia en este caso será "pasar" este valor computado hasta el momento a `X` (por medio del atributo `X.hval`), y luego pedirle a `X` que compute el valor `X.sval` como la suma (o resta) del valor heredado de `T` y lo que sea que `X` en sí haya parseado. Es decir, primero "bajaremos" el valor de `T` hacia `X`, sumando o restando según el caso, hasta llegar a las hojas (donde `X -> epsilon`). En este punto, lo que sea que tengamos acumulado lo "subiremos" hacia la raíz (por medio de `X.sval`). + +Veamos entonces toda la lista de reglas semánticas: + + E -> T X { X.hval = T.sval, E.sval = X.sval } + T -> i Y { Y.hval = i.val, T.sval = Y.sval } + | ( E ) { T.sval = E.sval } + X -> + E { X.sval = X.hval + E.sval } + | - E { X.sval = X.hval - E.sval } + | epsilon { X.sval = X.hval } + Y -> * T { Y.sval = Y.hval * T.sval } + | / T { Y.sval = Y.hval / T.sval } + | epsilon { Y.sval = Y.hval } + +Intentemos ahora parsear una cadena, a la vez que vamos evaluando los atributos. Vamos a representar por un lado la cadena que vamos parseando, y por otro lado la pila de "llamados" recursivos que se va formando con cada llamado del *parser* recursivo descedente asociado a esta gramática. En cada "llamado" recursivo reprsentaremos también el valor de cada atributo en la forma `S[attr=val]` (un `.` significa que el valor aún no ha sido calculado). Comenzamos por la cadena completa, y el llamado al símbolo `E`. Una advertencia para los débiles de espíritu, cualquiera que haya almorzado recientemente debería saltar al siguiente capítulo... + + |i{2} * ( i{5} - i{3} ) + + E[sval=.] + +En el primer paso, como `E` solo deriva en `T X`, no queda otra que llamar a `T`. Vamos a representar también el llamado a `X` para no olvidar que al retornar `T` debemos descender recursivamente por `X`. + + |i{2} * ( i{5} - i{3} ) + + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Ahora, mirando el token `i` y los $First$ de cada producción, aplicamos `T -> i Y`: + + |i{2} * ( i{5} - i{3} ) + + i[val=.] , Y[sval=.,hval=.] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Podemos entonces reconocer `i` y asociar el valor adecuado al atributo: + + i{2}|* ( i{5} - i{3} ) + + i[val=2] , Y[sval=.,hval=.] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Al retornar de `i` a `T`, como tenemos ya en `i` el valor asociado al token, aplicamos la regla semántica correspondiente a `Y`: + + i{2}|* ( i{5} - i{3} ) + + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Procedemos entonces expandir el símbolo `Y`: + + i{2}|* ( i{5} - i{3} ) + + *[] , T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +En este punto solo es necesario reconocer el token `*`, y luego descendemos recursivamente por `T`, pero esta vez por la producción `( E )`: + + i{2} *|( i{5} - i{3} ) + + ([], E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Avanzamos el siguiente token: + + i{2} * (|i{5} - i{3} ) + + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y ahora volvemos a descender recursivamente: + + i{2} * (|i{5} - i{3} ) + + T[sval=.] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y luego: + + i{2} * (|i{5} - i{3} ) + + i[val=.] , Y[sval=.,hval=.] + T[sval=.] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Reconocemos `i`: + + i{2} * ( i{5}|- i{3} ) + + i[val=5] , Y[sval=.,hval=.] + T[sval=.] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y retornamos recursivamente poniendo el valor de `i` en el atributo `hval` de Y: + + i{2} * ( i{5}|- i{3} ) + + Y[sval=.,hval=5] + T[sval=.] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Dado que `-` está en el $Follow(Y)$, aplicamos `Y -> epsilon`, y aquí veremos la magia de las gramáticas atributadas actuando, pues el valor de `hval` pasa a `sval` justo antes de retornar: + + i{2} * ( i{5}|- i{3} ) + + Y[sval=5,hval=5] + T[sval=.] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y ahora al retornar aplicamos la regla semántica en `X` que "sube" el valor de `Y.sval`: + + i{2} * ( i{5}|- i{3} ) + + T[sval=5] , X[sval=.,hval=.] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Una vez parseado `T`, antes de retornar, pasamos su valor a `hval` de `X`: + + i{2} * ( i{5}|- i{3} ) + + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Expandimos entonces la producción `X -> - E`: + + i{2} * ( i{5}|- i{3} ) + + -[], E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Avanzamos el siguiente token y expandimos: + + i{2} * ( i{5} -|i{3} ) + + T[sval=.], X[sval=.,hval=.] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Nuevamente, expandimos `T -> i Y` (ya esto se está volviendo un poquito repetitivo...): + + i{2} * ( i{5} -|i{3} ) + + i[val=.], Y[sval=.,hval=.] + T[sval=.], X[sval=.,hval=.] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y de nuevo hacemos la secuencia de `match` y paso de valor de `i` para `Y`: + + i{2} * ( i{5} - i{3}|) + + Y[sval=.,hval=3] + T[sval=.], X[sval=.,hval=.] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Ahora vendrá una cascada de evaluaciones y reducciones a $\epsilon$ que disfrutaremos en cámara lenta. Primero, pasamos el valor `Y.hval` para `Y.sval`: + + i{2} * ( i{5} - i{3}|) + + Y[sval=3,hval=3] + T[sval=.], X[sval=.,hval=.] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Al retornar `Y`, sintetizamos el valor de `T.sval`: + + i{2} * ( i{5} - i{3}|) + + T[sval=3], X[sval=.,hval=.] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y lo pasamos para `X.hval`: + + i{2} * ( i{5} - i{3}|) + + X[sval=.,hval=3] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Como `)` está en el $Follow(X)$, solo queda pasar el valor `X.hval` para `X.sval`: + + i{2} * ( i{5} - i{3}|) + + X[sval=3,hval=3] + E[sval=.] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y al retornar felizmente este valor va para `E.sval`: + + i{2} * ( i{5} - i{3}|) + + E[sval=3] + X[sval=.,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Ahora se está poniendo interesante la pila. En el tope tenemos a `E[sval=3]` que debe retornar para `X`. Recordemos que esta producción era justamente `X -> - E`, por lo que al retornar `E` se aplica la regla semántica que computa, por primera vez, la operación resta! LoL! Siguiendo esta regla, tenemos que hacer `X.sval` igual a `X.hval - E.sval`. + + i{2} * ( i{5} - i{3}|) + + X[sval=2,hval=5] + E[sval=.], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Retornamos entonces "subiendo" el valor de `X.sval`: + + i{2} * ( i{5} - i{3}|) + + E[sval=2], )[] + T[sval=.] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y ahora al retornar `E`, justo antes de llamar a `match`, "subimos" a `T` el valor correspondiente: + + i{2} * ( i{5} - i{3}|) + + )[] + T[sval=2] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Luego avanzamos al último token que nos queda de la cadena de entrada: + + i{2} * ( i{5} - i{3} )| + + T[sval=2] + Y[sval=.,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +Y ahora vuelve a producirse otro paso mágico, pues `Y` al retornar `T` realiza la tan esperada operación de multiplicación! + + i{2} * ( i{5} - i{3} )| + + Y[sval=4,hval=2] + T[sval=.] , X[sval=.,hval=.] + E[sval=.] + +El retorno de `Y` es recibido de buena gana por `T`: + + i{2} * ( i{5} - i{3} )| + + T[sval=4] , X[sval=.,hval=.] + E[sval=.] + +Que estaba esperando solo para pasarle este valor a `X`: + + i{2} * ( i{5} - i{3} )| + + X[sval=.,hval=4] + E[sval=.] + +Ahora `X`, sin nada más que hacer, debe expandirse en $\epsilon$, pero antes, computará el valor de su atributo `X.sval`: + + i{2} * ( i{5} - i{3} )| + + X[sval=4,hval=4] + E[sval=.] + +Y lo devuelve con gracia a `E`: + + i{2} * ( i{5} - i{3} )| + + E[sval=4] + +De modo que hemos terminado de parsear la cadena, y no solo hemos reconocido su bien merecida pertenencia al lenguaje, sino que además nos la hemos ingeniado para obtener, a la misma vez, el valor ya computado de la expresión aritmética! xD. + +Si parece que hemos tenido que hacer malabares para calcular el valor de la expresión, intentemos pensar en el código equivalente que realiza esta misma evaluación sobre el árbol de derivación ya creado. Hemos definido un mecanismo formal para expresar el cómputo de atributos sobre un árbol de derivación, que nos ha permitido expresar fácilmente la evaluación de la expresión aritmética, sin tener que lidiar con todos los detalles de implementación, paso de parámetros, etc. De hecho, este mecanismo es tan formal, que lo hemos ejecutado de forma mecánica, sin pararnos a razonar, solamente siguiendo a ciegas las reglas semánticas, ¡y ha funcionado! + +## Evaluando atributos durante el proceso de *parsing* ascendente + +Antes de terminar, para aquellos que no quedaron satisfechos con la sección anterior, pues tenemos más... Vamos a realizar un proceso similar, pero esta vez sobre una gramática LR. En este tipo de gramáticas, tenemos que pagar un precio a la hora de definir atributos, pues solamente podemos evaluarlos durante el proceso de parsing si todos los atributos son sintetizados. Intuitivamente, esto es cierto ya que en la pila de símbolos nunca tendremos a un "padre" antes que a un "hijo", debido a la naturaleza *bottom-up* del proceso de *parsing*. Por tanto, los atributos del símbolo "padre" solamente pueden depender de los atributos de sus "hijos", y nunca de su propio "padre". Por otro lado, como se construye el árbol de derivación extrema derecha, tampoco pueden depender de los atributos de los hermanos. + +El proceso de evaluación general funcionará de la siguiente manera. Cada vez que se introduce un símbolo en la pila, computaremos el valor de todos sus atributos, a partir de los símbolos hijo que acabamos de sacar de la pila. Los tokens entran a la pila con sus atributos ya evaluados por el *lexer*. + +Con esto en mente, vamos a definir entonces la gramática LR de expresiones aritméticas con un único atributo sintetizado `val` en cada nodo. En el proceso de *parsing* ascendente, iremos computando los valores correspondientes a partir de los valores de los hijos. Las reglas semánticas que nos quedan son bastante intuitivas, y no requieren de mayor explicación: + + E -> E + T { E0.val = E1.val + T.val } + | E - T { E0.val = E1.val - T.val } + | T { E0.val = T.val } + T -> T * F { T0.val = T1.val * F.val } + | T / F { T0.val = T1.val / F.val } + | F { T0.val = F.val } + F -> i { F.val = i.val } + | ( E ) { F.val = E.val } + +Vamos entonces a representar para esta gramática en la pila de símbolos además los valores de los atributos, y la cadena de entrada como siempre: + + |i{2} * ( i{5} - i{3} ) + | + +No vamos a mostrar aquí la tabla LR, ya que para esta gramática es bastante intuitivo que operación realizar en cada caso. Por tanto nos ahorraremos especificar exactamente en qué estado nos encontramos, y simplemente asumiremos que automáta LR funciona. Comenzamos entonces por introducir `i` en la pila, y calculamos el valor correspondiente (que viene en el token): + + i{2}|* ( i{5} - i{3} ) + i[val=2]| + +En este punto podemos reducir `F -> i`, y calcular el valor correspondiente: + + i{2}|* ( i{5} - i{3} ) + F[val=2]| + +Seguimos teniendo un *handle*, así que volvemos a reducir: + + i{2}|* ( i{5} - i{3} ) + T[val=2]| + +El siguiente paso es un **shift** (pues no hay `*` en el $Follow(E)$): + + i{2} *|( i{5} - i{3} ) + T[val=2] *| + +Y el siguiente: + + i{2} * (|i{5} - i{3} ) + T[val=2] * (| + +Y el siguiente: + + i{2} * ( i{5}|- i{3} ) + T[val=2] * ( i[val=5]| + +Podemos entonces reducir nuevamente (subiendo el valor del atributo): + + i{2} * ( i{5}|- i{3} ) + T[val=2] * ( F[val=5]| + +Y de nuevo: + + i{2} * ( i{5}|- i{3} ) + T[val=2] * ( T[val=5]| + +Y de nuevo: + + i{2} * ( i{5}|- i{3} ) + T[val=2] * ( E[val=5]| + +Seguimos entrando en la pila: + + i{2} * ( i{5} -|i{3} ) + T[val=2] * ( E[val=5] -| + +Y el siguiente: + + i{2} * ( i{5} - i{3}|) + T[val=2] * ( E[val=5] - i[val=3]| + +Y ahora vamos a reducir a `F -> i` de nuevo: + + i{2} * ( i{5} - i{3}|) + T[val=2] * ( E[val=5] - F[val=3]| + +Y a `T -> F`: + + i{2} * ( i{5} - i{3}|) + T[val=2] * ( E[val=5] - T[val=3]| + +Y ahora podemos reducir `E -> E - T` y aplicar la regla semántica que computa la resta: + + i{2} * ( i{5} - i{3}|) + T[val=2] * ( E[val=2]| + +Luego no nos queda otra opción que hacer **shift** por última vez: + + i{2} * ( i{5} - i{3} )| + T[val=2] * ( E[val=2] )| + +Y ahora, como es de esperar, reducimos `F -> ( E )` quedándonos con el valor almacenado: + + i{2} * ( i{5} - i{3} )| + T[val=2] * F[val=2]| + +Luego reducimos `T -> T * F` computando el valor correspondiente: + + i{2} * ( i{5} - i{3} )| + T[val=4]| + +Y por último `E -> T`, dejando en la pila el símbolo inicial, y teniendo computado el valor asociado al atributo `val`: + + i{2} * ( i{5} - i{3} )| + E[val=4]| + +Como hemos podido ver, el proceso de *parsing* LR es bastante más sencillo (una vez computada la tabla, claro), y además más poderoso en términos de las gramáticas que puede reconocer que el *parsing* LL. Sin embargo, desde el punto de vista de los atributos, el *parsing* LR nos obliga a definir todos nuestros atributos de forma sintetizada, lo que reduce el poder expresivo de las gramáticas atributadas. En la práctica, sin embargo, este es el tipo de *parser* más utilizado, y las reglas semánticas que queremos expresar son lo suficientemente amables como para contentarnos con gramáticas s-atributadas. + +## El proceso de *parsing* completo + +Hemos visto entonces los conceptos fundamentales que nos permiten llegar desde una cadena, hasta un árbol de sintaxis abstracta. De forma general, el proceso completo es el siguiente: + +* Definimos una gramática libre del contexto que capture las propiedades sintácticas del lenguaje, de la forma más "natural" posible (con la menor cantidad de producciones "superfluas"). +* Diseñamos un árbol de sintaxis abstracta con los tipos de nodos que representan exactamente las funciones semánticas de nuestro lenguaje. +* Definimos las reglas semánticas que construyen el árbol de sintaxis abstracta, preferiblemente quedando una gramática s-atributada. +* Construimos un *lexer* a partir de las expresiones regulares que definen a los tokens. +* Construimos un *parser*, idealmente LALR (o LR si no es posible) que además de reconocer la cadena, nos evalúe y construya el AST durante el proceso de *parsing*. +* Implementamos los predicados semánticos restantes sobre el AST construido. + +Este proceso está tan bien estudiado, que la mayoría de los generadores de *parser* existentes automatizan toda esta parte. A partir de una gramática libre del contexto con reglas semánticas, y una jerarquía de nodos del AST, estos generadores de *parsers* son capaces de construir el autómata LR y devolvernos directamente el AST instanciado. Contar con herramientas de este tipo nos permite iterar muy rápidamente sobre el lenguaje, modificando la gramática o el AST de forma independiente, ya que el único punto de acoplamiento son las reglas semánticas. Por este motivo es preferible tener gramáticas más sencillas, y dejar para la fase semántica la mayor cantidad de problemas. + +De modo que prácticamente toda la complejidad de diseñar un lenguaje radica en definir correctamente las funciones semánticas, e implementar la fase de chequeo semántico. De hecho, en los últimos años, casi toda la investigación sobre *parsing* se ha movido a lenguajes ambigüos o lenguaje natural, y la investigación en temas de compilación puros se ha concentrado en implementar funciones semánticas más complejas. En los capítulos siguientes nos concentraremos en problemas típicos del análisis semántico, y veremos estructuras de datos y estrategias para su implementación. diff --git a/doc/content/chap6.pmd b/doc/content/chap6.pmd new file mode 100644 index 000000000..62b916860 --- /dev/null +++ b/doc/content/chap6.pmd @@ -0,0 +1,446 @@ +--- +previous-chapter: chap5 +next-chapter: chap7 +--- + +# Semántica de Tipos {#semantics} + +En la mayoría de los lenguajes de programación modernos existe el concepto de "tipo". De manera informal, diremos que un tipo es una definición de especifica cuáles operaciones son válidas a realizar sobre un objeto particular. Un objeto en este caso puede ser un valor simple (`int` o `bool` en los lenguajes tipo C), o un objeto compuesto en algún lenguaje orientado a objetos. El paradigma **orientado a objetos** ha venido a convertirse en los últimos años en una de las columnas fundamentales del diseño y la investigación de nuevos lenguajes de programación. En este paradigma, cada "valor" que se puede manipulado en un programa es un *objeto*, y los objetos pueden agruparse para definir objetos más complejos. A cada objeto se le asocia un *tipo*, que define las operaciones válidas a realizar sobre dicho objeto. + +La implementación más usual del concepto de tipo es una **clase**. Una clase (en C, C++, C#, Java, Python, Ruby, y tantos otros lenguajes orientados a objetos) es fundamentalmente una definición de las operaciones disponibles para un tipo. En general las clases permiten definir *atributos* que almacenan un valor, y *métodos* (o *funciones*) que permiten realizar una serie de operaciones (con o sin efectos colaterales) sobre el tipo en cuestión y los *argumentos* del método. A todos estos lenguajes los llamados *lenguajes tipados*, porque manejan el concepto de tipo. De forma general, si la operación `f(x)` (o `x.f()`) es válida en algunos contextos, e inválida en otros, aunque en ambos casos `f` y `x` son símbolos definidos, entonces diremos que dicho lenguaje es tipado, pues la validez de una operación no solo depende de que estén definidos los símbolos que participan, sino de **cómo** están definidos dichos símbolos. Un ejemplo de lenguaje no tipado es el lenguaje para expresiones que definimos en la sección *[Diseño de un AST]*. + +Una forma usual de clasificar a los lenguajes tipados es la distinción entre tipado *dinámico* y *estático*. En ambos casos cada expresión, variable y método tiene asociado un tipo que define las operaciones válidas. La diferencia fundamental radica en que en los lenguajes con tipado estático, además existe una *declaración explícita* del tipo que deseamos para una expresión, variable, método, etc. Esto lo hacemos con la esperanza de poder capturar en la fase de chequeo semántico la mayor cantidad de errores asociados a inconsistencias de tipos posibles. En los lenguajes con tipado dinámico las inconsistencias de tipos no pasan desapercibidas, simplemente se espera hasta la ejecución para detectarlas. + +En general, la discusión entre si es preferible el tipado estático o dinámico es futil. En muchas ocasiones, es conveniente tener lo antes posible una validación de que la expresión que queremos compilar no tendrá inconsistencias de tipos, y por este motivo surgieron los lenguajes con tipado estático. Por otro lado, es inevitable que existan circunstancias en las que el compilador será incapaz de inferir exactamente el tipo real que tendrá una expresión y nos impedirá realizar alguna operación cuando en realidad dicha operación sería posible. Por ejemplo, si tenemos la siguiente declaración de clases en C#: + +```cs +class A { + public void F() { /* ... */ } +} + +class B : A { + public void G() { /* ... */ } +} +``` + +El siguiente fragmento código da error de compilación pues el tipo declarado para la variable `a` es `A`, donde no está definida la operación `G`, aunque sabemos que en caso de ejecutar, no existiría realmente ningún error de inconsistencia de tipos, pues el tipo real del objeto almancenado en `a` es `B`: + +```cs +A a = new B(); +a.G(); +``` + +Por analogía, le llamaremos *tipo estático* al tipo declarado de una variable, atributo, método, o cualquier construcción sintáctica que almacene o produzca un valor, y *tipo dinámico* al tipo asociado a dicho valor durante la ejecución del programa. Es decir, en el caso anterior, `a` es una variable con tipo estático `A`, pero que en tiempo de ejecución almacena un objeto cuyo tipo dinámico es `B`. Más adelante podremos formalizar esta noción. + +En esta sección nos dedicaremos entonces a construir un **verificador de tipos**, que nos es más que un algoritmo que nos dirá si todos los usos de tipos en nuestro AST son consistentes. Idealmente, queremos que nuestro verificador de tipos nos permita decidir exactamente cuáles programas hacen un uso consistente de los tipos, pero como hemos visto en el ejemplo anterior, en ocasiones es imposible determinar exactamente cuál será el tipo dinámico de una expresión en tiempo de ejecución. En estos caso, generalmente preferimos errar por exceso, es decir, evitar la ejecución de aquellos programas donde *podría* existir una inconsistencia de tipos, aunque en la realidad no suceda. Cuando un verificador de tipos cumple esta propiedad, decimos que es *consistente*. Es decir, un verificador consistente detecta todos los programas con errores de tipo, aunque puede decidir erróneamente que un programa correcto es incorrecto. Por supuesto, queremos reducir al mínimo posible este segundo caso. + +En los lenguajes tipados es muy común que se permita construir *jerarquías de tipos*. Estas jeraquías se construyen mediante una operación, denominada generalmente **herencia**, que define que un tipo `B` es un *subtipo* del tipo `A`. La semántica exacta de la herencia varía de lenguaje en lenguaje, pero en general significa que todas las operaciones definidas para `A` también lo están para `B`, aunque `B` puede introducir nuevas operaciones (métodos, atributos, etc.), o *sobrescribir* la implementación de algunas de las operaciones definidas en `A`. + +Esta sobrescritura generalmente se asocia al nombre de **polimorfismo**, que para nuestro interés simplemente será el mecanismo que permite que una expresión `a.f()` se traduzca como la ejecución de una implementacion particular de `f` que depende del tipo dinámico de `a`, y no simplemente la implementación definida en el tipo estático. A este proceso le llamamos *resolución de métodos virtuales*. + +Las reglas de la herencia varían en diversos lenguajes de programación, pero en general se distinguen dos grandes paradigmas, los lenguajes con *herencia simple*, donde cada tipo puede heredar de un solo tipo "padre", y los lenguajes con herencia múltiple. En los primeros, la jerarquía de tipos es un árbol (o conjunto de árboles, si no existe un tipo base de todos los tipos), y en el segundo caso la jerarquía de tipos se comporta como un grafo dirgido y acíclico (por supuesto, la herencia cíclica es, en principio, imposible). Del mismo modo que con los lenguajes estáticos y dinámicos, existen argumentos a favor y en contra de cada paradigma, aunque de forma general, los lenguajes con herencia simple son más sencillos de verificar que los lenguajes con herencia múltiple. + +En cualquier caso, de forma general existe una relación entre los tipos de una jerarquía, que llamaremos **relación de conformidad**, y denotaremos $B \leq A$, es decir, $B$ *se conforma a* $A$, si se cumple que $B$ hereda de $A$ o, recursivamente, si hereda de algún tipo $C$ que se conforme a $A$. Verificar esta relación de conformidad en una implementación concreta de un verificador de tipos implica recorrer el árbol o grafo de la jerarquía de tipos. De momento asumiremos la relación como dada, y más adelante veremos ideas para su implementación en un ejemplo concreto. + +## Verificando tipos + +De modo que el problema que tenemos que resolver es, para un nodo particular del AST, si el uso de los tipos es consistente. Este proceso en general lo haremos *bottom-up*, ya que la consistencia del uso de tipos en una expresión particular dependerá de los tipos en sus partes componentes. Por lo tanto, en un recorrido en post-orden del AST, iremos computando los tipos asociados a los nodos "hijos", y en el retorno chequearemos en cada "padre" la consistencia y computaremos el tipo del padre. Por ejemplo, si estamos en un nodo `SumExpr` que representa una expresión binaria de suma, podemos decir que este nodo es consistente si y solo sí cada una de las expresiones son a su vez consistentes, y son de tipo `int`, y la expresión en general es de tipo `int` también: + +```cs +class SumExpr : Expression { + public Expression Left; + public Expression Right; + public Type NodeType; + + public bool CheckTypes() { + if (!Left.CheckTypes() || !Right.CheckTypes()) { + return false; + } + + if (Left.NodeType != Type.Integer || + Right.NodeType != Type.Integer) { + return false; + } + + NodeType = Type.Integer; + return true; + } +} +``` + +De este modo, recursivamente, podemos computar el tipo de todas las expresiones de un lenguaje (todos los posibles nodos de un AST). Vamos a definir a continuación una notación formal para expresar esta noción del chequeo de tipos de forma recursiva. La notación que definiremos tiene la forma de una demostración en el lenguaje de la lógica de predicados. Comienza con una lista de precondiciones lógicas (sobre los tipos de las sub-expresiones), y termina con una conclusión que dice cuál es el tipo de la expresión actual. Por ejemplo, para el caso anterior, podemos escribir: + +$$ +\begin{array}{l} +e_1 : Integer \\ +e_2 : Integer \\ +\hline +\vdash e_1 + e_2 : Integer +\end{array} +$$ + +Podemos leer esta expresión de la siguiente forma: si $e_1$ es una expresión de tipo $Integer$ y $e_2$ es una expresión de tipo $Integer$, entonces se deduce que la expresión $e_1 + e_2$ es de tipo $Integer$. El símbolo $\vdash$ significa "se deduce que". + +## Contextos + +Una pregunta interesante es ¿qué sucede con las variables? Dado que estamos en un recorrido *bottom-up*, nos encontraremos la declaración de una variable luego de su uso. Luego, si nos encontramos un nodo `VarExpr` que representa el uso de una variable, ¿qué tipo le asociamos? En la sección *[Validando las reglas semánticas]* introdujimos el concepto de *contexto*, para almacenar las declaraciones anteriores, de forma que siempre supiéramos qué símbolo estaba declarado en cualquier expresión. Ahora vamos a extender este contexto, para especificar no solo los símbolos declarados, sino qué tipo está asociado a cada símbolo. Vamos a introducir entonces una función $O$ que llamaremos *contexto de objetos*, y que usaremos de la forma $O(x) = T$ para decir que este nodo existe un símbolo $x$ definido con tipo estático declarado $T$. Por tanto, extenderemos nuestra notación para incluir el contexto de objetos como parte de las precondiciones y la conclusión. Luego, la expresión suma quedaría de la forma: + +$$ +\begin{array}{l} +O \vdash e_1 : Integer \\ +O \vdash e_2 : Integer \\ +\hline +O \vdash e_1 + e_2 : Integer +\end{array} +$$ + +Que podemos leer de la siguiente forma: si dado el contexto de objetos $O$, podemos deducir (recursivamente) que el tipo de $e_1$ es $Integer$ (e igual para $e_2$), entonces en este mismo contexto de objetos podemos deducir que el tipo de $e_1 + e_2$ es $Integer$. Es importante notar que hemos dicho $O \vdash e : T$, y no $O(e) = T$, pues $e$ es una expresión en el sentido general, y $O$ solamente está definido para símbolos (variables, atributos, etc.). Por tanto, $O \vdash e : T$ nos indica que es necesario chequear el tipo de $e$ recursivamente en el contexto $O$ para computar el tipo que tiene la expresión. + +Los contextos de objetos se modifican cuando aparecen expresiones (instrucciones) que introducen nuevos símbolos (e.g. declaraciones de variables). Supongamos entonces que tenemos una expresión de la forma $T x \is e$, que indica que la variable $x$ se define con el tipo $T$ y se inicializa con la expresión $e$. Este es el tipo de instrucción que comunmente vemos en lenguajes tipo C para inicializar una variable recién declarada: + +```cs +int x = 4 + int.Parse(Console.ReadLine()); +``` + +En esta instrucción se introduce un nuevo símbolo en el contexto de objetos, con el nombre $x$, y el tipo $T$. Luego, es necesario verificar que el tipo de la expresión $e$ se conforme al tipo $T$, y luego definir el tipo de retorno de toda la expresión. En el caso particular de C, una instrucción de tipo asignación como esta no puede ser usada como expresión, y por tanto no devuelve valor, así que usaremos el símbolo $\emptyset$ para especificar que no tiene asociado (equivalente a `void`). Para especificar la modificación del contexto de objetos, introduciremos la sintaxis $O[T/x]$ que significa, informalmente, un nuevo contexto de objetos con las mismas definiciones que tenía $O$, pero además adicionando la definición del símbolo $x$ con tipo $T$. Formalmente: + +$$ +O[T/x](c) = \left\{ \begin{array}{ll} T & c = x \\ O(c) & c \neq x \end{array} \right. +$$ + +Armados con esta nueva notación, podemos definir la semántica de un nodo de declaración e inicialización: + +$$ +\begin{array}{l} +O \vdash e : T' \\ +T' \leq T \\ +\hline +O[T/x] \vdash T x \is e : \emptyset +\end{array} +$$ + +Podemos leer esta definición de la siguiente forma: si en el contexto actual el tipo de la expresión $e$ es $T'$, y $T'$ conforma a $T$, entonces en un nuevo contexto definimos $x$ con tipo $T$, y el tipo de retorno de la expresión es `void`. + +El otro problema de interés es cuando nos encontramos con la declaración o invocación de un método. De forma general, vamos a considerar que es permitido sobrescribir la implementación de un método $A.f$ en una clase $B \leq A$, siempre y cuando el tipo declarado de los parámetros de $f$ y el tipo de retorno de $f$ no cambien. Esto es lo que sucede en la mayoría de los lenguajes de tipado estático. En este caso, desde el punto de vista del chequeo de tipos, no nos interesa realmente cuál es la implementación concreta de $f$, ya que todas las implementaciones coinciden en cuanto a las definiciones de tipos. + +Vamos a introducir entonces un nuevo tipo de contexto $M$, que llamaremos *contexto de métodos*, y que usaremos de la forma $M(T,f) = \left\{ T_1, \ldots, T_{n+1} \right\}$, para expresar que el método $f$ definido en el tipo $T$ (o definido en algún tipo $T'$ tal que $T \leq T'$), tiene $n$ argumentos de tipo $T_1, \ldots, T_n$, y tipo de retorno $T_{n+1}$. El contexto $M$ no se modifica, sino que se construye en un primer recorrido por el AST, y luego simplememente sirve para consultar. De modo que asumiremos que en todo momento durante el chequeo de tipos, ya son conocidos de antemano todos los métodos declarados en todos los tipos accesibles por el programa que está siendo compilado. + +Tenemos entonces dos tipos de expresiones interesantes, la *declaración* de un método, y la *invocación*. Comenzaremos por la invocación de un método de instancia. Supongamos una sintaxis de la forma $x \cdot f(e_1, \ldots, e_n)$ para la invocación de métodos. Tenemos entonces que verificar el tipo de la expresión $x$, obtener el método $f$ asociado a ese tipo, verificar la conformación de los tipos de los argumentos, y entonces podemos computar el tipo de $f$: + +$$ +\begin{array}{l} +O \vdash x : T \\ +M(T,f) = \left\{ T_1, \ldots, T_{n+1} \right\} \\ +O \vdash e_i : T_i' \,\,\, \forall i = 1 \ldots n \\ +T_i' \leq T \,\,\, \forall i = 1 \ldots n \\ +\hline +O,M \vdash x \cdot f(e_1, \ldots, e_n) : T_{n+1} +\end{array} +$$ + +La invocación de un método estático es muy similar. Supongamos una sintaxis de la forma $T \cdot f(e_1, \ldots, e_n)$, la diferencia fundamental es que no es necesario computar el tipo de la expresión a quién se le invoca el método, pues la clase está definida explícitamente. Todo lo demás es prácticamente idéntico. + +$$ +\begin{array}{l} +M(T,f) = \left\{ T_1, \ldots, T_{n+1} \right\} \\ +O \vdash e_i : T_i' \,\,\, \forall i = 1 \ldots n \\ +T_i' \leq T \,\,\, \forall i = 1 \ldots n \\ +\hline +O,M \vdash T \cdot f(e_1, \ldots, e_n) : T_{n+1} +\end{array} +$$ + +Para poder formalizar la declaración de métodos, tenemos que introducir un nuevo elemento en nuestra notación, que llamaremos $C$, y que representará la *clase* actual donde se está realizando la verificación de la expresión correspondiente. En los lenguajes sin orientación a objetos (C) o donde no todo el código reside dentro de una clase (C++, Python), podemos definir un tipo especial $\Omega$ que representa el contexto "global". En última instancia, lo que queremos es poder diferenciar un método $f$ de otro del mismo nombre pero definido en un contexto diferente. Las clases son una de las posibles formas de definir un contexto, pero nada nos impide extender esta noción e incluir un contexto global. En algunos lenguajes se le llama *espacio de nombres* o **namespace** a un contexto donde todos los símbolos son de nombre distinto. En Python, por ejemplo, cada módulo define un nuevo espacio de nombres, donde los símbolos definidos ocultan, pero no sobrescriben a los símbolos definidos en otro módulo. + +Por otro lado, vamos a extender el concepto de contexto de objetos, para especificar $O_C$ como el contexto específico dentro de la clase $C$. Es decir, en este contexto daremos por supuesto que ya están definidos todos los atributos y métodos de $C$, que son visibles dentro del cuerpo de cada función. Por ejemplo, en C# serían todos los campos declarados en $C$ o declarados en algún padre de $C$ con la visibilidad adecuada (no `private`). + +Podemos entonces presentar una formalización de la semántica de tipos la definición de métodos. Supongamos una sintaxis de la forma: + +$$f(x_1 : T_1, \ldots, x_n : T_n) : T \{ e \}$$ + +Donde $x_i : T_i$ representa un argumento de $f$ de nombre $x_i$ y tipo $T_i$, $T$ es el tipo de retorno, y $e$ representa el cuerpo del método (visto como una expresión para simplificar). + +A grandes razgos el proceso es el siguiente: se definen los argumentos $x_i$ en el contexto de objetos hijo de $O_C$ donde se va a verificar la expresión $e$ y se verifica que el tipo del cuerpo conforme al tipo declarado de la función. Un tratamiento especial es necesario para el valor asociado a la instancia actual, que generalmente se llama `this` (C#) o `self` (Python). Por definición este símbolo en la instancia donde se está definiendo el método tiene exactamente el tipo $C$: + +$$ +\begin{array}{l} +M(C,f) = \{ T_1, \ldots, T_n, T \} \\ +O_C[T_1/x_1,\ldots,T_n/x_n,C/self] \vdash e : T' \\ +T' \leq T \\ +\hline +O_C,M,C \vdash f(x_1 : T_1, \ldots, x_n : T_n) : T \{ e \} +\end{array} +$$ + +Existen disímiles expresiones con reglas de tipos diversas pero, a grandes razgos, hemos mostrado cómo luce la formalización de la semántica de tipos de una expresión arbitraria. Armados con los conceptos de contexto de objetos y métodos, y una definición formal de la semántica de tipos para un lenguaje concreto de ejemplo, ya estamos en condiciones de implementar un verificador de tipos. + +## Implementando un verificador de tipos + +Para implementar un verificador de tipos necesitamos concretar dos elementos: una clase que nos permita manejar el contexto de objetos y el contexto de métodos, y un algoritmo para recorrer el AST. Vamos a ejemplificar algunos detalles de implementación, asumiendo un lenguaje orientado a objetos muy simple, con las siguientes características: + +* Un programa consiste en una lista de definiciones de clases. +* Todas las clases se definen en el mismo espacio de nombres global. +* Cada clase tiene atributos y métodos. +* Los atributos tienen un tipo asociado. +* Los métodos tienen un tipo de retorno (que puede ser `void`), y una lista de argumentos. +* Todos los atributos son privados y todos los métodos son publicos. +* Existe herencia simple. +* Un método se puede sobrescribir sí y solo sí se mantiene exactamente la misma definición para los tipos de retorno y de los argumentos. +* No existen sobrecargas de métodos ni de operadores. +* El cuerpo de todo método es una expresión. + +No vamos a especificar formalmente qué tipos de expresiones son válidas en este lenguaje, pero de forma general podemos pensar en ciclos, condicionales, expresiones aritméticas, inicializaciones (`new T()`), invocaciones a métodos, etc. En fin, todos los tipos de expresiones comunes en un lenguaje orientado a objetos moderno. Solamente formalizaremos algunas de estas expresiones cuando nos interese mostrar la implementación. + +Comencemos por representar los conceptos de tipo, atributo y método: + +```cs +interface IType { + string Name { get; } + IAtribute[] Attributes { get; } + IMethod[] Methods { get; } + IAttribute GetAttribute(string name); + IMethod GetMethod(string name); + bool DefineAttribute(string name, IType type); + bool DefineMethod(string name, IType returnType, + string[] arguments, IType[] argumentTypes); +} + +interface IAttribute { + string Name { get; } + IType Type { get; } +} + +interface IMethod { + string Name { get; } + IType ReturnType { get; } + IAttribute[] Arguments { get; } +} +``` + + Para representar un contexto podemos usar la siguiente *interface*, similar al contexto que hemos usado anteriormente en la sección *[Validando las reglas semánticas]*, pero modificada para adaptarse las definiciones anteriores: + +```cs +interface IContext { + IType GetType(string typeName); + IType GetTypeFor(string symbol); + IContext CreateChildContext(); + bool DefineSymbol(string symbol, IType type); + IType CreateType(string name) +} +``` + +Esta *interface* básicamente nos representa el contexto de objetos. El contexto de métodos realmente lo tenemos modelado como parte de la definición de cada tipo, por lo que no es necesario tener un contexto de métodos global. El propio tipo $C$ nos permitirá acceder al contexto de métodos del tipo actual. Por otro lado, para acceder al contexto de métodos de un tipo específico, basta resolver la instancia de `IType` correspondiente (mediante el método `GetType`). + +Vamos a definir entonces un subconjunto de los nodos del AST que nos interesa modelar. Comenzaremos como siempre por una clase base: + +```cs +public abstract class Node { + +} +``` + +Nuestro siguiente nodo es un programa, que se compone de una lista de definiciones de clase: + +```cs +public class Program : Node { + public List Classes; +} +``` + +Cada definición de clase a su vez define un tipo con un nombre y una lista de atributos y métodos: + +```cs +public class ClassDef : Node { + public string Name; + public List Attributes; + public List Methods; +} +``` + +Los atributos se definen como un nombre, tipo asociado, y una expresión de inicialización: + +```cs +public class AttrDef : Node { + public string Name; + public string Type; + public Expression Initialization; +} +``` + +Mientras que los métodos se definen como un nombre, una lista de argumentos (nombres y tipos), un tipo de retorno, y un cuerpo que es una expresión: + +```cs +public class MethodDef : Node { + public string Name; + public string ReturnType; + public List ArgNames; + public List ArgTypes; + public string ReturnType; + public Expression Body; +} +``` + +Luego nos quedarían todos los nodos de la jerarquía de expresiones, que no mostraremos por simplicidad. + +Centraremos a continuación nuestra atención en el problema de la verificación en sí. De forma general, primero tenemos que hacer un recorrido por todo el AST para encontrar todas las definiciones de tipos. Este primer paso es necesario antes de verificar los métodos o atributos de un tipo particular, ya que podemos tener una declaración de un tipo `A` con un atributo de tipo `B`, donde la declaración del tipo `B` aparece luego de la declaración de `A`. Por este motivo, es necesario recolectar primero todos los nombres de todas las clases declaradas y adicionarlos al contexto. Luego es necesario volver a recorrer todo el AST pero esta vez recogiendo las declaraciones de métodos y atributos, a quienes ya podemos asociar los tipos correspondientes. Esta segunda vez también es necesaria antes de pasar a analizar el cuerpo de los métodos, pues podemos tener un método `F` llamando a otro método `G` que está definido posteriormente. De esta forma completamos el contexto de métodos, y podemos finalmente recorrer el AST una vez más, esta vez adentrándonos en el cuerpo de los métodos y verificando la semántica de las expresiones. + +De modo que necesitamos hacer al menos 3 pasadas por el AST, ya que podemos tener definiciones que usen a su vez símbolos definidos posteriormente. Para evitar esto, en lenguajes como C y C++ es necesario declarar de antemano en archivo *header* (con extensión `.h`) los símbolos que luego serán definidos (en un archivo `.c`). + +Una primera aproximación a este problema nos lleva a definir al menos 3 métodos recursivos, uno para buscar las definiciones de tipos, otro para los métodos y atributos, y otro finalmente para la semántica. A medida que nuestro lenguaje crece, la semántica se complica, y aparecen nuevas fases (como la generación de código que veremos más adelante), notaremos que se repite este patrón de recorrer todo el AST buscando algunos nodos particulares y haciendo algunas operaciones en ellos. Por lo tanto, esta solución de definir un método recursivo para cada posible recorrido por el AST se vuelve cada vez menos atractivo. Cada vez que adicionamos algún tipo de chequeo tendremos que modificar la jerarquía del AST para acomodar los métodos recursivos necesarios. Por otro lado, si decidimos introducir un tipo de nodo nuevo (porque nuestra gramática ha cambiado o porque es conveniente especializar alguna función semántica), tendremos que redefinir todos estos métodos de chequeo en consecuencia. Por último, la mayoría de estos métodos recursivos se van a parecer mucho, pues todos tienen que descender recursivamente por los nodos del AST, y realizar alguna operación en pre-orden o post-orden. + +El problema que tenemos aquí es un caso típico de acoplamiento, que nos lleva a una replicación de comportamiento similar. Tenemos que reconocer que existen dos responsabilidades diferentes en cada uno de estos casos: una es la que juega cada nodo del AST, que consiste en representar la función semántica correspondiente; y la otra es justamente el procesamiento necesario a realizar en un nodo para verificar algún predicado semántico. Vamos entonces a separar la responsabilidad de procesar a un nodo del nodo en sí, y ponerla en una clase distinta. A este diseño que presentaremos se le denomina el **patrón visitor**, y es uno de los patrones de diseño más populares y útiles, especialmente en la implementación de compiladores. + +## El Patrón Visitor + +Comenzaremos por definir la siguiente *interface*: + +```cs +interface IVisitor where TNode : Node { + void Visit(TNode node); +} +``` + +La *interface* `IVisitor` nos permitirá abstraer el concepto de procesamiento sobre un nodo. En cada implementación particular, escogeremos qué procesamiento realizar sobre cada tipo de nodo particular, y cómo "caminar" sobre la porción de AST correspondiente. Veamos entonces como implementar la primera pasada, que nos permite recolectar todos los tipos definidos. Este *visitor* solamente se interesa en nodos de tipo `Program` y nodos de tipo `ClassDef`. Su tarea consiste en crear un contexto, y definir en este contexto todos los tipos que se encuentre: + +```cs +public class TypeCollectorVisitor: IVisitor, + IVisitor { + public IContext Context; + + public void Visit(Program node) { + Context = new // ... + + foreach(var classDef in node.Classes) { + this.Visit(classDef); + } + } + + public void Visit(ClassDef node) { + Context.CreateType(node.Name); + } +} +``` + +El llamado `this.Visit(classDef)` resolverá estáticamente la sobrecarga adecuada. Veamos ahora como implementar un *visitor* que construya todo el contexto de métodos y atributos. En este caso, nos interesan además los nodos de tipo `AttrDef` y `MethodDef`: + +```cs +public class TypeBuilderVisitor : IVisitor, + IVisitor, + IVisitor, + IVisitor { + + public IContext Context; + private IType currentType; + + public void Visit(Program node) { + foreach(var classDef in node.Classes) { + this.Visit(classDef); + } + } + + public void Visit(ClassDef node) { + currentType = Context.GetType(node.Name); + + foreach(var attrDef in node.Attributes) { + this.Visit(attrDef); + } + + foreach(var methodDef in node.Methods) { + this.Visit(methodDef); + } + } + + // ... +} +``` + +Hasta este punto simplemente hemos descendido por las definiciones de tipos hasta llegar a cada definición de atributo o método. En cada paso, nos hemos asegurado además de mantener una referencia al tipo concreto dentro del cual se están realizando las definiciones. Veamos entonces los métodos restantes: + +```cs +public class TypeBuilderVisitor : IVisitor, + IVisitor, + IVisitor, + IVisitor { + + public IContext Context; + private IType currentType; + + // ... + + public void Visit(AttrDef node) { + IType attrType = Context.GetType(node.Type); + currentType.DefineAttribute(node.Name, attrType); + } + + public void Visit(MethodDef node) { + IType returnType = Context.GetType(node.ReturnType); + var argTypes = node.ArgTypes.Select(t => Context.GetType(t)); + + currentType.DefineMethod(node.Name, returnType, + node.ArgNames.ToArray(), + argTypes.ToArray()); + } +} +``` + +Por último, tendremos un `TypeCheckerVisitor` que verificará finalmente la consistencia de tipos en todos los nodos del AST. Este implementará la *interface* `IVisitor` en cada tipo de nodo que sea capaz de chequear, incluidos todos los tipos de expresiones e instrucciones que no hemos definido. A este `TypeCheckerVisitor` le pasaremos el contexto ya construido anteriormente, y lo dejaremos procesar todo el AST. Este *visitor* además de verificar el tipo de todas las expresiones, será el encargado de computar el tipo asociado a cada expresión y almacenarlo en el nodo `Expression`: + +```cs +public abstract class Expression { + public IType ComputedType; +} +``` + +Hemos obviado hasta el momento cualquier consideración de error. Si alguno de los tipos definidos para alguno de los atributos o métodos no es válido, o alguno de los tipos aparece declarado más de una vez, o cualquier otro error semántico es detectado, nuestro verificador lanzará una excepción, o peor, fallará silenciosamente. Para manejar los errores de forma consistente, adicionaremos a los métodos `Visit` un argumento `IErrorLogger` con la *interface* siguiente: + +```cs +public interface IErrorLogger { + void LogError(string msg); +} +``` + +De modo que ante un error cualquier de chequeo de tipos, simplemente nos remitiremos a este objeto para indicar que ocurrió un error. Una vez detectado el error, la pregunta que queda es ¿qué hacer a continuación? Si detenemos el chequeo entonces nuestro compilador solamente será capaz de detectar un error en cada iteración, pero idealmente quisiéramos indicar la mayor cantidad de errores posibles en cada corrida. Por lo tanto, lo que se sugiere es tomar alguna acción de reparo sensata y continuar la verificacion. Por ejemplo: + +```cs +public class TypeCheckerVisitor : IVisitor<...> { + public Context Context; + + public void Visit(BinaryExpr node, IErrorLogger logger) { + this.Visit(node.Left, logger); + this.Visit(node.Right, logger); + + if (node.Left.ComputedType != node.Right.ComputedType) { + logger.LogError("Type mismatch..."); + node.ComputedType = null; + } + else { + node.ComputedType = node.Left.ComputedType; + } + } +} +``` + +Con estas herramientas, podemos adicionar un método en la clase `Program` que realice todas las pasadas correspondientes: + +```cs +public class Program : Node { + // ... + + public void CheckSemantics(IErrorLogger logger) { + var typeCollector = new TypeCollectorVisitor(); + typeCollector.Visit(this, logger); + + var typeBuilder = new TypeBuilderVisitor() { + Context = typeCollector.Context + }; + + typeBuilder.Visit(this, logger); + + var typeChecker = new TypeCheckerVisitor() { + Context = typeBuilder.Context; + }; + + typeChecker.Visit(this, logger); + } +} +``` diff --git a/doc/content/chap7.md b/doc/content/chap7.md new file mode 100644 index 000000000..678260d88 --- /dev/null +++ b/doc/content/chap7.md @@ -0,0 +1,441 @@ +--- +previous-chapter: chap6 +next-chapter: chap8 +--- + +# Generación de Código + +## Código de 3 Direcciones Orientado o Objetos (CIL) + +Para la generación de código intermedio de COOL a MIPS vamos +a diseñar un lenguaje de máquina con capacidades orientadas a objeto. +Este lenguaje nos va a permitir generar código de COOL de forma +más sencilla, ya que el salto directamente desde COOL a MIPS es +demasiado complejo. Este lenguaje se denomina CIL, **3-address object-oriented**. + +Un programa en CIL tiene 3 secciones: + +### Jerarquía de Tipos + +La primera es una sección (opcional) de declaración de tipos: + +```cil +.TYPES + +type A { + attribute x ; + method f : f1; +} + +type B { + attribute x ; + attribute y ; + method f : f1 ; + method g : f2 ; +} + +type C { + attribute x ; + attribute z ; + method f : f2; +} +``` + +El "tipo" de los atributos en CIL no importa, pues todos los atributos son de tipo numérico. El único tipo por valor es `Integer` que almacena un entero de 32 bits. Todos los demás tipos son por referencia, y por lo tanto se representan por el valor de 32 bits del lugar de memoria virtual donde se ubican. + +El orden de los atributos es muy importante, ya que luego veremos instrucciones para acceder a los atributos que usan realmente la dirección de memoria del atributo. Esta dirección está definida por el orden en que se declaran. Por este motivo, por ejemplo, si la clase `A` hereda de la clase `B`, y la clase `B` tiene un atributo `x`, es importante que en ambas declaraciones de tipos haya un atributo `x` y además que esté en el mismo orden. Lo mismo sucede con los métodos. Más adelante cuando completemos la generación de código veremos estos detalles más en profundidad. + +### Datos + +En la sección de datos se declaran todas las cadenas de texto constantes que serán usadas durante todo el programa. + +```cil +.DATA + +msg = "Hello World"; +``` + +### Funciones + +> Se toma como convenio que la primera función declarada es la función que se ejecuta al iniciar el programa. + +```cil +.CODE + +function f1 { + ... +} + +function f2 { + ... +} +``` + +El cuerpo de cada función se divide a su vez +en dos secciones. Primero se definen todos los parámetros +y variables locales, y luego las instrucciones en sí: + +```cil +function f1 { + PARAM x; + PARAM y; + + LOCAL a; + LOCAL b; + + +} +``` + +El cuerpo de una función en CIL se compone de una secuencia +de instrucciones, que siempre reciben a lo sumo 3 argumentos, +uno para almacenar el valor de retorno, y 2 operandos. + +Entre las instrucciones básicas tenemos: + +### Asignación simple + +```cil +x = y ; +``` + +### Operaciones aritméticas + +```cil +x = y + z ; +``` + +### Acceso a atributos + +El acceso a atributos se utiliza para obtener el valor de un atributo almacenado en un lugar de la memoria en una variable temporal. + +```cil +x = GETATTR y b ; +``` + +Es equivalente a `x = y.b`. + +```cil +SETATTR y b x ; +``` + +El "atributo" `b` realmente es solamente la dirección de memoria donde está el atributo. + +Es equivalente a `y.b = x`. + +### Acceso a arrays + +Cuando una variable es de un tipo array (o `string`), se puede acceder al iésimo elemento: + +```cil +x = GETINDEX a i ; +``` + +O asignar un valor: + +```cil +SETINDEX a i x ; +``` + +### Manipulación de memoria + +Para crear un nuevo objeto existe una instrucción de alocación de memoria: + +```cil +x = ALLOCATE T ; +``` + +Esta instrucción crea en memoria espacio suficiente para alojar un tipo `T` y devuelve en `x` la dirección de memoria de inicio del tipo. + +Para obtener el tipo dinámico de una variable se utiliza la sintaxis: + +```cil +t = TYPEOF x ; +``` + +Para crear arrays se utiliza una sintaxis similar: + +```cil +x = ARRAY y ; +``` + +Donde `y` es una variable de tipo numérico (como todas) que define el tamaño del array. + +### Invocación de métodos + +Para invocar un método se debe indicar el tipo donde se encuentra el método, además del método en concreto que se desea ejecutar. + +```cil +x = CALL f ; +``` + +Este llamado es una invocación estática, es decir, se llama exactamente al método `f`. + +Además existe un llamado dinámico, donde el método `f` se buscan en el tipo `T` y se resuelve la dirección del método real al que invocar: + +```cil +x = VCALL T f ; +``` + +Todos los parámetros deben ser pasados de antemano, con la siguiente instrucción: + +```cil +ARG a ; +``` + +Cada método espera que los parámetros estén ubicados en la memoria en el mismo orden en que están declarados en el método. Es responsabilidad del que invoca pasar los parámetros de forma adecuada. + +En particular, para todos los métodos "de instancia", que tiene un argumento `self` o similar, es responsabilidad del que invoca pasar este `self` como primer parámetro. + +### Saltos + +Los saltos condicionales en CIL siempre tienen una condición y una instrucción de salto: + +```cil +IF x GOTO label ; +``` + +Donde `label` tiene que ser una etiqueta declarada en algún lugar de la propia función. La etiqueta puede estar declarada después de su uso. Si la etiqueta no está declarada correctamente, el resultado de la operación no está definido. + +```cil +LABEL label ; +``` + +Los saltos incondicionales simplemente se ejecutan con: + +```cil +GOTO label ; +``` + +Como en CIL no existen variables *booleanas*, el valor de verdad de una expresión es realmente que la expresión sea distinta de cero, por lo tanto, los siguientes saltos son equivalentes: + +```cil +x = y != z; +IF x GOTO label ; + +x = y - z +IF x GOTO label ; +``` + +### Retorno de Función + +Finalmente todas las funciones deben tener una instrucción de retorno: + +```cil +RETURN x ; +``` + +Esta instrucción pone el valor de `x` en la dirección de retorno de `f` y además termina la ejecución de la función. Si esta instrucción no se ejecuta en el cuerpo de una función el resultado de la invocación de la función no está bien definido. Si no importa el valor de retorno de la función, simplemente se puede usar cualquiera de las siguientes dos variantes, (que son equivalentes): + +```cil +RETURN ; + +RETURN 0 ; +``` + +### Funciones de cadena + +Las cadenas de texto se pueden manipular con funciones especiales. Primero es necesario obtener una dirección a la cadena: + +```cil +x = LOAD msg ; +``` + +Luego se puede operar sobre una cadena con instrucciones +tales como `LENGTH`, `CONCAT` y `SUBSTRING`, con la semántica esperada: + +```cil +y = LENGTH x ; +``` + +Además hay una función STR que computa la representación textual de un valor numérico y devuelve la dirección en memoria: + +```cil +z = STR y ; +``` + +### Operaciones IO + +Finalmente, hay 2 instrucciones de entrada-salida, `READ` que lee de la entrada estándar hasta el siguiente cambio de línea (incluído): + +```cil +x = READ ; +``` + +Y `PRINT` que imprime en la salida estándar, sin incluir el cambio de línea. + +```cil +PRINT z ; +``` + +## Programas de ejemplo + +Veamos algunos programas de ejemplo directamente escritos en CIL antes de pasar a definir cómo haremos la generación de código. + +### Hola Mundo + +El "Hola Mundo" en CIL es muy sencillo: + +```cil +.DATA + +msg = "Hello World!\n" ; + +.CODE + +function main { + LOCAL x ; + + x = LOAD msg ; + PRINT x ; + RETURN 0 ; +} +``` + +Ahora, este programa si lo fuéramos a generar desde COOL realmente sería un poco más complejo. En COOL sería necesario tener una clase con un método `main`, y algunos detalles adicionales: + +```cool +class Main: IO { + msg : string = "Hello World!\n"; + + function main() : IO { + self.print(self.msg); + } +} +``` + +El programa completo en CIL que representa al programa anterior de COOL sería el siguiente. Hemos tenido cuidado de usar convenios de nombres que luego nos será útil respetar durante la generación de código. + +```cil +.TYPES + +type Main { + attribute Main_msg ; + method Main_main: f1 ; +} + +.DATA + +s1 = "Hello World!\n"; + +.CODE + +function entry { + LOCAL lmsg ; + LOCAL instance ; + LOCAL result ; + + lmsg = LOAD s1 ; + instance = ALLOCATE Main ; + SETATTR instance Main_msg lmsg ; + + ARG instance ; + result = VCALL Main Main_main ; + + RETURN 0 ; +} + +function f1 { + PARAM self ; + + LOCAL lmsg ; + + lmsg = GETATTR self Main_msg ; + PRINT lmsg ; + + RETURN self ; +} +``` + +Podemos ver que el código generado es más ineficiente que el código que se podría concebir manualmente. Este es un resultado necesario del hecho de subir de nivel de abstracción. Un programador humano escribiendo directamente CIL probablemetne pueda generar código más eficiente que nuestro compilador de COOL (al menos hasta que comencemos a aplicar técnicas de optimización de código), pero la ganancia en productividad es tal, que no tiene sentido tal comparación. + +## Generando código + +Veamos entonces algunas ideas sobre cómo generar código concreto de COOL en CIL. Primero nos vamos a concentrar en la generación de expresiones concretas y al final veremos cómo combinarlo todo para generar un programa completo, con sus clases y métodos virtuales. + +### Un lenguaje plantilla para la generación de código + +Para ejemplificar y documentar nuestras reglas de generación de código vamos a expandir el lenguaje CIL y el lenguaje COOL con una notación informal de "plantilla". No vamos a ser muy formales con esta notación, ya que no la usaremos nada más que como documentación. La idea básica es que permitiremos algunas expresiones "vagas", como puntos suspensivos, nombres genéricos, etc., donde nos sea conveniente. Además, no seremos estrictos con escribir todo el código CIL necesario, solamente la parte que corresponda al fragmento de COOL que nos interesa generar, y asumiremos que el lector entiende el contexto. A medida que veamos ejemplos se irá haciendo más claro este "lenguaje". + +Supongamos que tenemos una expresión en COOL de la forma: + +```cool +let x : Integer = 5 in + x + 1 +end +``` + +Esta expresión puede ser parte del cuerpo de un método cualquiera, rodeada por cualquier contexto. Asumamos que el método se denomina `f`, a falta de un nombre mejor. Como no hemos especificado exactamente aquí todo el contexto de la expresión, tendremos que ser vagos con la generación de código. Permitiremos entonces obviar las partes "poco importantes" y concentrarnos solo en la parte que nos interesa. Sin más, presentamos el código CIL: + +```cil-template +function f { + ... + LOCAL x ; + LOCAL ; + + ... + x = 5 ; + = x + 1 ; + ... +} +``` + +Aquí hemos tomado por convenio que el valor de la expresión lo guardamos en una variable de nombre ``, que hemos puesto entre angulares `<...>` para indicar que este no es el nombre final que quedará en el código CIL real, sino un nombre plantilla que estamos usando ahora a falta de no tener el contexto completo. Es decir, en la generación real de código ese nombre se sustituirá por algo como `value_017` o cualquier indicador que sea conveniente en ese momento, generado de forma automática. + +Por otro lado, supongamos que tenemos una expresión de la forma: + +```cil-template +let x : Integer = 5 in + x + +end +``` + +En esta expresión también estamos abusando de la notación, con el uso de `` para indicar que en COOL aquí va una expresión válida cuya forma exacta no nos interesa. Podemos entonces tomar un convenio como el siguiente: + +```cil-template +function f { + ... + + LOCAL x ; + LOCAL ; + + ... + x = 5 ; + + = x + ; +} +``` + +El convenio que estamos tomando aquí, es usar `` para indicar que se debe rellenar esta parte con todas las inicializaciones de variables locales que sean necesarias para poder computar la expresión ``. Además, luego en el cuerpo del método usamos `` para indicar que se debe rellenar con todo el código generado para la expresión ``. Finalmente, asumimos que `` será reemplazado por el nombre de la variable local que haya sido escogida para almacenar temporalmente el valor de ``. + +Esperamos que esta notación se vaya haciendo más clara a medida que veamos más ejemplos. Vamos a comenzar entonces con ejemplos concretos: + +### Expresiones Let-In + +Sea la expresión genérica de COOL `let-in` con la forma: + +```cool-template +let : = in + +end +``` + +Supongamos que esta expresión ocurre dentro de un método `f` arbitrario. Podemos entonces definir la generación de código de esta instrucción de la siguiente forma: + +```cil-template +function f { + ... + + LOCAL ; + + LOCAL ; + + ... + + = ; + + = ; +} +``` + +Puede parecer que no hemos ganado mucho con esta notación, pero en realidad hemos logrado definir para una expresión de tipo `let-in` arbitraria, exactamente lo que hace falta para su generación de código en CIL. Si interpretamos las expresiones `` y `` como, recursivamente, generar las inicializaciones de variables correspondientes, e igualmente `` y `` como, recursivamente, generar los fragmentos de código asociados, podemos ver que esta sintaxis nos permite decir de forma precisa en qué orden hay que recorrer el AST generando qué parte de cada tipo de nodo. No es difícil ver cómo este tipo de plantillas se convierten en respectivos llamados a *visitors* adecuados para cada parte del código. diff --git a/doc/content/chap8.md b/doc/content/chap8.md new file mode 100644 index 000000000..24f4185b8 --- /dev/null +++ b/doc/content/chap8.md @@ -0,0 +1,1711 @@ +--- +previous-chapter: chap7 +--- + +# El lenguaje HULK + +```python echo=False +import sys +import os + +sys.path.append(os.path.abspath(os.curdir)) + +from source.diagrams import Pipeline +``` + +En este capítulo definimos el lenguaje **HULK** (_Havana University Language for Kompilers_), un lenguaje de programación didáctico diseñado para este curso. +A grandes razgos, **HULK** es un lenguaje orientado a objetos, con herencia simple, polimorfismo, y encapsulamiento a nivel de clases. +Además en **HULK** es posible definir funciones globales fuera del contexto de cualquier clase. +También es posible definir _una única expresión global_ que constituye el punto de entrada al programa. + +La mayoría de las construcciones sintácticas en **HULK** son expresiones, incluyendo las instrucciones condicionales y los ciclos. +**HULK** es un lenguaje estáticamente tipado con inferencia de tipos opcional, lo que significa que algunas (o todas) las partes de un programa pueden ser anotadas con tipos, y el compilador verificará la consistencia de todas las operaciones. + +## Un lenguaje didáctico e incremental + +El lenguaje **HULK** ha sido diseñado para ser utilizado como mecanismo de aprendizaje y evaluación de un curso de Compilación. Por tal motivo, ciertas decisiones de diseño de lenguaje responden más a cuestiones didácticas que a cuestiones teóricas o pragmáticas. Un ejemplo ilustrativo es la inclusión de un solo tipo numérico básico. En la práctica los lenguajes de programación cuentan con varios tipos numéricos (`int`, `float`, `double`, `decimal`) para cubrir el amplio rango de _trade-off_ entre eficiencia y expresividad. Sin embargo, desde el punto de vista didáctico, ya es suficiente complejidad el tener que lidiar con un tipo numérico, y la inclusión de otros no aporta nada nuevo desde nuestro punto de vista. + +Otra decisión importante es el tipado estático con inferencia de tipos, que será explicado más adelante en detalle. La motivación detrás de esta característica es permitir a los estudiantes implementar primero un evaluador para el lenguaje, y luego preocuparse por la verificación de tipos. Así mismo, la decisión de tener expresiones globales, funciones globales, y clases, responde a la necesidad de introducir los diversos elementos del lenguaje poco a poco. Al tener expresiones globales, es posible implementar un intérprete de expresiones sin necesidad de resolver los problemas de contexto. Luego se pueden introducir las funciones y finalmente las características orientadas a objetos. De esta forma los estudiantes pueden ir aprendiendo sobre la marcha a medida que adicionan características al lenguaje, siempre teniendo un subconjunto válido del lenguaje implementado. + +El lenguaje **HULK** realmente es un conjunto de lenguajes de programación muy relacionados. Lo que llamaremos **HULK** _básico_ consiste en un subconjunto mínimo al que se le definen un conjunto extenso de características adicionales. El lenguaje _básico_ contiene expresiones, funciones globales y un sistema unificado de tipos con herencia simple. Las extensión incluyen desde soporte para _arrays_, hasta delegados, inferencia de tipos, iteradores, entre otras características. Cada una de estas extensiones se ha diseñado para que sea compatible con el resto de **HULK**, incluyendo el resto de la extensiones. Debe ser posible, una vez implementado un compilador básico, adicionar cualquier subconjunto de estas extensiones. + +Este diseño ha sido concebido para permitir el uso de **HULK** en un amplio rango de niveles de aprendizaje. Como lenguaje de expresiones y funciones, es útil para cursos introductorios sobre _parsing_ y técnicas básicas de compilación. La orientación a objetos introduce todo un universo de complejidades semánticas; sin embargo, el sistema de tipos de **HULK** es suficientemente sencillo como para ilustrar los problemas más comunes en la verificación semántica de tipos. Por su parte, cada una de las extensiones introduce problemáticas avanzadas e interesantes. Los _arrays_ introducen problemas relacionados con el manejo de memoria, mientras que las funciones anónimas y los iteradores son fundamentalmente problemas de transpilación y generación de código. La inferencia de tipos y la verificación de _null-safety_ es todo un ejercicio en inferencia lógica, que puede servir en cursos avanzados. La idea es que cada curso defina sus objetivos de interés, y pueda utilizar un subconjunto apropiado de **HULK** para ilustrar y evaluarlos. + +## HULK básico + +En esta sección definimos el subconjunto mínimo de **HULK**, que llamaremos _básico_. Este subconjunto consiste en un lenguaje de expresiones y funciones globales con tipado estático, y un sistema unificado de tipos con herencia simple. + +El programa más sencillo en **HULK** es, por supuesto, _Hola Mundo_: + +```hulk +print("Hola Mundo"); +``` + +En **HULK** un programa puede ser simplemente una expresión (terminada en `;`), en este caso, la invocación de una función global llamada `print` (que se presentará más adelante). La cadena de texto `"Hola Mundo"` es un literal del tipo `String`, definido en la biblioteca estándar, que se comporta de la forma convencional en la mayoría de los lenguajes de programación más populares: es inmutable, y codificado en UTF8. + +### Tipos básicos + +Además de los literales de cadena, en **HULK** hay 2 tipos básicos adicionales: `Number`, que representa valores numéricos y `Boolean` que representa valores de verdad (con los literales usuales `True` y `False`). + +El tipo `Number` representa tanto números enteros, como números con coma flotante. La semántica concreta dependerá de la arquitectura. Siempre que sea posible se representará con un valor entero de 64 (o 32) bits, o en su defecto, un valor flotante de 64 (o 32) bits, según permita la arquitectura. Las constantes numéricas se pueden escribir como `42` (valor entero) o `3.14` (valor flotante). + +**HULK** tiene una jerarquía de tipos unificada, cuya raíz es el tipo `Object`. Todos los demás tipos definidos en el lenguaje son concretos. + +### Expresiones elementales + +En **HULK** se definen todas las expresiones usuales, en orden decreciente de precedencia: + +- Operaciones lógicas entre expresiones de tipo `Boolean`: `a & b`, `a | b`, `!a`, siempre evaluadas con cortocircuito. +- Operaciones aritméticas entre expresiones de tipo `Number`: `-a`, `a % b`, `a * b`, `a / b`, `a + b`, `a - b`, con la precedencia y asociatividad usuales, y agrupamiento mediante paréntesis. El resultado es de tipo `Number` siempre. +- Comparaciones entre expresiones de tipo `Number`: `a < b`, `a > b`, `a <= b`, `a >= b`, con menor precedencia que las aritméticas, y sin asociatividad. +- Comparaciones de igualdad entre expresiones de cualquier tipo: `a == b`, `a != b`, con la semántica de igualdad por valor entre expresiones de tipo `Number`, `String` o `Boolean`, e igualdad por referencia en todos los demás tipos. Se permite comparar expresiones de cualquier tipo, y si sus tipos no son compatibles (e.j, `"Hola Mundo" == 42`) el resultado será `False`. +- El operador infijo `@` de concatenación entre `String`: `"Hello "@"World" == "Hello World"`. Para los casos donde es conveniente, el operador `@@` adiciona un espacio intermedio: `"Hello" @@ "World"` es igual a `"Hello World"`. + +En el espacio de nombres global siempre se encontrarán además las funciones `print`, `read` y `parse`, además de una serie de funciones elementales matemáticas, tales como `exp`, `pow`, `log`, `sqrt`, `min`, `max` y `random`. + +El valor `Null` es un valor especial que puede tener cualquier tipo, excepto `Number` y `Boolean`. `Null` representa la no existencia de una instancia asociada a la variable (_l-value_ en caso general) correspondiente, y cualquier operación que se intente sobre un valor `Null` lanzará un error en tiempo de ejecución, excepto `==`, que siempre devuelve `False`, y `!=` (que siempre devuelve `True`, incluso entre expresiones ambas iguales a `Null`). El literal `Null` es una expresión de tipo `Object` con valor igual a `Null`. + +### Variables + +Las variables en **HULK** se introducen con una expresión `let`: + +```hulk +let [:]= in +``` + +La semántica de la expresión `let` consiste en que se crea un nuevo ámbito donde se define la variable `` cuyo valor es el resultado de evaluar ``, y se evalua en este ámbito la expresión ``. + +```hulk +let msg:String="Hola Mundo" in print(msg) +``` + +Como se verá, indicar el tipo de una variable al declararla es opcional. Los detalles de la inferencia y verificación de tipos se darán más adelante. + +Existe una variante extendida de la expresión `let` en la que se permite introducir más de una variable: + +```hulk +let x=1, y=2, z=3 in x+(y*z) +``` + +Esta variante es semánticamente idéntica a: + +```hulk +let x=1 in let y=2 in let z=3 in x+(y*z) +``` + +El cuerpo de una expresión `let` puede ser también una _lista de expresiones_, encerradas entre `{` y `}` y separadas por `;`, siendo el valor final de la expresión `let` el valor de la última expresión de la lista. + +```hulk +let x=0 in { + print(x==0); # Imprime True + print(x==1); # Imprime False +} +``` + +Una _lista de expresiones_ **no es** una expresión en sí, es decir, no puede ser usada donde quiera que se requiera una expresión. Solamente se puede usar en el cuerpo de algunas construcciones sintácticas que se irán introduciendo poco a poco. +Es decir, el siguiente ejemplo **no es válido**: + +```hulk +let x={0;1} in print(x) # NO es válido +``` + +Como tampoco lo es: + +```hulk +{1;2} + {3;4;let x=5 in 5} # NO es válido +``` + +Ni ningún otro ejemplo similar donde se use un bloque de expresiones como una expresión, excepto en los contextos donde se indique explícitamente más adelante. + +### Asignación + +La asignación en **HULK** se realiza con el operador `:=`, y solamente es posible asignar a una variable que exista en el contexto actual: + +```hulk +let color="green" in { + print(color); # Imprime green + color:="blue"; + print(color); # Imprime blue +} +``` + +La asignación devuelve el valor asignado, y asocia a la derecha. Tiene menor prioridad que todas las expresiones aritméticas: + +```hulk +let x=0, y=0 in { + y := x := 5 + 5; + print(x); # 10 + print(y); # 10 + y := (x := 5) + 1; + print(x); # 5 + print(y); # 6 +} +``` + +### Espacios en blanco e indentación + +En **HULK** los espacios en blanco no son significativos, ni tampoco la indentación. La sintaxis del lenguaje permite indicar explícitamente, cuando es necesario, el ámbito de un bloque de código. El ejemplo anterior es equivalente a: + +```hulk +let x=1 in +let y=2 in +let z=3 in + x + (y * z) +``` + +O cualquier otra forma de indentar que sea conveniente. + +### Identificadores + +Los identificadores empiezan con un caracter del alfabeto ASCII (o `_`) y pueden opcionalmente contener números. Ejemplos de identificadores válidos son: + +```hulk +x +name +CamelCase +smallCamelCase +snake_case +_ugly_case +hunter42 +``` + +### Funciones + +**HULK** soporta funciones globales con 2 formas sintácticas muy similares. Una función se define por un nombre, argumentos con tipo opcional, un tipo de retorno también opcional, y el cuerpo. +Todas las funciones globales deben ser definidas **antes** de la expresión global que define el _cuerpo_ del programa. + +En la primera forma sintáctica, que llamamos "compacta", el cuerpo de la función debe ser exactamente una expresión (terminada en `;`): + +```hulk +function isEven(n:Number):Boolean -> n % 2 == 0; +``` + +En la segunda forma, que llamaremos "extendida", el cuerpo de una función puede ser una _lista de expresiones_ separadas por `;`. El valor de retorno de la función es el valor de la última expresión de la lista. En esta notación **no se incluye** un `;` al final de la declaración de la función. + +```hulk +function f(a:Number, b:Number, c:Number):Number { + a := b + c; + b := c + a; + c := a + b; +} + +let a:Number=1, b:Number=2, c:Number=3 in print(f(a,b,c)); # Imprime 13 +``` + +En **HULK** no existe una instrucción ni palabra reservada con semántica similar a `return`. Todas las funciones tienen un tipo de retorno y devuelven siempre un valor, aunque este valor puede ser `Null`. + +### Condicionales + +Las expresiones condicionales se introducen con la sintaxis siguiente: + +```hulk +if () [elif () ]* [else ]? +``` + +Es decir, una parte `if`, seguida de cero o más partes `elif` y finalmente una parte `else` opcional. +Una expresión `if` devuelve el valor de la parte que se ejecuta. Si no se ejecuta ninguna (no hay else), devolverá `Null`. Si esto invalida la consistencia de tipos (como se verá más adelante), será necesario definir una parte `else` para garantizar al compilador/intérprete el tipo esperado. + +```hulk +function fib(n:Number):Number -> if (n <= 1) 1 else fib(n-1) + fib(n-2); +``` + +Al igual que con las expresiones `let` y las funciones, cada cuerpo puede ser o bien una expresión o una lista de expresiones. Si no hay parte `else` y ninguna rama condicional se ejecuta, se devuelve `Null`. + +### Ciclos + +La expresión de ciclo más general en **HULK** es un ciclo `while` con la semántica común: + +```hulk +while () +``` + +Como ya es usual, `` puede ser una expresión o una lista de expresiones. + +```hulk +function gcd(a:Number, b:Number):Number { + let q:Number = a%b in while (q != 0) { + a := b; + b := q; + q := a%b; + }; + + b; +} +``` + +El valor de retorno de la expresión `while` es el valor de retorno del cuerpo la última vez que se ejecutó el ciclo, o `Null` en caso de que nunca se ejecute. Si es necesario, se puede adicionar una cláusula `else` para definir el valor cuando no haya ejecución. + +Con esta expresión, la manera más sencilla de implementar un contador (el común ciclo `for`) es: + +```hulk +let i:Number=0 in while (i < n) { + # ... + i := i+1; +} +``` + +### Lidiando con valores `Null` + +Si una variable tiene valor `Null`, se lanzará un error en tiempo de ejecución si se intenta cualquier operación sobre ella (expecto `==` y `!=`). **No** es posible evitar esto comprobando explícitamente: + +```hulk +if (x != Null) x.value else 0 +``` + +Ya que el operador `!=` devuelve `True` siempre que uno de los dos valores sea `Null`. Es decir `Null != Null == True`. Para estos casos, **HULK** introduce una sintaxis específica: + +```hulk +with ( as ) [else ] +``` + +Por ejemplo, en este caso: + +```hulk +with (x as o) o.value else 0 +``` + +La ventaja de esta sintaxis es que dentro del cuerpo de `with` se garantiza que `` nunca será `Null`. Además, la variable `` es **una referencia de de solo lectura** a la expresión ``, y el compilador impide que se le hagan asiganciones. De modo que es posible garantizar que este código nunca lanzará excepción en tiempo de ejecución por accesos o usos de ``. + +### Prioridad de las expresiones + +Las expresiones `let`, `if`, `while`, `case` y `with` tienen **menor prioridad** que todas las expresiones elementales (aritméticas, etc.), y siempre asocian a la derecha. Por lo tanto, para poder usar una de estas expresiones dentro de una expresión aritmética, por ejemplo, se deben encerrar entre paréntesis. + +Por ejemplo, el siguiente es un caso común: + +```hulk +let x:Number=5 in let y:Number=8 in x+y +``` + +Que es equivalente a: + +```hulk +let x:Number=5 in (let y:Number=8 in (x+y)) +``` + +Sin embargo, el siguiente caso **no es válido**, pues no se puede sumar con `let` sin parentizar (`let` tiene menor prioridad): + +```hulk +let x:Number=5 in x + let y:Number=8 in y # NO es valido +``` + +La forma correcta es: + +```hulk +let x:Number=5 in x + (let y:Number=8 in y) +``` + +Por último, el bloque `else` siempre asocia al `if` (o `while`) más cercano. +Es decir, la siguiente expresión: + +```hulk +if (a) if (b) y else z +``` + +Es no ambigua, y equivalente a: + +```hulk +if (a) (if (b) y else z) +``` + +Por otro lado, la invocación de funciones, instanciación, el acceso a miembros (e.g., `self.x`) y el indizado en _arrays_ tienen mayor prioridad que todas las expresiones elementales aritméticas. + +### Orientación a objetos en HULK + +Además de las características estructuradas y funcionales presentadas, el lenguaje **HULK** soporta el concepto de _tipo_, implementado mediante _clases_. Todos los valores creados en un programa de **HULK** tienen un tipo asociado, y este tipo no puede ser cambiado en tiempo de ejecución. Por esto decimos que **HULK** es un lenguaje con tipado estático. + +Aparte de los tipos nativos presentados (`Number`, `Boolean` y `String`), es posible definir nuevos tipos mediante la sintaxis: + +```hulk +class [] [is []] { + [;]* + []* +} +``` + +Todas las clases deben ser definidas **antes** que todas las funciones globales, pero esto _no impide_ que dentro del cuerpo de un método en una clase (explicado más adelante), se llame a una función global, o se use una clase definida posteriormente. + +Todas las clases en **HULK** heredan de una clase base. En caso de no especificarse, esta clase será `Object`, que es la raíz de la jerarquía de tipos en **HULK**. Los tipos básicos `Number`, `String` y `Boolean` también heredan de `Object`, pero a diferencia del resto de las clases, **no es permitido heredar de los tipos básicos**. Esto se restringe ya que los tipos básicos generalmente se implementan de forma especial para garantizar una mayor eficiencia, y por lo tanto deben ser tratados con cuidado en la jerarquía de tipos. + +#### Atributos y métodos + +Dentro del cuerpo de una clase se pueden definir dos tipos de elementos: atributos y métodos. +Los atributos se definen con un nombre, un tipo opcional, y una expresión de inicializacion _obligatoria_ (terminado en `;`): + +```hulk +class Point { + x:Number = 0; + y:Number = 0; +} +``` + +Todos los atributos en **HULK** son **privados**, es decir, no está permitido acceder a ellos desde otras clases, ni desde clases herederas. + +Los métodos se definen con una sintaxis muy similar a las funciones globales. La única diferencia es que en el contexto de un método siempre existe una variable implícita `self` que referencia a la instancia en cuestión. Es obligatorio acceder a los atributos y métodos de una clase a través de `self`, **nunca** usando su nombre directamente. + +```hulk +class Point { + x:Number = 0; + y:Number = 0; + + translate(x,y) -> Point(self.x + x, self.y + y); + length() -> sqrt(self.x * self.x + self.y * self.y); +} +``` + +Todos los atributos deben ser definidos **antes** que todos los métodos, y sus expresiones de inicialización no pueden utilizar métodos de la propia clase, ni valores de otros atributos (aunque sí pueden utilizar funciones globales). Todos los métodos en **HULK** son **públicos** y **virtuales**, redefinibles por los herederos. Además, todos los métodos son de instancia, no existen métodos estáticos, y no existe sintaxis para invocar a un método que no sea a través de una referencia a una instancia de una clase. + +#### Instanciando clases + +Para obtener una instancia de una clase en **HULK** se utiliza el nombre de la clase como si fuera un método, precedido la palabra clave `new`. + +```hulk +let p = new Point() in print(p.translate(5,3).length()); +``` + +Si se desea inicializar los atributos de la clase, se pueden definir _argumentos de clase_, y su valor usarse en la inicialización de los atributos: + +```hulk +class Point(x:Number, y:Number) { + x:Number = x; + y:Number = y; + # ... +} +``` + +Una vez definidos argumentos de clase, es obligatorio proporcionar su valor al construir la clase: + +```hulk +let p:Point = new Point(5,3) in print(p.length()); +``` + +#### Redefinición y polimorfismo + +En **HULK** todas las invocaciones a métodos de una instancia son polimórficas. Todos los métodos en **HULK** son virtuales, y pueden ser redefinidos, siempre que se mantenga la misma signatura (cantidad y tipo de los parámetros y retorno). La redefinición se realiza implícitamente si se define en una clase heredera un método con el mismo nombre de una clase ancestro. + +```hulk +class Person(name:String) { + name:String=name; + greet() -> "Hello" @@ self.name; +} + +class Colleague is Person { + greet() -> "Hi" @@ self.name; +} +``` + +Al heredar de una clase se heredan por defecto las definiciones de los argumentos de clase. Por lo tanto, al instanciar una clase heredera, es obligatorio proporcionar los valores de los argumentos: + +```hulk +let p:Person = new Colleague("Pete") in print(p.greet()); # Hi Pete +``` + +Sin embargo, **no está permitido** usar estos argumentos de clase implícitos en la inicialización de atributos de una clase heredera. Si es necesario usarlos, se pueden redefinir explícitamente en la clase heredera. Por otro lado, siempre que se redefinan argumentos de clase en una clase heredera, será necesario indicar explícitamente cómo se evaluan los argumentos de la clase padre en términos de los argumentos de la clase heredera: + +```hulk +class Noble(title:String, who:String) is Person(title @@ who) { } + +let p = new Noble("Sir", "Thomas") in print(p.greet()); # Hello Sir Thomas +``` + +#### Evaluando el tipo dinámico + +La expresión `case` permite comparar el tipo dinámico de una expresión con una lista de tipos posibles. Su sintaxis es la siguiente: + +```hulk +case of { + [: -> ;]+ +} +``` + +Esta expresión compara el tipo dinámico de `` contra cada uno de los tipos ``, y ejecuta el `` correspondiente a la rama del ancestro más cercano: + +```hulk +class A { } +class B is A { } +class C is B { } +class D is A { } + +case new C() of { + a:A -> print("A"); + b:B -> print("B"); # Se ejecuta esta rama + d:D -> print("D"); +} +``` + +En caso de ninguna rama ser válida en tiempo de ejecución, se lanza un error. En caso de poderse inferir el tipo de ``, se intentará validar la compatibilidad con los tipos ``, y se lanzará un error semántico de existir. El cuerpo de una rama cualquiera puede ser una lista de expresiones entre `{` y `}` si fuera necesario, como sucede con las funciones. + +Existe una versión compacta también de `case` cuando hay una sola rama, con la forma: + +```hulk +case of : -> +``` + +Esta forma puede usarse para evaluar un "downcast" en **HULK**, cuando se conoce con certeza el tipo dinámico de un objeto. + +Por ejemplo, el siguiente programa lanza error semántico pues `o` es de tipo estático `Object`, explícitamente declarado, por lo que no se puede sumar. + +```hulk +function dunno():Object -> 40; + +let o:Object = something() in o + 2; # error semántico +``` + +Sin embargo, usando `case` se puede forzar al verificador de tipos a que infiera `Number` para esta expresión, lanzando error en tiempo de ejecución si realmente el tipo dinámico fuera otro. + +```hulk +function dunno():Object -> 40; + +let o:Object = something() in case o of y:Number -> y + 2; +``` + +Hasta este punto, el lenguaje **HULK** básico definido representa un reto suficientemente interesante como proyecto de un semestre en un curso estándar de compilación. A continuación se definen un conjunto de extensiones que complejizan considerablemente el lenguaje en distintas dimensiones. + +## Extensiones a **HULK** + +En esta sección definimos un conjunto de extensiones a **HULK**. Todas estas extensiones adicionan elementos sintácticos o semánticos al lenguaje. Todas las extensiones están diseñadas para que sean compatibles con el lenguaje **HULK** _básico_, y también compatibles entre sí. De este modo, un compilador de **HULK** puede decidir implementar cualquier subconjunto de estas extensiones. + +### Extensión: Arrays + +Esta extensión introduce un tipo nativo con semántica similar al _array_ de los lenguajes de programación de la familia C. Este _array_ **no crece** dinámicamente y **no es covariante** en la asignación. El _array_ es un tipo genérico que se declara con una sintaxis especial. Como es de esperar, un _array_ se indiza con una expresión de tipo `Number` y el valor del primer índice es `0`. Si el valor del índice no es entero, se lanzará un error en tiempo de ejecución, al igual que si el índice sobrepasa los límites del array. Para los efectos del sistema de tipos, todo tipo _array_ hereda directamente de `Object`, y no se puede heredar de él. +Todos los _arrays_ en **HULK** tienen semántica de enlace por referencia. + +```hulk +let a:Number[] = {1, 2, 3, 4}, i:Number=0 in while (i < a.size()) { + print(a[i]); + i := i+1; +} +``` + +La forma de crear un array vacío es mediante la sintaxis: + +```hulk +let x:Number[] = new Number[20] in ... +``` + +Todo _array_ se inicializa con el valor por defecto del tipo correspondiente, que es `0` para `Number`, `False` para `Boolean`, y `Null` para cualquier otro tipo. En **HULK** no existen _arrays_ multidimensionales, pero sí es posible crear _arrays_ de _arrays_ (_ad infinitum_): + +```hulk +let x:Number[][] = new Number[][10] in ... +``` + +En este caso, el único _array_ que se inicializa es el más externo. Cada valor de `x[i]` se inicializa con `Null` y debe asignarse explícitamente: + +```hulk +let x:Number[][] = new Number[][10], n=0:Number in while(n[] { -> } +``` + +Donde `` es una expresión que devuelve el valor del i-ésimo elemento, indizado por la variable ``. Por ejemplo: + +```hulk +new Number[20]{ i -> 2*i+1 } +``` + +Es equivalente a: + +```hulk +let x:Number[] = new Number[20], i:Number=0 in while (i`. Este contexto es hijo del contexto donde se crea el _array_. En particular, **no tiene acceso** a la variable que referencia al propio _array_ (en caso de existir). Por ejemplo, la siguiente expresión **no** es válida: + +```HUL +# NO es válido +let x:Number[] = new Number[20]{ i -> if (i<=1) 0 + else x[i-1] + x[i-2] } +``` + +Ya que cuando se ejecuta la inicialización, la variable `x` aún no se ha definido. Para poder realizar una construcción de este tipo, introduciremos el uso de la palabra clave `self`, que servirá dentro de una expresión de inicialización para referirse al propio _array_: + +```hulk +# SI es válido +let x:Number[] = new Number[20]{ i -> if (i<=1) 0 + else self[i-1] + self[i-2] } +``` + +Pues es equivalente a: + +```hulk +let x:Number[] = new Number[20], i:Number=0 in while (i new Number[100] { j -> i*j } } +``` + +Que es equivalente a: + +```hulk +let x:Number[] = new Number[][100], i:Number=0 in while (i ... +} +``` + +Si se cumple que `T'i > Ti` y `T'r < Tr`. Es decir, recibe argumentos con tipos iguales o ancestros de los argumentos en la interfaz, y devuelve un tipo igual o descendiente. + +Para el sistema de tipos, si una clase `C` implementa una interfaz `I` con estas condiciones, entonces se considera `C < I`. Por lo tanto, es posible usar como tipos de los argumentos de una interfaz a otras interfaces, mientras que las implementaciones pueden usar tipos concretos, u otras interfaces compatibles. + +### Extensión: Tipos funcionales + +Esta extensión permite definir _tipos_ que representan funciones, y pueden ser utilizadas como ciudadanos de primera clase dentro de la jerarquía de tipos (delegados). + +Un _tipo funcional_ se declara con la sintaxis siguiente: + +```hulk +(, , ...) -> +``` + +Por ejemplo, para la función siguiente: + +```hulk +function fib(n:Number): Number -> if (n<=1) 1 else fib(n-1) + fib(n-2); +``` + +Una anotación de su tipo sería: + +```hulk +(Number) -> Number +``` + +Estas anotaciones sirven para declarar tipos funcionales que pueden ser usados entonces como argumentos o valores de retorno en otras funciones, o almacenados en variables: + +```hulk +let f:(Number)->Number = fib in ... +``` + +Nótese como se puede utilizar entonces el identificador `fib` (nombre de la función) como referencia a una instancia de un tipo funcional `(Number)->Number`. +Una vez obtenida una referencia a un tipo funcional, se puede utilizar exactamente como cualquier otro valoren **HULK**, es decir, ser pasado como parámetro a un método, almacenado en un _array_ (si se implementa esta extensión), o _invocado_. + +Para invocar un tipo funcional se usa la misma sintaxis que para invocar directamente una función global: + +```hulk +let f:(Number)->Number = fib in print(f(6)); +``` + +De la misma forma se pueden definir funciones con argumentos de tipos funcionales. Por ejemplo, si se implementan _arrays_, la siguiente función es posible: + +```hulk +function map(a:Number[], f:(Number)->Number):Number[] { + new Number[array.size()] { i -> f(a[i]) }; +} +``` + +Desde el punto de vista semántico, el tipo funcional anterior se comporta _como si_ existiera una interfaz como la siguiente, y una clase respectiva que implementara la interfaz: + +```hulk +interface NumberNumberFunction { + invoke(arg1:Number): Number; +} + +class FibFunction { + invoke(arg1:Number): Number -> fib(arg1); +} +``` + +Y el uso o invocación de este tipo funcional pudiera verse _como si_ se empleara de la siguiente forma: + +```hulk +let f:NumberNumberFunction = new FibFunction() in print(f.invoke(6)); +``` + +Con la particularidad de que, por supuesto, estas _supuestas_ clases e interfaces no son accesibles por el código usuario directamente, sino solo a través de la sintaxis definida anteriormente. + +Los tipos funcionales son invariantes tanto en los tipos de los argumentos como en el tipo de retorno. + +### Extensión: Funciones anónimas (expresiones _lambda_) + +Esta extensión introduce funciones anónimas, también conocidas como expresiones _lambda_. Una función anónima es una expresión cuyo tipo es un funcional. Sintácticamente se declaran muy parecido a las funciones globales, excepto que no es necesario indicar un nombre. Semánticamente, las funciones anónimas son expresiones, por lo que pueden ser usadas donde se requiera un funcional. +Por ejemplo, en una declaración de variables: + +```hulk +let f:(Number)->Number = function (x:Number):Number -> x * 2 in print(f(3)); +``` + +O directamente como parámetro a una función o método: + +```hulk +function map(a:Number[], f:(Number)->Number) { + new Number[]{ i -> f(a[i]) }; +} + +print(map(new Number[20]{ i -> i }, function (x:Number):Number -> x+2)); +``` + +Al igual que las funciones globales, el cuerpo puede ser una expresión simple o un bloque de expresiones. + +### Extensión: Clausura funcional + +Esta extensión adiciona a las expresiones _lambda_ un mecanismo de clausura que permite capturar variables existentes en el contexto de la función automáticamente. + +```hulk +let x:Number=3, f:(Number)->Number = function (y:Number):Number -> y * x in + print(f(5)); # 15 +``` + +La captura se realiza **por copia** siempre, por lo que las variables capturadas **no mantienen su valor** luego de ejecutada la función. +Sin embargo, la variable capturada visible dentro de la función anónima **si mantiente su valor** de una ejecución a la siguiente: + +```hulk +let x:Number=1 in + let f:(Number)->Number = function (y:Number):Number { + x := x + 1; + y * x; + } in { + print(f(3)); # Imprime 6 + print(f(5)); # Imprime 15 + print(x); # Imprime 1 + }; +``` + +Semánticamente, la clausura se comporta como si en el momento de definir la función anónima se copiaran los valores de las variables capturadas a campos internos de una _supuesta_ clase que representa el funcional. El ejemplo anterior sería equivalente semánticamente al siguiente código: + +```hulk +interface NumberNumberFunction { + invoke(arg1:Number):Number; +} + +class LambdaFunction1(x:Number) is NumberNumberFunction { + x:Number = x; + invoke(arg1:Number):Number { + self.x := self.x + 1; + y * self.x; + } +} + +let x:Number=1 in + let f:NumberNumberFunction = LambdaFunction1(x) in { + print(f.invoke(3)); # Imprime 6 + print(f.invoke(5)); # Imprime 15 + print(x); # Imprime 1 + }; +``` + +De esta forma se garantiza que el valor de `x` fuera de `f` no sea modificado, sin embargo, todas las ejecuciones de `f` comparten una misma referencia al `x` interno. + +### Extensión: Funciones genéricas + +Esta extensión introduce funciones globales con argumentos de tipos genéricos. Un tipo genérico se define con la sintaxis `'T` donde `T` es un identificador. Los tipos genéricos pueden usarse en tipos complejos (por ejemplo, un _array_, un tipo funcional, etc.). Una función genérica puede declarar como tipo de uno o más de sus argumentos un tipo genérico. + +```hulk +function map(a:'T[], f:('T)->'R): 'R[] { + new T'[] { i -> f(a[i]) }; +} +``` + +Los tipos genéricos se consideran declarados en los argumentos de la función. Dentro del cuerpo de una función genérica se pueden utilizar los tipos genéricos como si fueran tipos concretos. En el momento en que se realice una invocación de la función, los tipos genéricos declarados se realizarán en un tipo concreto. + +A los efectos semánticos, es como si cuando se realizara una invocación, se definiera en ese momento una versión de la función con los tipos concretos. + +### Extensión: Generadores (iteradores) + +Esta extensión adiciona una sintaxis para usar generadores (también llamados iteradores). Un generador es cualquier clase que implemente dos métodos: `next()` y `current()`. El método `next()` devuelve `Boolean` y su función es avanzar el iterador. El método `current()` devuelve un tipo arbitrario y retorna el elemento "actual" del generador. Por ejemplo: + +```hulk +class Range(start:Number, end:Number) { + i:Number = start; + next():Boolean { + self.i += 1; + self.i <= end; + } + current():Number -> self.i - 1; +} +``` + +Cualquier clase que posea estos dos métodos puede ser usada con la siguiente sintaxis: + +```hulk +for (: in ) +``` + +Por ejemplo: + +```hulk +for (x:Number in new Range(0,100)) print(x); +``` + +Esta expresión enlaza una variable `x` al valor `current()` del generador en cada iteración, y ejecuta la expresión correspondiente. Al igual que todas las expresiones con cuerpo (`let`, `while`), es posible usar una expresión simple o un bloque de expresiones. + +La expresión `for` es sintácticamente equivalente a una construcción como la siguiente: + +```hulk +let _iter:= in while (_iter.next()) { + let :=_iter.current() in ; +} +``` + +Por ejemplo, en este caso: + +```hulk +let _iter:Range=new Range(0,100) in while(_iter.next()) { + let x:Number=_iter.current() in print(x); +}; +``` + +### Extensión: Tipos generadores + +Esta extensión adiciona una familia especial de tipos, los tipos generadores, que son covariantes con cualquier clase que implemente una interfaz de generador adecuada. + +Un tipo generador se declara con la sintaxis: + +```hulk +* +``` + +Donde `` es un tipo cualquiera. Por ejemplo `Number*`, `Boolean*`, `Number[]*`, y por supuesto, `Number**` y cualquier otra composición. Los tipos generadores pueden usarse como tipo estático de una variable o parámetro donde se espere un generador, y son compatibles (covariantes) con cualquier tipo (clase) que cumpla la interfaz de generador correspondiente. + +Por ejemplo, la siguiente clase cumple con la interfaz de un generador de tipo `Number*`: + +```hulk +class Range(start:Number, end:Number) { + i:Number = start; + next():Boolean { + self.i += 1; + self.i <= end; + } + current():Number -> self.i - 1; +} +``` + +Por lo tanto, puede ser usado en el siguiente fragmento: + +```hulk +function sum(items:Number*) { + let s:Number=0 in for(x:Number in items) s:=s+x; +} + +print(sum(new Range(1,100))); # 4950 +``` + +De esta forma es posible escribir funciones "genéricas" con respecto a los tipos generadores, es decir, donde no sea necesario conocer de antemano el tipo concreto que implementa la interfaz de generador. Además, es posible escribir funciones que devuelvan tipos generadores y de esta forma simplificar la sintaxis: + +```hulk +function range(start:Number, end:Number):Number* -> new Range(start, end); + +for (x in range(1,100)) print(x); +``` + +Las variables y parámetros declarados con un tipo generador pueden ser usados en una expresión `for`, pero además, es posible interpretarlos como una _supuesta_ clase con métodos `next()` y `current()`, ya que la implementación "real" es esta. Por lo tanto, el siguiente código es válido: + +```hulk +let items:Number* = range(1,100) in items.next(); +``` + +Aún cuando no sea posible acceder estáticamente al tipo concreto que implementa el generador, es sabido que tendrá al menos los métodos `next()` y `current()` con la semántica esperada, por lo que es posible implementar funciones importantes tales como: + +```hulk +function empty(items:Number*) -> !items.next(); +``` + +O patrones como este: + +```hulk +class Take(items:Number*, k:Number) { + items:Number* = items; + k:Number = k; + + next():Boolean -> if (k>0) self.items.next() else False; + current():Number -> self.items.current(); +} + +function take(items:Number*, k:Number):Number* -> Take(items,k); +``` + +### Extensión: Expresiones generadoras + +Esta extensión añade una sintaxis para definir expresiones generadoras, es decir, expresiones que pueden usarse con la sintaxis `for`, cuyo tipo estático será un tipo generador. + +Una expresión generadora tiene la forma: + +```hulk +{ | in } +``` + +Donde `` es una expresión que involucra la variable ``, y `` captura el valor de retorno de ``, que debe ser una de las siguientes expresiones: + +- Un tipo generador. +- Un ciclo `while`. +- Un ciclo `for`. +- Una expresión `let` cuyo cuerpo es una de las anteriores. + +Los siguientes ejemplos son todos válidos: + +- Tipo generador explícito: + ```hulk + { 2*x | x in new Range(1, 100) } + ``` + +- Función que devuelve un tipo generador: + ```hulk + { x+1 | x in range(1, 100) } + ``` + +- Ciclo `while` (infinito en este caso): + ```hulk + { exp(x) | x in while (True) random() } + ``` + +- Ciclo `for` (anidado en este caso): + ```hulk + { x | x in for (i in range(1, 100)) + for (j in range(1, 100)) + i*j } + ``` + +- Expresión `let` con un ciclo en el cuerpo: + ```hulk + { x | x in let i:Number=0 in while (i < 100) { + i := i + 1; + random(); }} + ``` + +La variable `` tendrá sucesivamente todos los valores "producidos" para la expresión de iteración. + +Un expresión generadora es semánticamente equivalente a una clase que implemente el tipo generador correspondiente (al tipo estático de `x`), y cuya implementación de los métodos `next()` y `current()` corresponda al comportamiento definido. El mecanismo exacto para lograr esta transpilación es demasiado complejo para formalizarlo en esta sección, pero daremos un ejemplo ilustrativo. + +De manera general, el cuerpo del método `next()` corresponderá a la implementación de ``, desenrrollada de forma tal que cada paso se ejecute en un llamado correspondiente, mientras que el cuerpo de `current()` corresponderá a la expresión `` de retorno del generador. + +Por ejemplo, para la siguiente expresión: + +```hulk +{ exp(x) | x in let i:Number=0 in while (i < 100) { + i := i + 1; + random(); }} +``` + +Una posible implementación será el siguiente tipo generador: + +```hulk +class Generator { + x:Number = 0; # Variable que almacenará current + i:Number = 0; # Inicialización de la expresión let + + next():Boolean { + if (!(self.i < 100)) False + else { + self.i := self.i + 1; + self.x := random(); + True; + }; + } + + current():Number -> exp(self.x); +} +``` + +En el caso de que el cuerpo de una expresión generadora sea un generador directamente, o un ciclo `for`, existen formas de convertirlo a un patrón `let-while` básico. De esta forma todas las expresiones generadoras pueden reescribirse como **HULK** básico. + +Al igual que en las funciones anónimas, las variables externas referenciadas dentro de la clausura de una expresión generadora se capturan **por copia**. Por lo tanto, su modificación dentro de una expresión generadora no se percibe fuera de la expresión: + +```hulk +let i:Number = 0, + items:Number* = { x | x in while (i<10) i := i+1 } +in { + for (x:Number in items) print(x); # Imprime 1 ... 10 + print(i); # Imprime 0 +} +``` + +### Extensión: Inicialización de _arrays_ con generadores + +Esta extensión permite inicializar un _array_ a partir de un generador, mediante la sintaxis: + +```hulk +new [] +``` + +Por ejemplo, usando directamente un tipo generador: + +```hulk +new Number[range(1, 100)] +``` + +O una expresión generadora (en caso de implementarse): + +```hulk +new Number[{ 2*x | x in range(1, 100) }] +``` + +Nótese que esta sintaxis **no es** equivalente a la inicialización automática de _arrays_. En primer lugar no es necesario indicar el tamaño del _array_, pues se ejecutará el generador para saber el tamaño real necesario. Por otro lado, no es posible referirse al propio _array_ que se está inicializando en la expresión generadora, ya que el _array_ conceptualmente no existe hasta que no se haya terminado de generar toda la expresión. + +### Extensión: Inferencia de tipos + +Esta extensión introduce inferencia de tipos en **HULK**, de modo que no sea necesario especificar todas las anotaciones de tipos, si son inferibles dado el contexto. Formalizar precisamente en qué casos es posible inferir o no el tipo de una declaración es un problema complicado, y no lo intentaremos en este punto. Por el contrario, presentaremos algunos ejemplos donde es posible inferir el tipo, y otros ejemplos donde el mecanismo de inferencia de tipos de **HULK** no será capaz de deducirlo. + +El caso más sencillo, es cuando en una declaración de variable se omite el tipo. En este caso, el tipo se infiere de la expresión de inicialización: + +```hulk +let x=3+2 in case x of y:Number -> print("Ok); +``` + +De igual forma sucede con los atributos de una clase, cuando pueden ser inferidos por el tipo de la expresión de inicialización: + +```hulk +class Point(x:Number, y:Number) { + x=x; + y=y; + # ... +} +``` + +Un caso más complejo es cuando se deja sin especificar el tipo de retorno de una función, pero puede ser inferido a partir de su cuerpo: + +```hulk +function succ(n:Number) -> n + 1; +``` + +En el caso anterior, es fácil inferir el tipo de retorno de `succ` porque la expresión retorna exactamente el mismo tipo que un argumento. En estos casos, es posible incluso no especificar el tipo del argumento, ya que el operador `+` solo está definido para `Number`: + +```hulk +function succ(n) -> n + 1; +``` + +Sin embargo, a veces no es posible inferir el tipo de un argumento a partir de su uso _dentro del cuerpo_ de una función. En el caso siguiente, aunque sabemos que el tipo del argumento `p` debe ser `Point` para aceptar la invocación, _no se garantiza_ que el mecanismo de inferencia de tipos deba deducirlo (ya que en el futuro puede haber otras clases con un método `translate`). Dependiendo de la implementación, en estos casos se permite lanzar error semántico indicando que no fue posible inferir el tipo del argumento `p`. + +```hulk +function step(p) -> p.translate(1,1); + +let p = new Point(0,0) in step(p); # Puede lanzar error semántico +``` + +Por último, especial complejidad acarrean las funciones recursivas: + +```hulk +function fact(n) -> if (n<0) 1 else n*fact(n-1); +``` + +El ejemplo anterior permite inferir simultáneamente el tipo del argumento `n` y del retorno, ya que se usa el retorno de la función recursiva en una operación `+` que solo está definida para `Number`. Sin embargo, en el ejemplo siguiente: + +```hulk +function ackermann(m, n) -> + if (m==0) n+1 + elif (n==0) ackermann(m-1, 1) + else ackermann(m-1, ackermann(m, n-1)); +``` + +Como el tipo de retorno no se utiliza explícitamente en una operación matemática, no es trivial deducir que su tipo de retorno es `Number`, ya que `Object` funcionaría también como tipo de retorno. En estos casos, se desea que el mecanismo de inferencia deduzca _el tipo más concreto_ para el retorno y _el tipo más abstracto_ para los argumentos que sea posible. + +Finalmente, dos funciones mutuamente recursivas: + +```hulk +function f(a, b) -> is (a==1) b else g(a+1, b/2); +function g(a, b) -> if (b==1) a else f(a/2, b+1); +``` + +En este caso, es posible teóricamente inferir que `f` y `g` deben ambos retornar tipo `Number`, pero dada la complejidad de manejar la inferencia de tipos en más de una función a la vez, no se garantiza que sea posible deducir los tipos en este caso. + +Varias de las extensiones de **HULK** introducen tipos nuevos, por ejemplo, _arrays_, tipos generadores y tipos funcionales. En caso de implementar algunas de estas extensión, la inferencia de tipos también se debe extender de forma correspondiente. + +Cuando se crea un _array_, es posible inferir el tipo estático si se provee una expresión de inicialización: + +```hulk +let x = new [20]{ i -> (i+1)*(i+2) } in ... # Infiere Number +``` + +Sin embargo, si en la expresión de inicialización se usa el propio _array_, entonces no se garantiza que sea posible inferir el tipo: + +```hulk +let x = new [20]{ i -> if (i<=1) 1 else x[i-1] + x[i-2] } in ... +``` + +Cuando se define un tipo funcional, el tipo puede ser inferido a partir de la declaración de una función global: + +```hulk +function fib(n) -> if (n <= 1) 1 else fib(n-1) + fib(n-2); + +let f=fib in print(f(3)); # f infiere (Number) -> Number +``` + +Cuando se define una función anónima, el tipo puede ser inferido a partir de su cuerpo: + +```hulk +let f = function (x) -> x % 2 == 0 in print(f(10)); +``` + +En ocasiones, se puede inferir el tipo de un parámetro a partir del tipo de la variable donde es almacenada la función anónima: + +```hulk +let f:(Person)->Boolean = function (p) -> p.name() == "John" in ... +``` + +En este caso hipótetico el compilador infiere `Person` para el argumento `p` gracias a la declaración de `f`, por lo que reconoce `p.name` como un método válido en esta clase. + +En una expresión `for` el tipo de la variable puede ser inferido a partir del tipo del generador: + +```hulk +function range(start:Number, end:Number):Number* { + new Range(start,end); +} + +for (x in range(1,100)) print(x); # x infiere Number +``` + +Para las expresiones generadoras, el tipo puede ser inferido a partir del tipo de la variable generada. Por ejemplo, en el siguiente caso, el tipo inferido para `x` es `Number`, pues es el tipo de retorno del ciclo `while` (función `random()`). +El tipo inferido para la expresion `exp(x) < 0` es `Boolean`. +Por lo tanto el tipo inferido para toda la expresión `Boolean*`. + +```hulk +# g infiere Boolean* +let g = { exp(x) < 0 | x in let i:Number=0 in + while (i < 100) { + i := i + 1; + random(); }} in ... +``` + +### Extensión: _Null-safety_ + +Gracias a la existencia de la instrucción `with`, un compilador de **HULK** puede ser capaz de inferir para un programa si es seguro garantizar que no habrá errores en ejecución por variables `Null`. Es posible entonces que un compilador genere en estos casos un código más eficiente, al no tener que validar las referencias en todos los accesos y usos. En todos los casos en que no se pueda garantizar la _null-safety_, el compilador debe emitir una advertencia en tiempo de compilación (_warning_). + +Opcionalmente, el compilador de **HULK** puede ejecutarse en modo **null-safe**. En este modo, las advertencias por violación de _null-safety_ se convierten en errores de compilación. + +Nótese que no es estrictamente necesario usar `with` en todos los casos para garantizar la _null-safety_. Hay casos en que por el contexto es posible garantizar la seguridad. +El caso más sencillo es cuando se usan variables de tipo `Number` o `Boolean`, que por definición no pueden contener un valor `Null`. + +Un caso más interesante es cuando se puede inferir por la inicialización de una variable, por ejemplo: + +```hulk +let x = new Person("John Doe") in print(x.greet()); +``` + +En este caso se puede inferir que `x` nunca será `Null` pues no existe ninguna asignación, y el valor de la expresión `new Person(...)` nunca es `Null`. + +Por el contrario, si se usa un ciclo o una expresión `if` sin parte `else`, no es posible garantizar _null-safety_, incluso cuando realmente el valor de la expresión no pueda ser `Null`. + +```hulk +let i=10, x=(while (i > 0) i:=i-1) in print(x); +``` + +Así mismo, en los argumentos de una función nunca será posible garantizar _null-safety_. + +De manera general el compilador de **HULK** hará todo lo posible por inferir si cada uso es _null-safe_, incluso cuando no se introduzca una expresión `with`. En los casos en que no sea posible inferirlo, el programador siempre podrá introducir una expresión `with` para satisfacer al compilador. + +### Extensión: Macros + +Esta extensión introduce un sistema limitado de macros en tiempo de compilación con verificación semántica. Una función macro es similar a una función estándar (global) en sintaxis, pero se define con la palabra clave `define`: + +```hulk +define dmin(x:Number, y:Number):Number -> if (x <= y) x else y; +``` + +La diferencia más directa radica en que las funciones macro se evalúan en tiempo de compilación, y se expanden directamente en el lugar donde se usan. Por ejemplo, para el caso anterior, si se usa de la siguiente manera: + +```hulk +print(min(3,4)); +``` + +En tiempo de compilación se sustituirá el código anterior directamente por el resultado de expandir la función macro, lo que sería equivalente a haber escrito: + +```hulk +print(if (3 <= 4) 3 else 4); +``` + +Una diferencia adicional entre las funciones macro y las funciones estándar, es que en las funciones macro los parámetros **no se evalúan**, sino que se expanden directamente en el cuerpo del macro. Por ejemplo: + +```hulk +print(min(3+2, 4+5)); +``` + +Expande a: + +```hulk +print(if ((3+2) <= (4+5)) (3+2) else (4+5)); +``` + +Otra diferencia que se desprende directamente de esta definición, es que los parámetros de una función macro **no son _l-values_**, por lo que no es posible asignarles una expresión. + +Esto cambia considerablemente el comportamiento en comparación con una función estándar global si un parámetro tiene efectos colaterales. +Por ejemplo, supongamos las siguientes declaraciones: + +```hulk +function fmin(x:Number, y:Number):Number -> if (x if (x 0) { + x := x - 1; + y; + }; +} + +let y:Number=0 in print(repeat(10, y:=y + 1)); +``` + +El resultado de invocar a `repeat` es `1` pues **primero** se evalúa `y := y + 1` y luego se pasa este valor por copia a `repeat`. Sin embargo, si se define como una función macro: + +```hulk +define repeat(x:Number, y:Number):Number { + let i:Number=x in while (i > 0) { + i := i - 1; + y; + }; +} + +let y:Number=0 in print(repeat(10, y:=y + 1)); +``` + +En este caso la expansión de `repeat` genera un código semánticamente equivalente al siguiente: + +```hulk +let y:Number=0 in print( + let i:Number=10 in while (i > 0) { + i := i - 1; + y := y + 1; + } +); +``` + +En este caso el valor de `y` será `10`, pues la expresión `y := y + 1` se ejecuta **todas** las iteraciones del ciclo, en **el mismo contexto** donde se expande el macro. +Este efecto simplemente no es posible en **HULK** usando solo funciones, ni siquiera con expresiones _lambda_, pues el paso de parámetros siempre es **por copia**. + +Una función macro al expandirse puede generar un bloque de expresiones. Aunque en **HULK** no es permitido al usuario escribir directamente un bloque de expresiones en cualquier lugar (por ejemplo, como valor de un parámetro), esta es una restricción sintáctica, impuesta por el _parser_. Desde el punto de vista semántico los bloques de expresión se comportan como expresiones cuyo tipo y valor de retorno son los de la última expresión del bloque. + +La expansión de un macro **no es** una simple sustitución léxica del cuerpo del macro en el lugar donde se invoca. Por el contrario, la expansión es sintáctica, y se realiza a nivel de AST. Esto significa que no es necesario que una definición de macro se preocupe por parentizar expresiones o poner `;` adicionales "por si acaso", pues en el momento de la expansión del macro, los elementos léxicos ya no importan. + +Por otro lado, las funciones macros deben ser _higiénicas_, esto significa que **no pueden contaminar** el contexto donde se expanden con símbolos que puedan cambiar la semántica. Por este motivo, **todas las variables** declaradas dentro de un macro (ya sea en expresiones `let`, `for`, etc.) deben ser renombradas a símbolos internos que no puedan coincidir con los símbolos escritos por el programador. Si esto no se hiciera, entonces pudiera suceder que nombres de símbolos expandidos por el macro ocultaran símbolos del contexto. +Por ejemplo: + +```hulk +let i:Number=0 in repeat(10, i := i + 1); +``` + +Generaría: + +```hulk +let i:Number=0 in + let i:Number=10 in while (i>0) { + i := i - 1; + i := i + 1; + } +``` + +Con lo cual el ciclo no terminaría nunca. +Por este motivo realmente la sustitución debe generar un código más parecido al siguiente: + +```hulk +let i:Number=0 in + let #var0:Number=10 in while (#var0>0) { + #var0 := #var0 - 1; + i := i + 1; + } +``` + +Donde `#var0` es un identificador generador dinámicamente que no puede ser escrito por el usuario (por restricciones del _lexer_). De esta forma se garantiza que la expansión de un macro nunca introduzca símbolos que oculten otros símbolos en el contexto donde se usen. Esta sustitución **debe hacerse automáticamente**, es decir, en la definición del macro se puede declarar un símbolo `i` que será automáticamente sustituido por `#varX` o cualquier otro convenio similar. + +El proceso de expansión de un macro puede terminar en una expresión que aún contenga macros. Estos macros volverán a ser expandidos, recursivamente, hasta que no quede ningún macro por expandir. Si este proceso produce una recursión infinita (en la práctica, una cantidad elevada de expansiones), se lanzará un error en tiempo de compilación. Idealmente, si es posible detectar durante el chequeo semántico del macro la posibilidad de una expansión infinita, se debe lanzar un error o _warning_. + +### Extensión: Bloques macro + +Esta extensión permite invocar a las funciones macro con una sintaxis especial, donde el último parámetro puede ser definido fuera de los paréntesis de la invocación. Siguiendo con el mismo ejemplo de la sección anterior (macro `repeat`), esta extensión permitiría invocarlo de la forma: + +```hulk +let y:Number=0 in repeat (10) y:=y+1; +``` + +O de la forma: + +```hulk +let y:Number=0 in repeat (10) { + y:=y+1; +}; +``` + +Es decir, la expresión (o bloque de expresiones) que sigue a una función macro se usa como el último parámetro del macro. Esto permite simular en **HULK** construcciones sintácticas como la anterior, que parecen nativas del lenguaje, sin perder la verificación semántica ni la inferencia de tipos (opcional) que funciona en el resto de **HULK**. +Veamos algunas macros interesantes que se pueden implementar con esta idea. + +Es posible simular expresiones condicionales distintas, como la siguiente: + +```hulk +define unless (cond:Boolean, expr:Object):Object -> if (!cond) expr; +``` + +Que se puede usar de la siguiente forma: + +```hulk +let msg:String=read() in unless (msg=="Exit") { + print("Hello World"); +}; +``` + +También es posible simular distintos sabores de ciclos, como este: + +```hulk +define until (cond:Boolean, expr:Object):Object -> while(!cond) expr; +``` + +Que se podría usar de la siguiente manera: + +```hulk +let x:Number=10 in until (x == 0) { + x := x - 1; + print(x); +}; +``` + +### Extensión: Patrones de expresiones en macros + +Esta extensión añade un mecanismo de _pattern matching_ para expresiones dentro de los macros. Este mecanismo permite definir macros cuya expansión dependa de la estructura sintáctica de los argumentos. Para ello introduciremos una expresión `match` que **solo** puede ser usada en macros. Esta expresión permite _deconstruir_ la estructura sintáctica de una expresión arbitraria `e` y tomar decisiones en función de los elementos que la componen. + +Veamos un ejemplo un tanto esotérico para introducir los elementos básicos de la sintaxis de patrones. Supongamos que queremos definir un macro `simplify` que recibe una expresión aritmética y devuelve una expresión de igual valor pero simplificada. Las reglas para simplificar serán muy sencillas: si es una expresión `+`, entonces si una de las dos partes es `0`, me quedo con la otra, y si es una expresión `*` entonces si una de las dos partes es `1` me quedo con la otra. En otro caso la expresión se mantiene igual. + +```hulk +define simplify(e:Number):Number { + match e with { + e1:Number + Number(0) -> simplify(e1); + e1:Number * Number(1) -> simplify(e1); + Number(0) + e1:Number -> simplify(e1); + Number(1) * e1:Number -> simplify(e1); + e1:Number -> e1; + }; +} +``` + +En esta sintaxis, similar a `case`, la expresión `e` se compara _estructuralmente_ (en términos del AST) con cada uno de los patrones (las expresiones en la parte izquierda de `->`). Para el **primer** patrón que sea compatible se expande entonces la expresión en la parte derecha de `->`. Si ningún patrón es compatible, se lanzará un error en tiempo de compilación durante la expansión del macro, indicando que ninguna de las formas esperadas era compatible. +Para indicar _valores literales_ (`Boolean`, `Number` y `String`) usaremos una sintaxis como la mostrada (e.g., `Number(4)` o `String("Hello World")`). + +La compatibilidad se realiza mediante una _unificación_ recursiva del AST de `e` con el AST de cada patrón. En este proceso, las variables (`e1` en el ejemplo) que existan en el patrón se unificarán con los sub-árboles correspondientes del AST. +Las "variables" `e1`, `e2`, etc., que unificarán con sub-árboles del AST, deben anotarse con un tipo que indica el tipo más abstracto esperado. Es decir que `e:Object` unifica con cualquier árbol. + +Por ejemplo: + +```hulk +simplify (1 * 3 + 0); +``` + +En este caso el primer patrón es compatible, siendo `e1` unificado con `(1 * 3)`, por lo que se obtiene la expansión: + +```hulk +simplify(1 * 3); +``` + +Como en esta expansión aún quedan macros, se vuelve a expandir `simplify` siendo compatible el cuarto patrón, `e1` unificando con `3`. La expansión final queda entonces: + +```hulk +3; +``` + +Nótese que la unificación puede funcionar si se asigna a la misma variable ASTs con estructura idéntica. Por ejemplo, si deseamos añadir como patrón que `x + x` se convierte en `2*x`, podemos definir el macro como: + +```hulk +define simplify(e:Number):Number { + match e with { + # ... los casos vistos anteriormente + e1:Number + e1:Number -> 2 * e1; + e1:Number -> e1; + }; +} +``` + +En este caso se unificará solamente si ambas partes de la expresión `+` tienen exactamente la misma estructura, por ejemplo `3*2 + 3*2` unifica `e1` con `3*2`, pero `3*2 + 2*3` no funciona, ya que aunque semánticamente ambas sub-expresiones tendrán el mismo valor, no tienen exactamente la misma estructura sintáctica para los respectivos AST. + +Todas las expresiones de **HULK** _que no definen símbolos_ son usables como patrones en una expresión `match`, y para cada una la sintaxis como patrón se corresponde naturalmente con la sintaxis como expresión. Es decir, `let`, `for`, las expresiones generadoras, las expresiones _lambda_ y las expresiones de inicialización de _array_ **no pueden** ser usadas como patrones. +También es posible unificar con una expresión compleja. En este caso, se verificará recursivamente cada parte de la expresión. +Algunos ejemplos: + +```hulk +# ... +match e with { + e1:Number + e2:Number -> ... # Expresiones + e1:Number * e2:Number -> ... # aritméticas simples o + e1:Number + (e2:Number - e3:Number) -> ... # complejas, + while (e1:Boolean) e2:Object -> ... # Ciclos, + if (c:Boolean) e1:Object -> ... # Condicionales sin o + if (c:Boolean) e1:Object else e2:Object -> ... # con parte else, + x:Number -> ... # Variables, + Number(5) -> ... # Literales, + Person(n:String) -> ... # Instanciación, + e1:Object := e2:Object -> ... # Asignación, + fib(e1:Number) -> ... # Invocación a funciones + e1:Person.greet() -> ... # y métodos de instancia. +} +``` + +Para el caso de los bloques de expresiones, es posible unificar directamente con un bloque de expresión que tiene una cantidad exacta de elementos: + +```hulk +match e with { + { e1:Object ; e2:Object ; e3:Object } -> ... +} +``` + +Sin embargo, en ocasiones no se sabe de antemano la cantidad de expresiones que tendrá el bloque. Para estos casos, definiremos una sintaxis especial que permite _deconstruir_ un bloque de expresiones con **más de 1 elemento** en 2 partes: la primera expresión, y un bloque de expresiones restante. Esto permite aplicar recursivamente un macro a un bloque de expresiones de longitud arbitraria: + +```hulk +define simplify(e:Number):Number { + match e with { + # ... los casos vistos anteriormente + { e1:Number | e2:Number } -> { simplify(e1) ; simplify(e2) }; + } +} +``` + +En esta nueva sintaxis, el operador `|` sirve para indicar la concatenación de la primera expresión con el resto del bloque de expresiones. Nótese que para que esto funcione, `e2` no puede ser un bloque vacío, es decir, `e` originalmente contenía al menos 2 expresiones. Nótese que en esta situación el código expandido tendría la forma `{ e1 ; { e2; { e3; ...} } }`, es decir, los bloques se irían anidando a medida que se ejecuta el macro recursivamente. Sin embargo, `{ e1; { e2; } }` es semánticamente equivalente a `{ e1; e2 }` siempre, por lo que el compilador es libre de "desenredar" esta anidación de bloques de expresiones de forma automática. +Además, para que el caso base funcione, el compilador debe considerar un bloque con una sola expresión `{ e; }` equivalente a la misma expresión `e` por si sola. + +El _pattern matching_ en macros que hemos definido en esta extensión es uno de las técnicas más poderosas de meta-programación que se pueden lograr en un lenguaje con tipado estático. Nótese que el compilador puede tener que realizar un procesamiento potencialmente ilimitado (excepto por efectos prácticos en los límites de la recursividad). Aunque no lo hemos demostrado formalmente, el mecanismo de macros definido con _pattern matching_ es Turing-completo. Una manera relativamente fácil de entender por qué, es notar que es posible codificar cualquier máquina de Turing como una secuencia de expresiones, representando los estados y los valores de la cinta mediante constantes. A base de _pattern matching_ y expansiones de macro recursivas, es posible simular cualquier máquina de Turing _en tiempo de compilación_. + +A modo de ejemplo veamos cómo resolver el conocido problema de identificar si una secuencia de números `0` o `1` representa un número en binario divisible por `3`. Este es un conocido lenguaje regular, cuyo autómata tiene `3` estados que representan los posibles restos con `3`. La función macro siguiente simula este autómata (la presentaremos sin demostración): + +```hulk +define multiple3(state:Number, value:Number):Boolean { + match state with { + Number(0) -> match value with { + Number(0) -> True; + Number(1) -> False; + { Number(0) | rest:Number } -> multiple3(0, rest); + { Number(1) | rest:Number } -> multiple3(1, rest); + }; + Number(1) -> match value with { + Number(0) -> False; + Number(1) -> True; + { Number(0) | rest:Number } -> multiple3(2, rest); + { Number(1) | rest:Number } -> multiple3(0, rest); + }; + Number(2) -> match value with { + Number(0) -> False; + Number(1) -> False; + { Number(0) | rest:Number } -> multiple3(1, rest); + { Number(1) | rest:Number } -> multiple3(2, rest); + }; + }; +} +``` + +Este macro se puede ejecutar de la siguiente forma: + +```hulk +multiple3 (0) { 1; 1; 0; }; +``` + +Y se expandiría directamente al literal `True`, computando _en tiempo de compilación_ un problema de la palabra en un lenguaje regular. No es muy complicado ver como extender esta idea a simular una máquina de Turing. Solo es necesario "llevar la cuenta" de la posición del cabezal. + +## Formalización del lenguaje HULK + +En esta sección presentaremos una descripción formal de **HULK**, en términos sintácticos, semánticos y operacionales. Esta sección debe servir como referencia para la construcción de un compilador de **HULK**, pero recomendamos las secciones anteriores que explican de forma más intuitiva todos los elementos relevantes del lenguaje. + +### Sintaxis de HULK + +Una gramática posible para **HULK** se muestra a continuación. Nótese que por motivos didácticos, esta gramática es ambigua. En particular, la asociatividad y prioridad de los distintos tipos de expresiones se deja sin resolver, para dar espacio a los estudiantes a que resuelvan estos problemas. + +Los terminales de **HULK** son: + +```Grammar +NUMBER := [0-9]+(.[0-9]+)? +STRING := " UNICODE* " # Todos los caracteres unicode válidos +BOOLEAN := True | False +LITERAL := NUMBER | STRING | BOOLEAN +ID := [a-zA-Z_][a-zA-Z0-9]* +``` + +Un programa en **HULK** tiene tres partes: declaraciones de clases, declaraciones de funciones y una expresión opcional terminada en punto y coma (`;`): + +```Grammar + := []* []* [ ;] +``` + +Una clase contiene atributos y métodos, y opcionalmente declaraciones de argumentos de clases: + +```Grammar + := class ID [()] [is ID [()]] { [ ;]* []* } + := ID [: ID] [, ID [: ID]]* + | epsilon + := [, ]* + | epsilon +``` + +Los atributos tiene un nombre, opcionalmente un tipo y una inicialización obligatoria. + +```Grammar + := ID [: ID] = +``` + +Un método tiene un nombre, argumentos, un tipo de retorno opcional y un cuerpo. Hay 2 tipos de notaciones para métodos, una donde el cuerpo es una expresión simple (y termina en `;`) y otra donde el cuerpo es una lista de expresiones. + +```Grammar + := ID ( ) [: ID] + := -> ; + | { [ ;]+ } +``` + +Una función global tiene una signatura muy parecida a un método, pero requiere la palabra clave `function`: + +```Grammar + := function ID ( ) [: ID] +``` + +Finalmente las expresiones se dividen en 8 tipos fundamentales: + +```Grammar + := + | + | + | + | + | + | + | +``` + +Una expresión de tipo `let` se compone de un bloque de inicializaciones, y un cuerpo. Igual que las funciones, este cuerpo puede ser simple o compuesto por una lista de expresiones: + +```Grammar + := let in + := [, ]* + := ID [: ID] = + := + | { [ ;]+ } +``` + +Una expresión de tipo `if` tiene un conjunto de condiciones y opcionalmente una cláusula `else`: + +```Grammar + := if ( ) + [elif ( ) ]* + [else ] +``` + +Una expresión de tipo `while` tiene una condición, un cuerpo, y opcionalmente una cláusula `else`: + +```Grammar + := while ( ) + [else ] +``` + +Una expresión de tipo `case` tiene una expresión y un conjunto de ramas compuestas por identificador, tipo, y expresión de retorno: + +```Grammar + := case of + := ID : ID -> + | { [ID : ID -> ;]* } +``` + +Una asignación tiene una locación a la izquierda y una expresión a la derecha: + +```Grammar + := ':=' + := '[' ']' + | . + | ID +``` + +Una expresión de creación de _array_ tiene un tipo opcional, una cantidad, y opcionalmente una cláusula de inicialización: + +```Grammar + := new ID? '[' ']' [{ ID -> }]? +``` + +Una expresión de instanciación tiene un tipo y un conjunto de argumentos de clase: + +```Grammar + := new ID ( ) +``` + +Las expresiones elementales se componen de todas las operaciones lógicas, aritméticas, etc., además de la invocación a funciones globales, métodos, y atributos: + +```Grammar + := == | != + | < | > + | <= | >= + | & | '|' | ! + | @ | @@ + | + | - + | % | * | / + | [ '[' ']' ]? + | [ .] ID [( )]? + | - | ( ) +``` + +**NOTA**: Como se ha explicado al inicio de la sección, la gramática anterior no tiene en cuenta la asociatividad ni precedencia de los diferentes tipos de expresiones. Esto se ha hecho a propósito, para permitir a los estudiantes resolver los problemas de ambigüedad resultantes del modo que consideren oportuno. + +### Semántica de tipos + +En **HULK** todas las expresiones tienen asociado un tipo estático, que debe ser inferido por el compilador. Cada expresión o instrucción de **HULK** tiene reglas de consistencia de tipos que deben ser verificadas por el compilador. En esta sección asumiremos que todos los tipos están explícitamente declarados. La sección siguiente explica cómo realizar la inferencia de tipos cuando existan declaraciones sin anotaciones de tipo. Para definir el tipo inferido y las restricciones de consistencia de cada tipo de expresión usaremos la notación definida en el capítulo [Semántica de Tipos](#semantics). + +### Reglas para la inferencia de tipos + +### Semántica operacional + +## Implementando un Compilador de **HULK** + +La implementación de un compilador de **HULK** tiene varios detalles y retos interesantes. A continuación queremos discutir algunas cuestiones que facilitarán esta tarea. + +### Consideraciones generales + +El compilador de **HULK** es un proyecto complejo, que debe ser dividido convenientemente en subproblemas, para ser atacado de forma efectiva. Si el proyecto se realiza en un equipo, existen algunos puntos importantes donde la carga puede ser divida. + +El punto de división más evidente es el AST semántico, que separa todo el proceso de _parsing_ de las fases de verificación semántica y generación de código. Si se define primero una jerarquía para el AST y se usa el patrón _Visitor_, es posible dividir el trabajo al menos en 2 fases independientes: _parsing_ y chequeo semántico. Mientras un miembro del equipo construye la gramática y el _parser_, otro miembro puede implementar toda la verificación semántica, sin estorbarse mutuamente, pues la interfaz de comunicación es el AST. +Así mismo, un tercer miembro puede a partir del AST semántico implementar toda la generación de código, asumiendo que la verificación semántica es correcta, sin importar que aún no esté implementada. + +Para la fase de generación de código, recomendamos que se utilice un lenguaje intermedio, similar a **CIL**. Esto permitirá nuevamente dividir el trabajo en 2 fases bien separadas. Primero se define un AST de este lenguaje intermedio, que debe ser mucho más sencillo que un AST para **HULK**. A partir de este punto, 2 personas diferentes pueden trabajar en 2 tareas: la transformación del AST semántico al AST de **CIL**, y la transformación de este AST a MIPS. + +De modo que existen al menos 4 tareas del compilador que pueden implementarse en paralelo, estableciendo como interfaces de comunicación 2 ASTs, 1 para **HULK** y uno para **CIL**. Las tareas opcionales de inferencia de tipos y optimización de código también ser incluidas en este esquema de forma no disruptiva. Esto queda resumido en la siguiente gráfica: + +```python echo=False, results="plain" +Pipeline(['HULK', 'AST-HULK', 'AST-CIL', 'MIPS'], [ + (0, 1, 'Parser\nLexer'), + (1, 1, 'Semántica\nInferencia'), + (1, 2, 'Generación'), + (2, 2, 'Optimización'), + (2, 3, 'Generación') +]).print(width="100%", float=False) +``` + +### Flujo de trabajo + +El lenguaje **HULK** ha sido diseñado de forma que su compilador pueda implementarse *bottom-up*. Esto es, en vez de implementar cada fase del compilador (_lexer_, _parser_, semántico, generación de código) de forma secuencial, proponemos que se tomen las características del lenguaje (expresiones, funciones, clases) y se vayan adicionando, en cada momento implementando las modificaciones que cada fase requiera. A continuación proponemos un orden para implementar las características del lenguaje. En cada paso, sugerimos implementar _todas_ las fases, es decir, introducir los tipos de _token_ nuevos, producciones en la gramática, nodos del AST, reglas de verificación semántica y generación de código. + +Para simplificar aun más la organización, proponemos dividir el desarrollo del compilador en 2 grandes fases: _frontend_ y _backend_. La fase de _frontend_ termina con la verificación semántica en el AST de HULK y la fase de _backend_ comienza justo en la generación de código de HULK a CIL. Ambas fases pueden ser implementadas en paralelo (por personas diferentes), o en serie. En esta sección asumiremos que estas 2 fases se realizan en serie, y por tanto primero ejemplificaremos como implementar todo el _frontend_ y luego todo el _backend_, pero es importante recordar que ambas fases son prácticamente independientes y se pueden ir desarrollando a la par. + +La ventaja de comenzar de esta manera, es que muy rápidamente se tocan todos los puntos claves del _frontend_ del compilador y se comienza a trabajar en todas las fases, aunque en cada una es muy sencillo lo que debe implementarse. Esto no quiere decir que más adelante no sea necesario regresar y revisar decisiones de diseño que en este punto no fueron previstas, pero eso es inevitable en cualquier caso. Al obligarse a comenzar el proyecto implementando un primer prototipo funcional _completo_, habrás garantizado "chocar" con la mayoría de los obstáculos temprano. + +Veamos entonces una propuesta de organización. + +#### Paso 1: Expresiones Aritméticas + +Implementar los operadores `+`, `-`, `*`, `/` y `%`, y el tipo `Number`. En este punto tu compilador debe ser capaz de _interpretar_ programas como el siguiente: + +```hulk +(34.1 * (123.42 - 208)) / (24 + 9); +``` + +Para resolver este paso deberás: + +- Implementar un tokenizador básico de expresiones aritméticas. +- Diseñar una gramática no-ambigüa de expresiones. +- Construir un AST con soporte para expresiones. +- Construir un visitor para interpretar el AST. + +#### Paso 2: Funciones globales + +Implementar la invocación (**solo la invocación**) a funciones globales (`print`, `parse`, `max`, `min`, `sin`, `cos`, etc.). En este punto tu compilador debe ser capaz de interpretar programas como el siguiente: + +```hulk +print(sin(2 * 3.1415) + cos(1 / (4.54 - 6.72))); +``` + +Para resolver este paso deberás: + +- Adicionar las reglas y producciones a la gramática. +- Añadir un nodo de invocación a funciones. +- Implementar un _visitor_ de verificación semántica que chequee la cantidad de argumentos pasados a una función. +- Añadir al intérprete la implementación de las funciones elementales. + +#### Paso 3: Declaración de funciones + +Implementar la declaración de funciones, potencialmente _solo_ con la notación compacta. En este punto tu compilador debe ser capaz de interpretar programas como el siguiente: + +```hulk +function tan(x) -> sin(x) / cos(x); + +print(tan(2 * 3.1415)); +``` + +Para resolver este paso deberás: + +- Adicionar reglas y producciones para la declaración. +- Comprobar que la cantidad de parámetros declarados coincida con la invocación. + +#### Paso 4: + +### Casos de prueba diff --git a/doc/cool-manual.pdf b/doc/cool-manual.pdf old mode 100644 new mode 100755 diff --git a/doc/github-git-cheat-sheet.pdf b/doc/github-git-cheat-sheet.pdf old mode 100644 new mode 100755 diff --git a/doc/report.md b/doc/report.md new file mode 100644 index 000000000..e9b0392c2 --- /dev/null +++ b/doc/report.md @@ -0,0 +1,400 @@ +# Reporte sobre el Compilador de Cool + +## Uso del compilador + +El `Compilador de Cool` implementado es un programa en lenguaje **Python**; programa que tiene +como función principal dada la dirección de un archivo tipo `"file.cl"`, que contenga un programa +de **Cool**, analizar dicho fichero reportar errores si tiene, en caso contrario generar un nuevo +fichero en la misma dirección en esta ocasión terminado en `".mips"`. El programa se puede ejecutar +con el comando: + + python -m cool_compiler + +En implementación del compilador se utilizo la librería **sly**, en especifico la version 0.4, la misma +debe ser instalada previo a la ejecución del programa. Para instalar dicha librería se debe correr el comando: + + pip install sly==0.4 + +## Arquitectura del compilador + +El compilador es un único gran módulo `cool_compiler`, que contiene otros 6 módulos más: + +### 1 - Módulo Cmp + +Módulo aportado por los profesores de la asignatura, cuyas implementaciones ha servido de +apoyo para las distintas clases practicas y proyectos a lo largo del curso. De este módulo +se utilizan principalmente las clase `Type` y `Scope`, asi como los decoradores necesarios para +implementar el patrón **visitor**. A dichas implementaciones a lo largo del desarrollo se le +realizaron pequeñas modificaciones para ajustarlas, más aun, a las necesidades del desarrollo: + +- __@visitor.result__: Nuevo decorador que se agregó a los decoradores del patrón visitor. + Este decorador recibe la clase que sera el resultado de la función a la cual decora, una vez + dicha función concluye sus valores de retorno son utilizados para instancias la clase en + cuestión. Además pasa del nodo de entrada hacia el nuevo nodo resultante la información + sobre a que linea y columna pertenecen dichos nodos en el código original + +### 2 - Módulo Lexer + +Módulo que comienza con el análisis de código de cool que se desea compilar, su función principal +es convertir la cadena de caracteres en una cadena de token. Los token son la primera abstracción +que se le aplica al código, estos son subcadenas que son lexicográficamente significativas y según +este significado se les asigna un tipo (literal, keyword, type, identificador, number, string, etc). +El desarrollo de este módulo se apoyo en la libreria **sly**; específicamente la clase **Lexer**, la cual +brinda la facilidad de definir un autómata que reconozca las subcadenas significativas para un +lenguaje dad. Heredando de la clase **Lexer** y definiendo las propiedades _literals_ y _tokens_ se +puede expresar la lista de expresiones regulares que el autómata debe reconocer, en este caso en +particular se definieron de la siguiente manera: + +```python + ... + tokens = { + CLASS, INHERITS, + IF, THEN, ELSE, FI, + LET, IN, + WHILE, LOOP, POOL, + CASE, OF, ESAC, + ISVOID, NEW, NOT, + TRUE, FALSE, + ID, NUMBER, TYPE, + ARROW, LOGICAR, LESS_OR, + STRING + } + + literals = { + '{','}', '@', '.', ',', ';', + '=', '<', '~', '+', '-', + '*', '/', '(', ')', ':', + } + ... +``` + +La propiedad _tokens_ de la clase que hereda de **Lexer**, por defecto interpreta que los tipos de +token definidos en la lista se le deben asignar a toda ocurrencia literal de dicho tipo, obviando si los +caracteres se encuentran en mayúscula o no. En caso en que el comportamiento por defecto no se ajuste +a las necesidades del lenguaje, **sly** permite que se redefina la expresión regular asignada a los tipos +de token definidos (por ejemplo en el caso de cool los token ID y STRING). La sintaxis para refefinir +la expresión regular, es definiendo a la clase que hereda de **Lexer** una propiedad igual al tipo de +token que quiere redefinir: + +```python + ... + ID = r'[a-zA-Z][a-zA-Z0-9_]*' + STRING = r'\"' + ... +``` + +Otra de las grandes ayudas que aporta **sly** que la facilidad de definir un método que se llamará al +momento una ocurrencia de un tipo de token determinado. De esta manera se pueden definir nuevos +comportamiento y personalizar el análisis del autómata. Para explotar esta característica de la librería +basta con definir un método dentro de la clase con nombre igual a al tipo de token al que desea reaccionar + +```python + ... + def STRING(self, token): + lexer = CoolString(self) + ... +``` + +Esta facilidad resultó muy útil para manejar el reconocimiento de los string y los comentarios de **Cool**. +Para estos dos casos se definieron otras dos clase que hereda de **Lexer** para darle un análisis diferenciado. +Estos fragmentos de código tiene un comportamientos similares al lenguaje `(ab)*` el cual no es regular, por lo +cual no basta con un autómata finito determinista para reconocer todo el lenguaje. Para completar el reconocimiento +de estos fragmentos, apoyados en **sly**, se implementaron autómatas con manipulación de memoria y asi poder contar +la cantidad de ocurrencias de los distintos delimitadores + +### 3 - Módulo Parser + +El módulo Parser se encarga de chequear la consistencia sintáctica del código en cuestión. Dicho módulo también fue +implementado con la ayuda de **sly**, específicamente con su clase **Parser**. Esta clase facilita la definición de +gramáticas atributadas de manera extremadamente cómoda. Heredando de **Parser** se pueden definir métodos como +atributo de cada producción de la gramática y mediante el decorador **@\_** se especifica la producción a la que se le +debe asignar dicho atributo. Ejemplo: + +```python + # cclass: no terminal y epsilon terminal + # en prod.cclass se encuentra el resultado del no terminal cclass + # en prod.epsilon se encuentra el terminal epsilon + @_("cclass epsilon") + def class_list(self, prod): + return [prod.cclass] +``` + +Además **Parser** ofrece las herramientas para desambiguar en casos en que exista colisiones entre las producciones, +como por ejemplo las producciones que tiene como cabecera el no terminal `expression`. Para que el parser sepa decidir +cual de las producciones se debe seleccionar en cada escenario se necesita definir una prioridad entre las producciones. +Para definir las precedencias de los distintos operadores, la clase **Parser** tiene la propiedad **precedence**, tupla de +tuplas ordenadas de menor a mayor precedencia. Dicha propiedad inicialmente se encuentra vacia, y de ser necesario se pueden +predefinir, en el caso particular del compilador de cool se predefinió de la manera siguiente: + +```python + ... + precedence = ( + ('right', 'ARROW'), + ('left','NOT'), + ('nonassoc', '=','<','LESS_OR'), + ('left', '+', '-'), + ('left', '*', '/'), + ('left', "ISVOID"), + ('left', '~'), + ('left', '@'), + ('right', 'IN'), + ('left', '.'), + ) + ... +``` + +Aprovechando la característica de que la gramática se encuentra recogida en una clase, se desarrollaron algunas herramientas +para realizar la inversión de la dependencia entre la gramática y el ast, mediante el patrón **Factory**. Desde el módulo +parser se definió un enum con los nombres de los nodos que la clase parser le pasará a la factoría de nodos, además de un +decorador que enlace un método con el nombre del nodo que el mismo creará + +### 4 - Módulo Type + +Este módulo es un apoyo para el resto de los módulos principales, en el cual se definirán los tipos build-in, y se inyectarán +mediante el decorador `build_in_type` al diccionario de la clase **CoolTypeBuildInManager** la cual cuenta con una implementación +según el _patrón singleton_. Al momento en que cada uno de los tipos build-in son agregados al diccionario interno de manager de +los mismo se crea una instancia y se ejecutan todas sus funciones mediante las herramientas de la librería de Python `inspect`. +El resultado final de este módulo es una clase que contiene toda la información de los tipos build-in accesible a partir de los +nombres de los mismos y una implementación bastante extensible de la definición de los mismo. Ejemplo: + +```python +@build_in_type +class String(Type): + def __init__(self): + super().__init__("String") # Define el nombre del tipo + type_body_def(self) + + @property + def is_shield(self): # sobre escribe alguna de las + return True # propiedades de la clase Type + + def value(self): # define un atributo + self.define_attribute("value", self) + + def length(self): # define una función + self.define_method("length", [], Int()) + .... +``` + +### 5 - Módulo Semantic + +La fase del análisis semántico del código en cuestión se encuentra conformado por dos recorridos sobre el **AST** resultante de la +fase **Parser** además de la implementación de la factoría de _nodos_ antes comentada que unido al proceso anterior origina el +**árbol de sintaxis abstracta** correspondiente al código de entrada. Como el parser construye los distintos nodos, según la factoría, en +profundidad, osea primero los hijos y luego el padre, entonces se decidió unir la factoría con el primer recorrido que se estudio en +las clases de chequeo semántico, **Recolección de Tipos**, pues antes de construir el nodo **Program**, raíz del **AST de Cool**, ya se +construyeron todos los nodos **Class** y por tanto ya se pueden tener localizados todos los nombres de los nuevos tipos definidos en el +programa que se intenta compilar. Para la implementación de dicha factoría, se definieron algunos decoradores con los que se logran mapear +cada método con la palabra clave del nodo que dicho método construirá, logrando así en la clase **CoolFactory** un aspecto similar al +_patrón visitor_, patrón de diseño de todas las implementaciones siguiente en el proceso de compilación. + +```python +@factory +class CoolFactory: + @decored(Nodes.Program) + @compose + def program(self, class_list): + return Program(class_list, self.global_names) + + @decored(Nodes.Class) + @compose + def cool_class(self, name, parent, features): + self.global_names.append((name, self.lineno, self.index)) + return CoolClass(name,parent,features) +``` + +Siguiendo el paradigma **FP** cada uno de los procesos y análisis que se realizan a partir de esta etapa tendrán como resultado un +nuevo **AST** cada cual con la información agregada del recorrido que lo origino, logrando asi procesos puros libres de efectos segundarías +y estados internos, además de objetos inmutables. Esta metodología, analizar la salida de un procesos anterior y definir un nuevo **AST** com +respuesta del análisis actual, lo comienza la factoría de nodos definiendo el primer **AST** sobre el que se trabajará + +Siguiendo las pautas marcadas en las clases de **Compilación** una vez realizada la recolección de tipos, se hace necesario construir los mismo +y así contar con una documentación de los tipos definidos en el programa para futuros procesamientos. Este recorrido es bastante simple ya que +no es mas que la acumulación de información sobre los distintas funciones y atributos de cada uno de los tipos definidos en el nuevo programa. +Además de chequear que todos los tipos a los que se les hace referencia de manera explicita; ya sea el tipo de los atributos, de los parámetros +de las funciones, del retorno de las funciones, asignaciones `let`, o ramas del los `case`, estén definido y reconocidos por procesos anteriores. +Genera como resultado un nuevo **AST**, donde en todo nodo en el que se hace referencias explicitas al los distintos tipos se guarda la toda la +documentación recogida en dicha pasada sobre el tipo en cuestión + +Se finaliza el chequo semántico con un último recorrido donde se validan todas las reglas y predicados con las que debe cumplir un codigo de **Cool** +según la documentación. Entre los problemas más interesantes que se presentan en esta fase pueden ser el control y definición de los distintos `scope` +y de los tipos estáticos de cada una de las expresiones, pues el resto no es más que la comprobación de una serie de predicados, según el nodo en +cuestión y el resultado de los nodos de los que dicho nodo depende. Para la resolución de los distintos `scope`, se reutilizo la clase **Scope** de +**cmp**, aportado por los profesores en el momento en que se impartieron los contenidos relacionados a este procesamiento. El tipo estático de cada +expresión se guarda en los respectivos nodos de respuesta y su definición depende de la expresión en cuestión, pues nodos como las operaciones +aritméticas o de comparación tiene un tipo estático previamente definidos por la documentación, Int y Bool respectivamente, mientras que otras +como los `if` y los `case` se debe realizar un búsqueda entre los ancestros de los tipos estáticos de cada una de las ramas para encontrar el +primer ancestro común entre los tipos de cada rama. Una vez finalizadas todas las validaciones de los distintos predicados por los distintos nodos +se genera un nuevo **AST** el cual sumando a la información anterior, los nodos de tipo **Expression** contiene además el tipo estático de la expresión + +### 6 - Módulo Codegen + +La fase final de la compilación, sabiendo que el código en cuestión es correcto tanto sintáctica como semánticamente, es la generación de un nuevo +programa que ejecute las ordenes trasmitida en el programa de entrada, en el sistema subyacente. En este caso en particular el lenguaje seleccionado +para dicho programa final fue **MIPS** y el proceso de su generación se encuentra dividido en dos por un lenguaje intermedio (CIL) para facilitar la +traducción de **Cool** a **Mips** + +#### Cool a CIL + +Este paso intermedio en la generación del programa final, es muy flexible y abierto, del lenguaje intermedio solo se generá un **AST** del mismo, con +lo cual dicho lenguaje no debe cumplir con otras reglas sintácticas y semánticas, salvos las que entienda el receptor del **AST** resultante. Con lo +cual en todo momento se le puede realizar todo tipo de cambios al lenguaje para facilitar la traducción ente **Cool** y **Mips**. El **CIL** resultante +al termino de este trabajo, se basa en las ideas expuestas por los profesores de la asignatura, un lenguaje donde toda instrucción tiene máximo 3 +operadores y en la mayoría de los casos uno de ellos es la variable a la que se le asignara el resultado de la operación. Siguiendo las ideas de nuestros +profesores, el nodos **Program** del **AST** de **CIL** se encuentra dividido en tres grandes componentes: + +- **Data**: Diccionario donde se almacena una serie de datos estáticos importantes para la ejecución del programa, principalmente los string literales + definidos en el programa y otros predefinidos como `____null____`, `____error____` o `____void_str____`. Además en esta sección + se almacena una información importante sobre los tipos del programa como una lista de enteros que representa la rama paterna del mismo (bajo el label + `(type name)\_parents`), el nombre literal del mismo (bajo el label `(type name)\_name`) y la tabla virtual de funciones, diccionario donde se almacena + el nombre de cada uno de los métodos del tipo y el nombre del padre más cercano que lo define +- **Type**: Lista de las distintas documentaciones de los tipos definidos en el programa, con su nombre, atributos y métodos, estos dos últimos ordenados + en función de la profundidad en al que fueron definidos, primeros los atributos y funciones definidos por los padres y luego el el tipo en cuestión +- **Functions**: Lista de los nodos **Function** del **AST de CIL**, dichos nodos cuenta con el nombre de la función, lista de parámetros, lista de variables + locales y lista de expresiones. Dicha lista contiene todas las funciones definidas a lo largo del programa, una funcione `new` por cada tipo definido (que + se encarga de asignar los valores a los distintos atributos de la clase en cuestión) más una función **main** encargada de crear la nueva instancia de la + clase **Main** y de llamar a la función **main de Main** + +El recorrido que genera **CIL** en rasgos generales, se concentra en construir los nodos **Function**, almacenado la lista de comandos resultante de +recorre la expresión de la función en cuestión, recorrido en el que se definirían las variables locales necesarias. Los nodos **Expression** de **CIL** +se pueden dividir en _comandos_ y _operaciones_, los _comandos_ no tiene resultado, mientras que las _operaciones_ si lo tiene. El resultado de evaluar +la función `visit` en nodos de tipo **Expression** de **Cool**, es una lista de nodos **Expression** de **CIL**. Para el caso de la _operación_ se define una palabra clave '', palabra que se utiliza para que el padre del nodo en cuestión detecte que tiene que cambiarla el nombre de la variable local +en la que se guardara el resultado final de la operación; además de funcionar como un pequeño auto test, pues si en el recorrido del padre de alguna +expresión espera que la lista resultante termine con una operación con esta palabra clave y no es así, al internar remplazar dicho valor se genera una +excepción especial para rápidamente detectar dicho error. A lo largo del recorrido por la expresión de cada función en particular se definen varias +variables locales, algunas naturales y marcadas por el programa, como son las definiciones `let` o `case`, y otras artificiales debido a las necesidades +de almacenar el resultado de operaciones intermedias, como por ejemplo las operaciones aritméticas que generan una variable local por cada operando. Otra +de las palabras clave (**\_**) que se definieron de la fase desarrollo de este recorrido tiene que ver con minimizar la cantidad de variables locales +artificiales a generar, pues si el resultado de una operación se va a utilizar inmediatamente que se resuelve dicha operación no será necesario almacenar +este resultado, ejemplo: + +```python + @visitor.when(AST.IfThenElse) + def visit(self, node: AST.IfThenElse, scope: Scope): + expr_list = [ASTR.Comment(f'Evalua la condicion de un If')] + # evaluá la condición del if + expr_list += self.visit(node.condition, scope) + # Cambia la palabra clave por la palabra clave _ + expr_list[-1].set_value('_') + expr_list.append(ASTR.Comment(f'Fin de la evaluacion de la condicion de un IF')) + + #Genera label con nombre únicos en el nuevo programa CIL + label_then = self.new_name(f'then_{self.currentFunc.name}', self.label_list) + label_fin = self.new_name(f'fin_{self.currentFunc.name}', self.label_list) + # Utiliza el resultado de la expresión antes resuelta + expr_list.append(ASTR.IfGoTo('_', label_then)) + ... +``` + +En la implementación de este recorrido se reutilizó la clase **Scope** de **cmp** para manejar los distintos scope de las distintas variables +locales. El scope no hace distinción entre parámetro de la función y variables locale, ya sean "naturales" o "artificiales", dejando fuera los +atributos de la clase a la que pertenece la función en cuestión. De esta manera se distinguen entre la asignación a una variable local y la +asignación a atributos de la clase. En la resolución de los nodos **Assing** de **Cool** es un buen ejemplo de todo lo sobre esta recorrido: + +```python + @visitor.when(AST.Assing) + def visit(self, node: AST.Assing, scope: Scope): + exp_list = [ASTR.Comment(f'Asignando un nuevo valor a la variable {node.id}')] + # evaluá la expresion + exp_list += self.visit(node.expr, scope) + # Cambia la palabra clave por la palabra clave _ + exp_list[-1].set_value('_') + # Busca si la variable es local o es un atributo de self + var = scope.find_variable(node.id) + if not var is None: + # Caso en que la variable es local y se le asigna el valor de la expresion anterior + exp_list.append(ASTR.Assign(var.type, '_')) + exp_list.append(ASTR.Assign(super_value, var.type)) + else: + # Caso en que la variable es un atributo de self y se le asigna el valor de la expresion anterior + exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.id], '_')) + exp_list.append(ASTR.GetAttr(super_value , 'self', self.currentType.attr[node.id])) + + return exp_list # retorna una lista de Expression de CIL +``` + +#### CIL a MIPS + +La genreación código **Mips** parte de una librería escrita en el propio lenguaje, la cual contendrá gran parte de las herramientas en las que se +apoyará el código final, pues es una buena idea orientar hacia el paradigma funcional las implementaciones de un lenguaje de bajo nivel que brinda +pocas abstraciones y contar con una lista de funcionalidades básicas para la ejecución de todo programa de **Cool** que ya se encuentren debidamente +testeado y aporte gran seguridad al momento de encontrar bugs. La librería consta de tres archivos (_int.mips_, _str.mips_, _bool.mips_), en los +cuales se impelmentan funciones básicas como las operaciones aritmeticas y de comparaciones entre los enteros, la comunicación con la entrado y la +salida estandar tanto para enteros como para strings, las funciones de _lenght_, _concat_, _substr_ y _eq_ de strings, además de las funciones +que crean los distintos objetos **Int**, **Bool** y **String**. A lo largo de las distintas implementaciones en **Mips** se adoptó una pequeña +leyenda de registro. + +- _$s6_ : Dirección de memoria donde se encuentra la instancia de **self** +- _$s4_ : Registro para guardar las informacionde que el recorrido **Cool a Cil** marca como temporales con la palabra clave **\_** +- _todos los registros $a_: Son los registros en los que la libreria implementada espera los distintos parametros + +Partiendo de esta base, la implementación del recorrido para generar el código **Mips** como punto final del proceso de compilación queda +encargado de traducir cada nodo de **CIL** a la lista de instrucciones de **Mips**, donde la mayoría realizarán llamados la las funciones +previamente definidas, y resolver otros problemas importantes que no se puden incluir en una libreria previamente definida, como el manejo +de la memoria tanto en el _heap_ como el _stack_, la localización de varibles locales, parametros de funciones y atributos de instancias. + +En el código **Mips** final se necesita definir de alguna manera los tipos, conocer su lista de funciones y guardar los valores de los +atributos de las distintas instancias del mismo. En este caso en la sección **.data** de el código que se genera finalmenalmente tendremos +varias informaciones relacionadas con los tipos y cada instancia hará referecincia a la dirección de memoria en donde se encuentra toda esta +información. Como en **Cool** todos los tipos heredan de **Object** e incluso tipos como **Int** y **Bool** que no tiene métodos ni atributos +propiamente definidos, igual necesita de una estructura de objetos para acceder a los métodos de **Object**. Por tanto en el código de **Mips** +resultante todos los valores reales, osea los numeros literales del código, los valores que se van computando, los booleano que se cambian por +ceros o unos, y las direcciones de memoria donde se encuetran los strings, se encuentran en el _heap_ referenciados por una direccion de memoria +que apunta al principio de la instancia, dicha dirección se encontrará ya sea en el _stack_ como varaible local o en _$s4_ como variable temporal. +Luego todas las variables locales y temporales, del _stack_ y _$s4_ son direcciones de memoria del _heap_ donde se encuentran todas las intancias, +las cuales hacen referencias a todos sus atributos definidos en el programa más uno adiciona **type_name** que es la direccion de memoria donde +podemos ver toda la información del tipo en cuestión y una propiedad extra más **value** para los tipos básicos **Int**, valor nūmerico, **Bool**, +cero o uno, **String**, dirección de memoria de string. Ejemplo: + +```t +.data +Main_parents: .word 1, 6, 14, 15, 0, # 1-Object, 6-IO, 14-Parse, 15-Main, 0-fin +Main_Name: .asciiz "Main" +Main: .word Main_Name, 4, Main_parents, Object_abort, ..., IO_in_int, ..., Parse_read_input, ..., Main_main, + +.text +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo boolop en puntero + 4 +#atributo rest en puntero + 8 +#atributo g en puntero + 12 +li $a0, 16 # Reservan memoria de (cantidad de attr + 1) * 4 +li $v0, 9 +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main +move $s4, $t0 # Guarda la información del tipo en la variable temporal _ +lw $t0, 4($sp) # Leer la instancia de la clase de la pila +move $t1, $s4 +sw $t1, 0($t0) # Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) # Lee el valor de la var self +addi $sp, $sp, -4 +sw $t0, 0($sp) # Push a la pila con self +jal new_ctr_Main # LLama a la funcion que resuelve el valor inicial de los atributos +``` + +Otro punto importante al momento generar el código final, es el debido mapeo de los parametros y veriables locales con su dirección en el _stack_. +Para llevar este conteo, a meddida que se va generando el código, se implemento una clase **Stack** con los métodos: + +- _push_: Recibe el nombre de una variable local, la agrega a su cola interna y devuelve la lista de comando de **Mips** para pushear en la pila +- _read_: Recibe un registro y el nombre de una variable local, devuelve la lista de comando para copiar el valor de la variable de la pila al registro +- _write_: Recibe un registro y el nombre de una variable local, devuelve la lista de comando para copiar del registro a la direccion de la pila que refiere a la variable +- _close_: No recibe parametros, y devuelve la lista de instrucciones para limpiar la pila entre llamados de funciones + +Apoyado en los conceptos anteriores el recorrido **visitor CIL a Mips** se mueve según los nombres que van apareciendo en una lista global del recorrido, +dicha lista comienza con la funcion `main` y va creciendo con cada nodo `SimpleCall`, `Call` o `VCall` que agregan a la lista el nombre de la +función a la que se va a llamar. De esta manera solo se genera las funciones que tiene alguna posibilidad de ser ejecutadas + +#### Generación de la Expresion Case - CheckType + +Para la resolució\*n de las expresiones `case` en el módulo de generación de código se creó un pipeline exprecífico que cuenta con un nuevo +nodo en el **AST** de **CIL**, **CheckType**, y de una función en la libreria de funciones basicas de **Mips**. El nodo **CheckType** se crea +con tres parametros al momento de su creación, el nombre de la variable local donde se guardara el valor booleano, la variable que tiene la +información de tipo de la expresión del `case` y el valor numerico que se le asigan al tipo de la rama en cuestión. Por tanto la expresión +`case` se traduce en un nodo **CheckType** por cada una de sus ramas, los cuales evaluan los distintos predicados para decidir cual de ellas +se debe ejecutar. Previo a la generación del **AST** de **CIL** de esta expresión se ordena todas las ramas en el orden topológico de la relación +hereditaria de los tipos. Luego en la libreria de funciones basicas de **Mips** se implemento la funcion `__check_type__` que recive la +dirección de memoria de una lista de enterios, osea el label (type_name)\_parents, y un entero, devuelve un booleano que es true y el entero +se encuenta en la lista, false en caso contrario. De esta manera la expresión `case` se reduce al chequeo secuencial de el predicado `CheckType` +y la ejecución de la rama donde el predicado es afirmativo. diff --git a/doc/report.pdf b/doc/report.pdf new file mode 100644 index 000000000..32f2ac1db Binary files /dev/null and b/doc/report.pdf differ diff --git a/doc/team.yml b/doc/team.yml old mode 100644 new mode 100755 index c16162532..3a3665511 --- a/doc/team.yml +++ b/doc/team.yml @@ -1,10 +1,7 @@ members: - - name: Nombre Apellido1 Apellido2 - github: github_id - group: CXXX - - name: Nombre Apellido1 Apellido2 - github: github_id - group: CXXX - - name: Nombre Apellido1 Apellido2 - github: github_id - group: CXXX + - name: Daniel Orlando Ortiz Pacheco + github: danielorlando97 + group: C412 + - name: Aldo Veldecia + github: Yuli01 + group: C412 diff --git a/img/img1.png b/img/img1.png old mode 100644 new mode 100755 diff --git a/img/img10.png b/img/img10.png old mode 100644 new mode 100755 diff --git a/img/img11.png b/img/img11.png old mode 100644 new mode 100755 diff --git a/img/img12.png b/img/img12.png old mode 100644 new mode 100755 diff --git a/img/img2.png b/img/img2.png old mode 100644 new mode 100755 diff --git a/img/img3.png b/img/img3.png old mode 100644 new mode 100755 diff --git a/img/img4.png b/img/img4.png old mode 100644 new mode 100755 diff --git a/img/img5.png b/img/img5.png old mode 100644 new mode 100755 diff --git a/img/img6.png b/img/img6.png old mode 100644 new mode 100755 diff --git a/img/img7.png b/img/img7.png old mode 100644 new mode 100755 diff --git a/img/img8.png b/img/img8.png old mode 100644 new mode 100755 diff --git a/img/img9.png b/img/img9.png old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt index 9eb0cad1a..26e4129a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,9 @@ -pytest -pytest-ordering +attrs==21.4.0 +iniconfig==1.1.1 +packaging==21.3 +pluggy==1.0.0 +py==1.11.0 +pyparsing==3.0.7 +pytest==7.0.1 +sly==0.4 +tomli==2.0.1 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 000000000..b58e63902 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/.vscode/launch.json b/src/.vscode/launch.json new file mode 100644 index 000000000..3e3efb5c2 --- /dev/null +++ b/src/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense para saber los atributos posibles. + // Mantenga el puntero para ver las descripciones de los existentes atributos. + // Para más información, visite: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Módulo", + "type": "python", + "request": "launch", + "module": "cool_compiler" + } + ] +} \ No newline at end of file diff --git a/src/Readme.md b/src/Readme.md old mode 100644 new mode 100755 diff --git a/src/cool_compiler/.DS_Store b/src/cool_compiler/.DS_Store new file mode 100644 index 000000000..d1e9f50fc Binary files /dev/null and b/src/cool_compiler/.DS_Store differ diff --git a/src/cool_compiler/.vscode/launch.json b/src/cool_compiler/.vscode/launch.json new file mode 100644 index 000000000..0f6e6bdc3 --- /dev/null +++ b/src/cool_compiler/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense para saber los atributos posibles. + // Mantenga el puntero para ver las descripciones de los existentes atributos. + // Para más información, visite: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Archivo actual", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/src/cool_compiler/Readme.md b/src/cool_compiler/Readme.md new file mode 100755 index 000000000..3b7eb910d --- /dev/null +++ b/src/cool_compiler/Readme.md @@ -0,0 +1,32 @@ +# El modulo cool_compiler + +Se componen de otros 5 modulos, cmp, lexer, parser, semantic, generator_code. +Menos cmp el cual contiene implementaciones utiles aportadas por los profesores +en el curso pasado, el resto mantienen la misma extructura para mantener un estado +open-close coherente, claro y flexible + + - `__init__.py` contiene las distintas implementaciones que pueden llegar a necesitar + un usuario de dicho modulo, y de esta manera abstraer al "mundo" del el contenido y + composicion del mismo + - `__dependency.py` en caso de ser necesario contienen los `import` de las implemetaciones + externas al modulo que el mismo necesita para su funcionamiento (como pueden ser los utiles + del modulo cmp) + - `__main__.py` es una ruta de ejecucion para el modulo como un todo, cada caso particular + se puede usar para ejecutar codico de prueba (con el comando `make {nombre del modulo}` ) + en el proceso de implementacion. Y en el caso particular del modulo cool_compiler supone + la puerta de inicio de todo el proyecto + +Para mayor legibilidad del proyecto las `.py` que contienen caracteristicas destintivas +del lenguaje de cool como pueden ser, tabla de expresiones regulares, gramatica, y AST semantico +se encuentran fuera de los distintos modulos en el nivel mas superficial del modulo cool_compiler. +Para la consistencia de los distintos modulos como un todo, es necesario un concenso en la implementacion +de estas caracteristicas del lenguaje, pues: + +- Primero, el tipo de los token debe coincidir con los no terminales de la gramtica, para lo que reunimos +estos tipos en un `Enum`, `TokenType` en **table_regex.py**, unificando ambos conceptos para cualquier +posible cambio. La implementacion y definicion de este `Enum` queda cargo del primero que lo necesite +entre los desarolladores de parser y lexer, al momento de textear su codigo. Tras la definicion +se debe actualizar el repo comun lo mas rapido posible para evitar errores +- Segundo, de igual manera sucede con los nodos del AST y la atributacion de la gramatica, y los modulos +en este caso particular el desarrolador del parser debe "esperar" por el de semantic, aunque esta definicion +es el primer paso del desarrollo del modulo semantic \ No newline at end of file diff --git a/src/cool_compiler/__init__.py b/src/cool_compiler/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py new file mode 100755 index 000000000..d3b8f8e05 --- /dev/null +++ b/src/cool_compiler/__main__.py @@ -0,0 +1,38 @@ +import sys +from .error import CoolError +from .lexer import CoolLexer +from .parser import CoolParser +from .codegen import CoolToCIL, MipsGenerate +from .semantic import * +from .types import CoolTypeBuildInManager + +path = "" +if len(sys.argv) > 1: + path = sys.argv[1] + +#path = "test.cl" + +with open(path, 'r') as _file: + text = _file.read() + _file.close() + errors = CoolError(text) + lexer = CoolLexer(errors) + type_manager = CoolTypeBuildInManager() + type_manager.all_inherence_of_object() + parser = CoolParser(CoolFactory(errors), errors) + + tokens = [token for token in lexer.tokenize(text)] + if errors.any(): sys.exit(1) + + ast = parser.parse(iter(tokens)) + if errors.any(): sys.exit(1) + + visitorList = [ CreateType, SemanticChecking, CoolToCIL , MipsGenerate ] + + for visitorClass in visitorList: + ast = visitorClass(errors).visit(ast) + if errors.any(): sys.exit(1) + +with open(path.replace('.cl', '.mips'), '+w') as _file: + _file.write(str(ast)) + _file.close() diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py new file mode 100755 index 000000000..cf0bf9cd3 --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py @@ -0,0 +1,20 @@ +import cmp.visitor as visitor + +def get_printer(ConstantNumberNode, BinaryNode): + + class PrintVisitor(object): + @visitor.on('node') + def visit(self, node, tabs): + pass + + @visitor.when(BinaryNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + '\\__' + ' '+ node.__class__.__name__ +' \n' + self.visit(node.left, tabs +1) + '\n' + self.visit(node.right, tabs + 1) + return ans + + @visitor.when(ConstantNumberNode) + def visit(self, node, tabs=0): + return '\t' * tabs + '\\__' + 'num: ' + node.lex + + printer = PrintVisitor() + return (lambda ast: printer.visit(ast)) \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py new file mode 100755 index 000000000..ca117b614 --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py @@ -0,0 +1,154 @@ +try: + import pydot +except: + pass + +class State: + def __init__(self, state, final=False): + self.state = state + self.final = final + self.transitions = {} + self.epsilon_transitions = set() + self.tag = None + + def has_transition(self, symbol): + return symbol in self.transitions + + def add_transition(self, symbol, state): + try: + self.transitions[symbol].append(state) + except: + self.transitions[symbol] = [state] + return self + + def add_epsilon_transition(self, state): + self.epsilon_transitions.add(state) + return self + + def recognize(self, string): + states = self.epsilon_closure + for symbol in string: + states = self.move_by_state(symbol, *states) + states = self.epsilon_closure_by_state(*states) + return any(s.final for s in states) + + def to_deterministic(self): + closure = self.epsilon_closure + start = State(tuple(closure), any(s.final for s in closure)) + + closures = [ closure ] + states = [ start ] + pending = [ start ] + + while pending: + state = pending.pop() + symbols = { symbol for s in state.state for symbol in s.transitions } + + for symbol in symbols: + move = self.move_by_state(symbol, *state.state) + closure = self.epsilon_closure_by_state(*move) + + if closure not in closures: + new_state = State(tuple(closure), any(s.final for s in closure)) + closures.append(closure) + states.append(new_state) + pending.append(new_state) + else: + index = closures.index(closure) + new_state = states[index] + + state.add_transition(symbol, new_state) + + return start + + @staticmethod + def from_nfa(nfa, get_states=False): + states = [] + for n in range(nfa.states): + state = State(n, n in nfa.finals) + states.append(state) + + for (origin, symbol), destinations in nfa.map.items(): + origin = states[origin] + origin[symbol] = [ states[d] for d in destinations ] + + if get_states: + return states[nfa.start], states + return states[nfa.start] + + @staticmethod + def move_by_state(symbol, *states): + return { s for state in states if state.has_transition(symbol) for s in state[symbol]} + + @staticmethod + def epsilon_closure_by_state(*states): + closure = { state for state in states } + + l = 0 + while l != len(closure): + l = len(closure) + tmp = [s for s in closure] + for s in tmp: + for epsilon_state in s.epsilon_transitions: + closure.add(epsilon_state) + return closure + + @property + def epsilon_closure(self): + return self.epsilon_closure_by_state(self) + + @property + def name(self): + return str(self.state) + + def __getitem__(self, symbol): + if symbol == '': + return self.epsilon_transitions + try: + return self.transitions[symbol] + except KeyError: + return None + + def __setitem__(self, symbol, value): + if symbol == '': + self.epsilon_transitions = value + else: + self.transitions[symbol] = value + + def __repr__(self): + return str(self) + + def __str__(self): + return str(self.state) + + def __hash__(self): + return hash(self.state) + + def graph(self): + G = pydot.Dot(rankdir='LR', margin=0.1) + G.add_node(pydot.Node('start', shape='plaintext', label='', width=0, height=0)) + + visited = set() + def visit(start): + ids = id(start) + if ids not in visited: + visited.add(ids) + G.add_node(pydot.Node(ids, label=start.name, shape='circle', style='bold' if start.final else '')) + for tran, destinations in start.transitions.items(): + for end in destinations: + visit(end) + G.add_edge(pydot.Edge(ids, id(end), label=tran, labeldistance=2)) + for end in start.epsilon_transitions: + visit(end) + G.add_edge(pydot.Edge(ids, id(end), label='ε', labeldistance=2)) + + visit(self) + G.add_edge(pydot.Edge('start', id(self), label='', style='dashed')) + + return G + + def _repr_svg_(self): + try: + return self.graph().create_svg().decode('utf8') + except: + pass \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py new file mode 100755 index 000000000..0a351192f --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py @@ -0,0 +1,220 @@ +from cmp.pycompiler import Sentence, Production +from cmp.utils import ContainerSet, Token, UnknownToken +from cmp.tools import build_parsing_table, metodo_predictivo_no_recursivo + +class BasicXCool: + def __init__(self, G): + self.G = G + self.fixed_tokens = { lex: Token(lex, G[lex]) for lex in '+ - * / ( )'.split() } + + @property + def firsts(self): + G = self.G + return { + G['+']: ContainerSet(G['+'] , contains_epsilon=False), + G['-']: ContainerSet(G['-'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['/']: ContainerSet(G['/'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['num']: ContainerSet(G['num'] , contains_epsilon=False), + G['E']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['-'], G['+'] , contains_epsilon=True), + G['Y']: ContainerSet(G['/'], G['*'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['+'], G['T'], G['X']): ContainerSet(G['+'] , contains_epsilon=False), + Sentence(G['-'], G['T'], G['X']): ContainerSet(G['-'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['*'], G['F'], G['Y']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['/'], G['F'], G['Y']): ContainerSet(G['/'] , contains_epsilon=False), + Sentence(G['num']): ContainerSet(G['num'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G[')'], G['-'], G.EOF, G['+'] , contains_epsilon=False), + G['F']: ContainerSet(G['-'], G.EOF, G['*'], G['/'], G[')'], G['+'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G[')'], G['-'], G.EOF, G['+'] , contains_epsilon=False) + } + + @property + def table(self): + G = self.G + return { + ( G['E'], G['num'], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['E'], G['('], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['X'], G['+'], ): [ Production(G['X'], Sentence(G['+'], G['T'], G['X'])), ], + ( G['X'], G['-'], ): [ Production(G['X'], Sentence(G['-'], G['T'], G['X'])), ], + ( G['X'], G[')'], ): [ Production(G['X'], G.Epsilon), ], + ( G['X'], G.EOF, ): [ Production(G['X'], G.Epsilon), ], + ( G['T'], G['num'], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['T'], G['('], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['Y'], G['*'], ): [ Production(G['Y'], Sentence(G['*'], G['F'], G['Y'])), ], + ( G['Y'], G['/'], ): [ Production(G['Y'], Sentence(G['/'], G['F'], G['Y'])), ], + ( G['Y'], G[')'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G['-'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G.EOF, ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G['+'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['F'], G['num'], ): [ Production(G['F'], Sentence(G['num'])), ], + ( G['F'], G['('], ): [ Production(G['F'], Sentence(G['('], G['E'], G[')'])), ] + } + + @property + def tokenizer(self): + G = self.G + fixed_tokens = self.fixed_tokens + + def tokenize_text(text): + tokens = [] + for item in text.split(): + try: + float(item) + token = Token(item, G['num']) + except ValueError: + try: + token = fixed_tokens[item] + except: + token = UnknownToken(item) + tokens.append(token) + eof = Token('$', G.EOF) + tokens.append(eof) + return tokens + + return tokenize_text + +class PowXCool: + def __init__(self, G): + self.G = G + + @property + def firsts(self): + G = self.G + return { + G['+']: ContainerSet(G['+'] , contains_epsilon=False), + G['-']: ContainerSet(G['-'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['/']: ContainerSet(G['/'] , contains_epsilon=False), + G['^']: ContainerSet(G['^'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['num']: ContainerSet(G['num'] , contains_epsilon=False), + G['E']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['A']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['-'], G['+'] , contains_epsilon=True), + G['Y']: ContainerSet(G['/'], G['*'] , contains_epsilon=True), + G['Z']: ContainerSet(G['^'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['+'], G['T'], G['X']): ContainerSet(G['+'] , contains_epsilon=False), + Sentence(G['-'], G['T'], G['X']): ContainerSet(G['-'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['*'], G['F'], G['Y']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['/'], G['F'], G['Y']): ContainerSet(G['/'] , contains_epsilon=False), + Sentence(G['A'], G['Z']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['^'], G['F']): ContainerSet(G['^'] , contains_epsilon=False), + Sentence(G['num']): ContainerSet(G['num'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G['-'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['F']: ContainerSet(G['-'], G['*'], G['/'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['A']: ContainerSet(G['-'], G['*'], G['/'], G['^'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G['-'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['Z']: ContainerSet(G['-'], G['*'], G['/'], G[')'], G.EOF, G['+'] , contains_epsilon=False) + } + +class Regex: + def __init__(self, G): + self.G = G + + @property + def firsts(self): + G = self.G + return { + G['|']: ContainerSet(G['|'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['symbol']: ContainerSet(G['symbol'] , contains_epsilon=False), + G['E']: ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + G['A']: ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['|'] , contains_epsilon=True), + G['Y']: ContainerSet(G['symbol'], G['('] , contains_epsilon=True), + G['Z']: ContainerSet(G['*'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + Sentence(G['|'], G['E']): ContainerSet(G['|'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + Sentence(G['T']): ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + Sentence(G['A'], G['Z']): ContainerSet(G['symbol'], G['('] , contains_epsilon=False), + Sentence(G['*']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['symbol']): ContainerSet(G['symbol'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G['|'], G[')'], G.EOF , contains_epsilon=False), + G['F']: ContainerSet(G['symbol'], G['|'], G['('], G[')'], G.EOF , contains_epsilon=False), + G['A']: ContainerSet(G['symbol'], G.EOF, G['|'], G['*'], G['('], G[')'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G['|'], G[')'], G.EOF , contains_epsilon=False), + G['Z']: ContainerSet(G['symbol'], G.EOF, G['|'], G['('], G[')'] , contains_epsilon=False) + } + + @property + def table(self): + G = self.G + return { + ( G['E'], G['symbol'], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['E'], G['('], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['X'], G['|'], ): [ Production(G['X'], Sentence(G['|'], G['E'])), ], + ( G['X'], G[')'], ): [ Production(G['X'], G.Epsilon), ], + ( G['X'], G.EOF, ): [ Production(G['X'], G.Epsilon), ], + ( G['T'], G['symbol'], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['T'], G['('], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['Y'], G['symbol'], ): [ Production(G['Y'], Sentence(G['T'])), ], + ( G['Y'], G['('], ): [ Production(G['Y'], Sentence(G['T'])), ], + ( G['Y'], G['|'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G[')'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G.EOF, ): [ Production(G['Y'], G.Epsilon), ], + ( G['F'], G['symbol'], ): [ Production(G['F'], Sentence(G['A'], G['Z'])), ], + ( G['F'], G['('], ): [ Production(G['F'], Sentence(G['A'], G['Z'])), ], + ( G['Z'], G['*'], ): [ Production(G['Z'], Sentence(G['*'])), ], + ( G['Z'], G['symbol'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G.EOF, ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['|'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['('], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G[')'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['A'], G['symbol'], ): [ Production(G['A'], Sentence(G['symbol'])), ], + ( G['A'], G['('], ): [ Production(G['A'], Sentence(G['('], G['E'], G[')'])), ] + } + + @property + def parser(self): + firsts = self.firsts + follows = self.follows + M = build_parsing_table(self.G, firsts, follows) + parser = metodo_predictivo_no_recursivo(self.G, M) + return parser \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py new file mode 100755 index 000000000..e89c62ad3 --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py @@ -0,0 +1,87 @@ +import io, os, sys, types + +from IPython import get_ipython +from nbformat import read +from IPython.core.interactiveshell import InteractiveShell + +def find_notebook(fullname, path=None): + """find a notebook, given its fully qualified name and an optional path + + This turns "foo.bar" into "foo/bar.ipynb" + and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar + does not exist. + """ + name = fullname.rsplit('.', 1)[-1] + if not path: + path = [''] + for d in path: + nb_path = os.path.join(d, name + ".ipynb") + if os.path.isfile(nb_path): + return nb_path + # let import Notebook_Name find "Notebook Name.ipynb" + nb_path = nb_path.replace("_", " ") + if os.path.isfile(nb_path): + return nb_path + +class NotebookLoader(object): + """Module Loader for Jupyter Notebooks""" + def __init__(self, path=None): + self.shell = InteractiveShell.instance() + self.path = path + + def load_module(self, fullname): + """import a notebook as a module""" + path = find_notebook(fullname, self.path) + + print ("importing Jupyter notebook from %s" % path) + + # load the notebook object + with io.open(path, 'r', encoding='utf-8') as f: + nb = read(f, 4) + + + # create the module and add it to sys.modules + # if name in sys.modules: + # return sys.modules[name] + mod = types.ModuleType(fullname) + mod.__file__ = path + mod.__loader__ = self + mod.__dict__['get_ipython'] = get_ipython + sys.modules[fullname] = mod + + # extra work to ensure that magics that would affect the user_ns + # actually affect the notebook module's ns + save_user_ns = self.shell.user_ns + self.shell.user_ns = mod.__dict__ + + try: + for cell in nb.cells: + if cell.cell_type == 'code': + # transform the input to executable Python + code = self.shell.input_transformer_manager.transform_cell(cell.source) + # run the code in themodule + exec(code, mod.__dict__) + finally: + self.shell.user_ns = save_user_ns + return mod + +class NotebookFinder(object): + """Module finder that locates Jupyter Notebooks""" + def __init__(self): + self.loaders = {} + + def find_module(self, fullname, path=None): + nb_path = find_notebook(fullname, path) + if not nb_path: + return + + key = path + if path: + # lists aren't hashable + key = os.path.sep.join(path) + + if key not in self.loaders: + self.loaders[key] = NotebookLoader(path) + return self.loaders[key] + +sys.meta_path.append(NotebookFinder()) \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py new file mode 100755 index 000000000..c2a54bd6b --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py @@ -0,0 +1,447 @@ +import json + +class Symbol(object): + + def __init__(self, name, grammar): + self.Name = name + self.Grammar = grammar + + def __str__(self): + return self.Name + + def __repr__(self): + return repr(self.Name) + + def __add__(self, other): + if isinstance(other, Symbol): + return Sentence(self, other) + + raise TypeError(other) + + def __or__(self, other): + + if isinstance(other, (Sentence)): + return SentenceList(Sentence(self), other) + + raise TypeError(other) + + @property + def IsEpsilon(self): + return False + + def __len__(self): + return 1 + +class NonTerminal(Symbol): + + + def __init__(self, name, grammar): + super().__init__(name, grammar) + self.productions = [] + + + def __imod__(self, other): + + if isinstance(other, (Sentence)): + p = Production(self, other) + self.Grammar.Add_Production(p) + return self + + if isinstance(other, tuple): + assert len(other) > 1 + assert len(other) == len(other[0]) + 2, "Debe definirse una, y solo una, regla por cada símbolo de la producción" + # assert len(other) == 2, "Tiene que ser una Tupla de 2 elementos (sentence, attribute)" + + if isinstance(other[0], Symbol) or isinstance(other[0], Sentence): + p = AttributeProduction(self, other[0], other[1:]) + else: + raise Exception("") + + self.Grammar.Add_Production(p) + return self + + if isinstance(other, Symbol): + p = Production(self, Sentence(other)) + self.Grammar.Add_Production(p) + return self + + if isinstance(other, SentenceList): + + for s in other: + p = Production(self, s) + self.Grammar.Add_Production(p) + + return self + + raise TypeError(other) + + @property + def IsTerminal(self): + return False + + @property + def IsNonTerminal(self): + return True + + @property + def IsEpsilon(self): + return False + +class Terminal(Symbol): + + def __init__(self, name, grammar): + super().__init__(name, grammar) + + @property + def IsTerminal(self): + return True + + @property + def IsNonTerminal(self): + return False + + @property + def IsEpsilon(self): + return False + +class EOF(Terminal): + + def __init__(self, Grammar): + super().__init__('$', Grammar) + +class Sentence(object): + + def __init__(self, *args): + self._symbols = tuple(x for x in args if not x.IsEpsilon) + self.hash = hash(self._symbols) + + def __len__(self): + return len(self._symbols) + + def __add__(self, other): + if isinstance(other, Symbol): + return Sentence(*(self._symbols + (other,))) + + if isinstance(other, Sentence): + return Sentence(*(self._symbols + other._symbols)) + + raise TypeError(other) + + def __or__(self, other): + if isinstance(other, Sentence): + return SentenceList(self, other) + + if isinstance(other, Symbol): + return SentenceList(self, Sentence(other)) + + raise TypeError(other) + + def __repr__(self): + return str(self) + + def __str__(self): + return ("%s " * len(self._symbols) % tuple(self._symbols)).strip() + + def __iter__(self): + return iter(self._symbols) + + def __getitem__(self, index): + return self._symbols[index] + + def __eq__(self, other): + return self._symbols == other._symbols + + def __hash__(self): + return self.hash + + @property + def IsEpsilon(self): + return False + +class SentenceList(object): + + def __init__(self, *args): + self._sentences = list(args) + + def Add(self, symbol): + if not symbol and (symbol is None or not symbol.IsEpsilon): + raise ValueError(symbol) + + self._sentences.append(symbol) + + def __iter__(self): + return iter(self._sentences) + + def __or__(self, other): + if isinstance(other, Sentence): + self.Add(other) + return self + + if isinstance(other, Symbol): + return self | Sentence(other) + + +class Epsilon(Terminal, Sentence): + + def __init__(self, grammar): + super().__init__('epsilon', grammar) + + + def __str__(self): + return "e" + + def __repr__(self): + return 'epsilon' + + def __iter__(self): + yield from () + + def __len__(self): + return 0 + + def __add__(self, other): + return other + + def __eq__(self, other): + return isinstance(other, (Epsilon,)) + + def __hash__(self): + return hash("") + + @property + def IsEpsilon(self): + return True + +class Production(object): + + def __init__(self, nonTerminal, sentence): + + self.Left = nonTerminal + self.Right = sentence + + def __str__(self): + + return '%s := %s' % (self.Left, self.Right) + + def __repr__(self): + return '%s -> %s' % (self.Left, self.Right) + + def __iter__(self): + yield self.Left + yield self.Right + + def __eq__(self, other): + return isinstance(other, Production) and self.Left == other.Left and self.Right == other.Right + + + @property + def IsEpsilon(self): + return self.Right.IsEpsilon + +class AttributeProduction(Production): + + def __init__(self, nonTerminal, sentence, attributes): + if not isinstance(sentence, Sentence) and isinstance(sentence, Symbol): + sentence = Sentence(sentence) + super(AttributeProduction, self).__init__(nonTerminal, sentence) + + self.attributes = attributes + + def __str__(self): + return '%s := %s' % (self.Left, self.Right) + + def __repr__(self): + return '%s -> %s' % (self.Left, self.Right) + + def __iter__(self): + yield self.Left + yield self.Right + + + @property + def IsEpsilon(self): + return self.Right.IsEpsilon + + # sintetizar en ingles??????, pending aggrement + def syntetice(self): + pass + +class Grammar(): + + def __init__(self): + + self.Productions = [] + self.nonTerminals = [] + self.terminals = [] + self.startSymbol = None + # production type + self.pType = None + self.Epsilon = Epsilon(self) + self.EOF = EOF(self) + + self.symbDict = {} + + def NonTerminal(self, name, startSymbol = False): + + name = name.strip() + if not name: + raise Exception("Empty name") + + term = NonTerminal(name,self) + + if startSymbol: + + if self.startSymbol is None: + self.startSymbol = term + else: + raise Exception("Cannot define more than one start symbol.") + + self.nonTerminals.append(term) + self.symbDict[name] = term + return term + + def NonTerminals(self, names): + + ans = tuple((self.NonTerminal(x) for x in names.strip().split())) + + return ans + + + def Add_Production(self, production): + + if len(self.Productions) == 0: + self.pType = type(production) + + assert type(production) == self.pType, "The Productions most be of only 1 type." + + production.Left.productions.append(production) + self.Productions.append(production) + + + def Terminal(self, name): + + name = name.strip() + if not name: + raise Exception("Empty name") + + term = Terminal(name, self) + self.terminals.append(term) + self.symbDict[name] = term + return term + + def Terminals(self, names): + + ans = tuple((self.Terminal(x) for x in names.strip().split())) + + return ans + + + def __str__(self): + + mul = '%s, ' + + ans = 'Non-Terminals:\n\t' + + nonterminals = mul * (len(self.nonTerminals)-1) + '%s\n' + + ans += nonterminals % tuple(self.nonTerminals) + + ans += 'Terminals:\n\t' + + terminals = mul * (len(self.terminals)-1) + '%s\n' + + ans += terminals % tuple(self.terminals) + + ans += 'Productions:\n\t' + + ans += str(self.Productions) + + return ans + + def __getitem__(self, name): + try: + return self.symbDict[name] + except KeyError: + return None + + @property + def to_json(self): + + productions = [] + + for p in self.Productions: + head = p.Left.Name + + body = [] + + for s in p.Right: + body.append(s.Name) + + productions.append({'Head':head, 'Body':body}) + + d={'NonTerminals':[symb.Name for symb in self.nonTerminals], 'Terminals': [symb.Name for symb in self.terminals],\ + 'Productions':productions} + + # [{'Head':p.Left.Name, "Body": [s.Name for s in p.Right]} for p in self.Productions] + return json.dumps(d) + + @staticmethod + def from_json(data): + data = json.loads(data) + + G = Grammar() + dic = {'epsilon':G.Epsilon} + + for term in data['Terminals']: + dic[term] = G.Terminal(term) + + for noTerm in data['NonTerminals']: + dic[noTerm] = G.NonTerminal(noTerm) + + for p in data['Productions']: + head = p['Head'] + dic[head] %= Sentence(*[dic[term] for term in p['Body']]) + + return G + + def copy(self): + G = Grammar() + G.Productions = self.Productions.copy() + G.nonTerminals = self.nonTerminals.copy() + G.terminals = self.terminals.copy() + G.pType = self.pType + G.startSymbol = self.startSymbol + G.Epsilon = self.Epsilon + G.EOF = self.EOF + G.symbDict = self.symbDict.copy() + + return G + + @property + def IsAugmentedGrammar(self): + augmented = 0 + for left, right in self.Productions: + if self.startSymbol == left: + augmented += 1 + if augmented <= 1: + return True + else: + return False + + def AugmentedGrammar(self): + if not self.IsAugmentedGrammar: + + G = self.copy() + # S, self.startSymbol, SS = self.startSymbol, None, self.NonTerminal('S\'', True) + S = G.startSymbol + G.startSymbol = None + SS = G.NonTerminal('S\'', True) + if G.pType is AttributeProduction: + SS %= S + G.Epsilon, lambda x : x + else: + SS %= S + G.Epsilon + + return G + else: + return self.copy() + #endchange \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py new file mode 100755 index 000000000..5c7cdd5e2 --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py @@ -0,0 +1,10 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJyVUk1r3DAQvftXiJy81BXJtaBDD+lSqFvThmVBGCOvx46ovhjJ2WZL/3sly5vNllwKAs08zeg9vdEAI+lnqYbOCfTSTF0QvYJyW40SffDVaJWyR7/5UJCa/f5TkNEiEUQasqUN2mE+BGmNj8dkzwT9AmOIYRPD73J6THFqgNSQb+RNm4pJwOdlJzXfV9BS4RyYoRSbBMKvA7jw+pxx0cZUjpdr6MGaIKTxHTgvlTVL/YUuK+f7zHchfJPxivKKEyHMaEhdDNErDcEOtnMIg4wvf7KdsR3CYY7mPdloW52cWirLYwrJjvEtvf/2qdpSHwSGH8+6tyq9RWt2G7cT4yk7PkoF5AFnWDRMbEeddeUiTrAj1zpVJQMm+tk/AGpphMp6E8iYWMXnbCFdEdIjiJ85BuXhDGv9jt0V/6AOpQnlzT2iRUo+9hZD/BeU0pts1NmQr9ZAcdV6cbhhNZ8q0fLbNgNpKjJNBYWZoFRgyib/kM37u2pZm7Oq3XkyawWX7cp8ejl5Y2b/qXvNTi8D1sVffqzjDA=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) + +deprecated_metodo_predictivo_no_recursivo = metodo_predictivo_no_recursivo +def metodo_predictivo_no_recursivo(G, M): + parser = deprecated_metodo_predictivo_no_recursivo(G, M) + def updated(tokens): + return parser([t.token_type for t in tokens]) + return updated \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py new file mode 100755 index 000000000..2ff28ec0b --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py @@ -0,0 +1,141 @@ +from cmp.pycompiler import Production, Sentence, Symbol, EOF, Epsilon + +class ContainerSet: + def __init__(self, *values, contains_epsilon=False): + self.set = set(values) + self.contains_epsilon = contains_epsilon + + def add(self, value): + n = len(self.set) + self.set.add(value) + return n != len(self.set) + + def extend(self, values): + change = False + for value in values: + change |= self.add(value) + return change + + def set_epsilon(self, value=True): + last = self.contains_epsilon + self.contains_epsilon = value + return last != self.contains_epsilon + + def update(self, other): + n = len(self.set) + self.set.update(other.set) + return n != len(self.set) + + def epsilon_update(self, other): + return self.set_epsilon(self.contains_epsilon | other.contains_epsilon) + + def hard_update(self, other): + return self.update(other) | self.epsilon_update(other) + + def find_match(self, match): + for item in self.set: + if item == match: + return item + return None + + def __len__(self): + return len(self.set) + int(self.contains_epsilon) + + def __str__(self): + return '%s-%s' % (str(self.set), self.contains_epsilon) + + def __repr__(self): + return str(self) + + def __iter__(self): + return iter(self.set) + + def __nonzero__(self): + return len(self) > 0 + + def __eq__(self, other): + if isinstance(other, set): + return self.set == other + return isinstance(other, ContainerSet) and self.set == other.set and self.contains_epsilon == other.contains_epsilon + + +def inspect(item, grammar_name='G', mapper=None): + try: + return mapper[item] + except (TypeError, KeyError ): + if isinstance(item, dict): + items = ',\n '.join(f'{inspect(key, grammar_name, mapper)}: {inspect(value, grammar_name, mapper)}' for key, value in item.items() ) + return f'{{\n {items} \n}}' + elif isinstance(item, ContainerSet): + args = f'{ ", ".join(inspect(x, grammar_name, mapper) for x in item.set) } ,' if item.set else '' + return f'ContainerSet({args} contains_epsilon={item.contains_epsilon})' + elif isinstance(item, EOF): + return f'{grammar_name}.EOF' + elif isinstance(item, Epsilon): + return f'{grammar_name}.Epsilon' + elif isinstance(item, Symbol): + return f"G['{item.Name}']" + elif isinstance(item, Sentence): + items = ', '.join(inspect(s, grammar_name, mapper) for s in item._symbols) + return f'Sentence({items})' + elif isinstance(item, Production): + left = inspect(item.Left, grammar_name, mapper) + right = inspect(item.Right, grammar_name, mapper) + return f'Production({left}, {right})' + elif isinstance(item, tuple) or isinstance(item, list): + ctor = ('(', ')') if isinstance(item, tuple) else ('[',']') + return f'{ctor[0]} {("%s, " * len(item)) % tuple(inspect(x, grammar_name, mapper) for x in item)}{ctor[1]}' + else: + raise ValueError(f'Invalid: {item}') + +def pprint(item, header=""): + if header: + print(header) + + if isinstance(item, dict): + for key, value in item.items(): + print(f'{key} ---> {value}') + elif isinstance(item, list): + print('[') + for x in item: + print(f' {repr(x)}') + print(']') + else: + print(item) + +class Token: + """ + Basic token class. + + Parameters + ---------- + lex : str + Token's lexeme. + token_type : Enum + Token's type. + """ + + def __init__(self, lex, token_type): + self.lex = lex + self.token_type = token_type + + def __str__(self): + return f'{self.token_type}: {self.lex}' + + def __repr__(self): + return str(self) + + @property + def is_valid(self): + return True + +class UnknownToken(Token): + def __init__(self, lex): + Token.__init__(self, lex, None) + + def transform_to(self, token_type): + return Token(self.lex, token_type) + + @property + def is_valid(self): + return False \ No newline at end of file diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py new file mode 100755 index 000000000..964842836 --- /dev/null +++ b/src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py @@ -0,0 +1,80 @@ +# The MIT License (MIT) +# +# Copyright (c) 2013 Curtis Schlak +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import inspect + +__all__ = ['on', 'when'] + +def on(param_name): + def f(fn): + dispatcher = Dispatcher(param_name, fn) + return dispatcher + return f + + +def when(param_type): + def f(fn): + frame = inspect.currentframe().f_back + func_name = fn.func_name if 'func_name' in dir(fn) else fn.__name__ + dispatcher = frame.f_locals[func_name] + if not isinstance(dispatcher, Dispatcher): + dispatcher = dispatcher.dispatcher + dispatcher.add_target(param_type, fn) + def ff(*args, **kw): + return dispatcher(*args, **kw) + ff.dispatcher = dispatcher + return ff + return f + + +class Dispatcher(object): + def __init__(self, param_name, fn): + frame = inspect.currentframe().f_back.f_back + top_level = frame.f_locals == frame.f_globals + self.param_index = self.__argspec(fn).args.index(param_name) + self.param_name = param_name + self.targets = {} + + def __call__(self, *args, **kw): + typ = args[self.param_index].__class__ + d = self.targets.get(typ) + if d is not None: + return d(*args, **kw) + else: + issub = issubclass + t = self.targets + ks = t.keys() + ans = [t[k](*args, **kw) for k in ks if issub(typ, k)] + if len(ans) == 1: + return ans.pop() + return ans + + def add_target(self, typ, target): + self.targets[typ] = target + + @staticmethod + def __argspec(fn): + # Support for Python 3 type hints requires inspect.getfullargspec + if hasattr(inspect, 'getfullargspec'): + return inspect.getfullargspec(fn) + else: + return inspect.getargspec(fn) diff --git a/src/cool_compiler/cmp/__init__.py b/src/cool_compiler/cmp/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/src/cool_compiler/cmp/ast.py b/src/cool_compiler/cmp/ast.py new file mode 100755 index 000000000..ec162b83b --- /dev/null +++ b/src/cool_compiler/cmp/ast.py @@ -0,0 +1,62 @@ +import cmp.visitor as visitor + +class Node: + def evaluate(self): + raise NotImplementedError() + +class AtomicNode(Node): + def __init__(self, lex): + self.lex = lex + +class UnaryNode(Node): + def __init__(self, node): + self.node = node + + def evaluate(self): + value = self.node.evaluate() + return self.operate(value) + + @staticmethod + def operate(value): + raise NotImplementedError() + +class BinaryNode(Node): + def __init__(self, left, right): + self.left = left + self.right = right + + def evaluate(self): + lvalue = self.left.evaluate() + rvalue = self.right.evaluate() + return self.operate(lvalue, rvalue) + + @staticmethod + def operate(lvalue, rvalue): + raise NotImplementedError() + +def get_printer(AtomicNode=AtomicNode, UnaryNode=UnaryNode, BinaryNode=BinaryNode, ): + + class PrintVisitor(object): + @visitor.on('node') + def visit(self, node, tabs): + pass + + @visitor.when(UnaryNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__ {node.__class__.__name__}' + child = self.visit(node.node, tabs + 1) + return f'{ans}\n{child}' + + @visitor.when(BinaryNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__ {node.__class__.__name__} ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AtomicNode) + def visit(self, node, tabs=0): + return '\t' * tabs + f'\\__ {node.__class__.__name__}: {node.lex}' + + printer = PrintVisitor() + return (lambda ast: printer.visit(ast)) \ No newline at end of file diff --git a/src/cool_compiler/cmp/ast_abstract_node.py b/src/cool_compiler/cmp/ast_abstract_node.py new file mode 100755 index 000000000..d4ac120d8 --- /dev/null +++ b/src/cool_compiler/cmp/ast_abstract_node.py @@ -0,0 +1,33 @@ +class Node: + def evaluate(self): + raise NotImplementedError() + +class AtomicNode(Node): + def __init__(self, lex): + self.lex = lex + +class UnaryNode(Node): + def __init__(self, node): + self.node = node + + def evaluate(self): + value = self.node.evaluate() + return self.operate(value) + + @staticmethod + def operate(value): + raise NotImplementedError() + +class BinaryNode(Node): + def __init__(self, left, right): + self.left = left + self.right = right + + def evaluate(self): + lvalue = self.left.evaluate() + rvalue = self.right.evaluate() + return self.operate(lvalue, rvalue) + + @staticmethod + def operate(lvalue, rvalue): + raise NotImplementedError() \ No newline at end of file diff --git a/src/cool_compiler/cmp/automata.py b/src/cool_compiler/cmp/automata.py new file mode 100755 index 000000000..f42b6f00c --- /dev/null +++ b/src/cool_compiler/cmp/automata.py @@ -0,0 +1,207 @@ +try: + import pydot +except: + pass + +class State: + def __init__(self, state, final=False, formatter=lambda x: str(x), shape='circle'): + self.state = state + self.final = final + self.transitions = {} + self.epsilon_transitions = set() + self.tag = None + self.formatter = formatter + self.shape = shape + + # The method name is set this way from compatibility issues. + def set_formatter(self, value, attr='formatter', visited=None): + if visited is None: + visited = set() + elif self in visited: + return + + visited.add(self) + self.__setattr__(attr, value) + for destinations in self.transitions.values(): + for node in destinations: + node.set_formatter(value, attr, visited) + for node in self.epsilon_transitions: + node.set_formatter(value, attr, visited) + return self + + def has_transition(self, symbol): + return symbol in self.transitions + + def add_transition(self, symbol, state): + try: + self.transitions[symbol].append(state) + except: + self.transitions[symbol] = [state] + return self + + def add_epsilon_transition(self, state): + self.epsilon_transitions.add(state) + return self + + def recognize(self, string): + states = self.epsilon_closure + for symbol in string: + states = self.move_by_state(symbol, *states) + states = self.epsilon_closure_by_state(*states) + return any(s.final for s in states) + + def to_deterministic(self, formatter=lambda x: str(x)): + closure = self.epsilon_closure + start = State(tuple(closure), any(s.final for s in closure), formatter) + + closures = [ closure ] + states = [ start ] + pending = [ start ] + + while pending: + state = pending.pop() + symbols = { symbol for s in state.state for symbol in s.transitions } + + for symbol in symbols: + move = self.move_by_state(symbol, *state.state) + closure = self.epsilon_closure_by_state(*move) + + if closure not in closures: + new_state = State(tuple(closure), any(s.final for s in closure), formatter) + closures.append(closure) + states.append(new_state) + pending.append(new_state) + else: + index = closures.index(closure) + new_state = states[index] + + state.add_transition(symbol, new_state) + + return start + + @staticmethod + def from_nfa(nfa, get_states=False): + states = [] + for n in range(nfa.states): + state = State(n, n in nfa.finals) + states.append(state) + + for (origin, symbol), destinations in nfa.map.items(): + origin = states[origin] + origin[symbol] = [ states[d] for d in destinations ] + + if get_states: + return states[nfa.start], states + return states[nfa.start] + + @staticmethod + def move_by_state(symbol, *states): + return { s for state in states if state.has_transition(symbol) for s in state[symbol]} + + @staticmethod + def epsilon_closure_by_state(*states): + closure = { state for state in states } + + l = 0 + while l != len(closure): + l = len(closure) + tmp = [s for s in closure] + for s in tmp: + for epsilon_state in s.epsilon_transitions: + closure.add(epsilon_state) + return closure + + @property + def epsilon_closure(self): + return self.epsilon_closure_by_state(self) + + @property + def name(self): + return self.formatter(self.state) + + def get(self, symbol): + target = self.transitions[symbol] + assert len(target) == 1 + return target[0] + + def __getitem__(self, symbol): + if symbol == '': + return self.epsilon_transitions + try: + return self.transitions[symbol] + except KeyError: + return None + + def __setitem__(self, symbol, value): + if symbol == '': + self.epsilon_transitions = value + else: + self.transitions[symbol] = value + + def __repr__(self): + return str(self) + + def __str__(self): + return str(self.state) + + def __hash__(self): + return hash(self.state) + + def __iter__(self): + yield from self._visit() + + def _visit(self, visited=None): + if visited is None: + visited = set() + elif self in visited: + return + + visited.add(self) + yield self + + for destinations in self.transitions.values(): + for node in destinations: + yield from node._visit(visited) + for node in self.epsilon_transitions: + yield from node._visit(visited) + + def graph(self): + G = pydot.Dot(rankdir='LR', margin=0.1) + G.add_node(pydot.Node('start', shape='plaintext', label='', width=0, height=0)) + + visited = set() + def visit(start): + ids = id(start) + if ids not in visited: + visited.add(ids) + G.add_node(pydot.Node(ids, label=start.name, shape=self.shape, style='bold' if start.final else '')) + for tran, destinations in start.transitions.items(): + for end in destinations: + visit(end) + G.add_edge(pydot.Edge(ids, id(end), label=tran, labeldistance=2)) + for end in start.epsilon_transitions: + visit(end) + G.add_edge(pydot.Edge(ids, id(end), label='ε', labeldistance=2)) + + visit(self) + G.add_edge(pydot.Edge('start', id(self), label='', style='dashed')) + + return G + + def _repr_svg_(self): + try: + return self.graph().create_svg().decode('utf8') + except: + pass + + def write_to(self, fname): + return self.graph().write_svg(fname) + +def multiline_formatter(state): + return '\n'.join(str(item) for item in state) + +def lr0_formatter(state): + try: + return '\n'.join(str(item)[:-4] for item in state) + except TypeError: + return str(state)[:-4] \ No newline at end of file diff --git a/src/cool_compiler/cmp/cil.py b/src/cool_compiler/cmp/cil.py new file mode 100755 index 000000000..de6782c16 --- /dev/null +++ b/src/cool_compiler/cmp/cil.py @@ -0,0 +1,231 @@ +import cmp.visitor as visitor + + +class Node: + pass + +class ProgramNode(Node): + def __init__(self, dottypes, dotdata, dotcode): + self.dottypes = dottypes + self.dotdata = dotdata + self.dotcode = dotcode + +class TypeNode(Node): + def __init__(self, name): + self.name = name + self.attributes = [] + self.methods = [] + +class DataNode(Node): + def __init__(self, vname, value): + self.name = vname + self.value = value + +class FunctionNode(Node): + def __init__(self, fname, params, localvars, instructions): + self.name = fname + self.params = params + self.localvars = localvars + self.instructions = instructions + +class ParamNode(Node): + def __init__(self, name): + self.name = name + +class LocalNode(Node): + def __init__(self, name): + self.name = name + +class InstructionNode(Node): + pass + +class AssignNode(InstructionNode): + def __init__(self, dest, source): + self.dest = dest + self.source = source + +class ArithmeticNode(InstructionNode): + def __init__(self, dest, left, right): + self.dest = dest + self.left = left + self.right = right + +class PlusNode(ArithmeticNode): + pass + +class MinusNode(ArithmeticNode): + pass + +class StarNode(ArithmeticNode): + pass + +class DivNode(ArithmeticNode): + pass + +class GetAttribNode(InstructionNode): + pass + +class SetAttribNode(InstructionNode): + pass + +class GetIndexNode(InstructionNode): + pass + +class SetIndexNode(InstructionNode): + pass + +class AllocateNode(InstructionNode): + def __init__(self, itype, dest): + self.type = itype + self.dest = dest + +class ArrayNode(InstructionNode): + pass + +class TypeOfNode(InstructionNode): + def __init__(self, obj, dest): + self.obj = obj + self.dest = dest + +class LabelNode(InstructionNode): + pass + +class GotoNode(InstructionNode): + pass + +class GotoIfNode(InstructionNode): + pass + +class StaticCallNode(InstructionNode): + def __init__(self, function, dest): + self.function = function + self.dest = dest + +class DynamicCallNode(InstructionNode): + def __init__(self, xtype, method, dest): + self.type = xtype + self.method = method + self.dest = dest + +class ArgNode(InstructionNode): + def __init__(self, name): + self.name = name + +class ReturnNode(InstructionNode): + def __init__(self, value=None): + self.value = value + +class LoadNode(InstructionNode): + def __init__(self, dest, msg): + self.dest = dest + self.msg = msg + +class LengthNode(InstructionNode): + pass + +class ConcatNode(InstructionNode): + pass + +class PrefixNode(InstructionNode): + pass + +class SubstringNode(InstructionNode): + pass + +class ToStrNode(InstructionNode): + def __init__(self, dest, ivalue): + self.dest = dest + self.ivalue = ivalue + +class ReadNode(InstructionNode): + def __init__(self, dest): + self.dest = dest + +class PrintNode(InstructionNode): + def __init__(self, str_addr): + self.str_addr = str_addr + +def get_formatter(): + + class PrintVisitor(object): + @visitor.on('node') + def visit(self, node): + pass + + @visitor.when(ProgramNode) + def visit(self, node): + dottypes = '\n'.join(self.visit(t) for t in node.dottypes) + dotdata = '\n'.join(self.visit(t) for t in node.dotdata) + dotcode = '\n'.join(self.visit(t) for t in node.dotcode) + + return f'.TYPES\n{dottypes}\n\n.DATA\n{dotdata}\n\n.CODE\n{dotcode}' + + @visitor.when(TypeNode) + def visit(self, node): + attributes = '\n\t'.join(f'attribute {x}' for x in node.attributes) + methods = '\n\t'.join(f'method {x}: {y}' for x,y in node.methods) + + return f'type {node.name} {{\n\t{attributes}\n\n\t{methods}\n}}' + + @visitor.when(FunctionNode) + def visit(self, node): + params = '\n\t'.join(self.visit(x) for x in node.params) + localvars = '\n\t'.join(self.visit(x) for x in node.localvars) + instructions = '\n\t'.join(self.visit(x) for x in node.instructions) + + return f'function {node.name} {{\n\t{params}\n\n\t{localvars}\n\n\t{instructions}\n}}' + + @visitor.when(ParamNode) + def visit(self, node): + return f'PARAM {node.name}' + + @visitor.when(LocalNode) + def visit(self, node): + return f'LOCAL {node.name}' + + @visitor.when(AssignNode) + def visit(self, node): + return f'{node.dest} = {node.source}' + + @visitor.when(PlusNode) + def visit(self, node): + return f'{node.dest} = {node.left} + {node.right}' + + @visitor.when(MinusNode) + def visit(self, node): + return f'{node.dest} = {node.left} - {node.right}' + + @visitor.when(StarNode) + def visit(self, node): + return f'{node.dest} = {node.left} * {node.right}' + + @visitor.when(DivNode) + def visit(self, node): + return f'{node.dest} = {node.left} / {node.right}' + + @visitor.when(AllocateNode) + def visit(self, node): + return f'{node.dest} = ALLOCATE {node.type}' + + @visitor.when(TypeOfNode) + def visit(self, node): + return f'{node.dest} = TYPEOF {node.type}' + + @visitor.when(StaticCallNode) + def visit(self, node): + return f'{node.dest} = CALL {node.function}' + + @visitor.when(DynamicCallNode) + def visit(self, node): + return f'{node.dest} = VCALL {node.type} {node.method}' + + @visitor.when(ArgNode) + def visit(self, node): + return f'ARG {node.name}' + + @visitor.when(ReturnNode) + def visit(self, node): + return f'RETURN {node.value if node.value is not None else ""}' + + printer = PrintVisitor() + return (lambda ast: printer.visit(ast)) \ No newline at end of file diff --git a/src/cool_compiler/cmp/evaluation.py b/src/cool_compiler/cmp/evaluation.py new file mode 100755 index 000000000..55ff38e9d --- /dev/null +++ b/src/cool_compiler/cmp/evaluation.py @@ -0,0 +1,33 @@ +from cmp.pycompiler import EOF +from cmp.tools.parsing import ShiftReduceParser + +def evaluate_reverse_parse(right_parse, operations, tokens): + if not right_parse or not operations or not tokens: + return + + right_parse = iter(right_parse) + tokens = iter(tokens) + stack = [] + for operation in operations: + if operation == ShiftReduceParser.SHIFT: + token = next(tokens) + stack.append(token.lex) + elif operation == ShiftReduceParser.REDUCE: + production = next(right_parse) + head, body = production + attributes = production.attributes + assert all(rule is None for rule in attributes[1:]), 'There must be only synteticed attributes.' + rule = attributes[0] + + if len(body): + synteticed = [None] + stack[-len(body):] + value = rule(None, synteticed) + stack[-len(body):] = [value] + else: + stack.append(rule(None, None)) + else: + raise Exception('Invalid action!!!') + + assert len(stack) == 1 + assert isinstance(next(tokens).token_type, EOF) + return stack[0] \ No newline at end of file diff --git a/src/cool_compiler/cmp/languages.py b/src/cool_compiler/cmp/languages.py new file mode 100755 index 000000000..e2c0c33da --- /dev/null +++ b/src/cool_compiler/cmp/languages.py @@ -0,0 +1,228 @@ +from cmp.pycompiler import Sentence, Production +from cmp.utils import ContainerSet, Token, UnknownToken +from cmp.tools.parsing import build_parsing_table, metodo_predictivo_no_recursivo + +class BasicXCool: + def __init__(self, G): + self.G = G + self.fixed_tokens = { lex: Token(lex, G[lex]) for lex in '+ - * / ( )'.split() } + + @property + def firsts(self): + G = self.G + return { + G['+']: ContainerSet(G['+'] , contains_epsilon=False), + G['-']: ContainerSet(G['-'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['/']: ContainerSet(G['/'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['num']: ContainerSet(G['num'] , contains_epsilon=False), + G['E']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['-'], G['+'] , contains_epsilon=True), + G['Y']: ContainerSet(G['/'], G['*'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['+'], G['T'], G['X']): ContainerSet(G['+'] , contains_epsilon=False), + Sentence(G['-'], G['T'], G['X']): ContainerSet(G['-'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['*'], G['F'], G['Y']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['/'], G['F'], G['Y']): ContainerSet(G['/'] , contains_epsilon=False), + Sentence(G['num']): ContainerSet(G['num'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G[')'], G['-'], G.EOF, G['+'] , contains_epsilon=False), + G['F']: ContainerSet(G['-'], G.EOF, G['*'], G['/'], G[')'], G['+'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G[')'], G['-'], G.EOF, G['+'] , contains_epsilon=False) + } + + @property + def table(self): + G = self.G + return { + ( G['E'], G['num'], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['E'], G['('], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['X'], G['+'], ): [ Production(G['X'], Sentence(G['+'], G['T'], G['X'])), ], + ( G['X'], G['-'], ): [ Production(G['X'], Sentence(G['-'], G['T'], G['X'])), ], + ( G['X'], G[')'], ): [ Production(G['X'], G.Epsilon), ], + ( G['X'], G.EOF, ): [ Production(G['X'], G.Epsilon), ], + ( G['T'], G['num'], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['T'], G['('], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['Y'], G['*'], ): [ Production(G['Y'], Sentence(G['*'], G['F'], G['Y'])), ], + ( G['Y'], G['/'], ): [ Production(G['Y'], Sentence(G['/'], G['F'], G['Y'])), ], + ( G['Y'], G[')'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G['-'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G.EOF, ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G['+'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['F'], G['num'], ): [ Production(G['F'], Sentence(G['num'])), ], + ( G['F'], G['('], ): [ Production(G['F'], Sentence(G['('], G['E'], G[')'])), ] + } + + @property + def tokenizer(self): + G = self.G + fixed_tokens = self.fixed_tokens + + def tokenize_text(text): + tokens = [] + for item in text.split(): + try: + float(item) + token = Token(item, G['num']) + except ValueError: + try: + token = fixed_tokens[item] + except: + token = UnknownToken(item) + tokens.append(token) + eof = Token('$', G.EOF) + tokens.append(eof) + return tokens + + return tokenize_text + +class PowXCool: + def __init__(self, G): + self.G = G + + @property + def firsts(self): + G = self.G + return { + G['+']: ContainerSet(G['+'] , contains_epsilon=False), + G['-']: ContainerSet(G['-'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['/']: ContainerSet(G['/'] , contains_epsilon=False), + G['^']: ContainerSet(G['^'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['num']: ContainerSet(G['num'] , contains_epsilon=False), + G['E']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['A']: ContainerSet(G['num'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['-'], G['+'] , contains_epsilon=True), + G['Y']: ContainerSet(G['/'], G['*'] , contains_epsilon=True), + G['Z']: ContainerSet(G['^'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['+'], G['T'], G['X']): ContainerSet(G['+'] , contains_epsilon=False), + Sentence(G['-'], G['T'], G['X']): ContainerSet(G['-'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['*'], G['F'], G['Y']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['/'], G['F'], G['Y']): ContainerSet(G['/'] , contains_epsilon=False), + Sentence(G['A'], G['Z']): ContainerSet(G['num'], G['('] , contains_epsilon=False), + Sentence(G['^'], G['F']): ContainerSet(G['^'] , contains_epsilon=False), + Sentence(G['num']): ContainerSet(G['num'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G['-'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['F']: ContainerSet(G['-'], G['*'], G['/'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['A']: ContainerSet(G['-'], G['*'], G['/'], G['^'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G['-'], G[')'], G.EOF, G['+'] , contains_epsilon=False), + G['Z']: ContainerSet(G['-'], G['*'], G['/'], G[')'], G.EOF, G['+'] , contains_epsilon=False) + } + +class Regex: + def __init__(self, G): + self.G = G + + @property + def firsts(self): + G = self.G + return { + G['|']: ContainerSet(G['|'] , contains_epsilon=False), + G['*']: ContainerSet(G['*'] , contains_epsilon=False), + G['(']: ContainerSet(G['('] , contains_epsilon=False), + G[')']: ContainerSet(G[')'] , contains_epsilon=False), + G['symbol']: ContainerSet(G['symbol'] , contains_epsilon=False), + G['ε']: ContainerSet(G['ε'] , contains_epsilon=False), + G['E']: ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + G['T']: ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + G['F']: ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + G['A']: ContainerSet(G['ε'], G['symbol'], G['('] , contains_epsilon=False), + G['X']: ContainerSet(G['|'] , contains_epsilon=True), + G['Y']: ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=True), + G['Z']: ContainerSet(G['*'] , contains_epsilon=True), + Sentence(G['T'], G['X']): ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + Sentence(G['|'], G['E']): ContainerSet(G['|'] , contains_epsilon=False), + G.Epsilon: ContainerSet( contains_epsilon=True), + Sentence(G['F'], G['Y']): ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + Sentence(G['T']): ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + Sentence(G['A'], G['Z']): ContainerSet(G['symbol'], G['ε'], G['('] , contains_epsilon=False), + Sentence(G['*']): ContainerSet(G['*'] , contains_epsilon=False), + Sentence(G['symbol']): ContainerSet(G['symbol'] , contains_epsilon=False), + Sentence(G['ε']): ContainerSet(G['ε'] , contains_epsilon=False), + Sentence(G['('], G['E'], G[')']): ContainerSet(G['('] , contains_epsilon=False) + } + + @property + def follows(self): + G = self.G + return { + G['E']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['T']: ContainerSet(G[')'], G.EOF, G['|'] , contains_epsilon=False), + G['F']: ContainerSet(G[')'], G.EOF, G['symbol'], G['|'], G['ε'], G['('] , contains_epsilon=False), + G['A']: ContainerSet(G.EOF, G['|'], G['*'], G['('], G[')'], G['symbol'], G['ε'] , contains_epsilon=False), + G['X']: ContainerSet(G[')'], G.EOF , contains_epsilon=False), + G['Y']: ContainerSet(G[')'], G.EOF, G['|'] , contains_epsilon=False), + G['Z']: ContainerSet(G.EOF, G['|'], G['('], G[')'], G['symbol'], G['ε'] , contains_epsilon=False) + } + + @property + def table(self): + G = self.G + return { + ( G['E'], G['symbol'], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['E'], G['ε'], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['E'], G['('], ): [ Production(G['E'], Sentence(G['T'], G['X'])), ], + ( G['X'], G['|'], ): [ Production(G['X'], Sentence(G['|'], G['E'])), ], + ( G['X'], G[')'], ): [ Production(G['X'], G.Epsilon), ], + ( G['X'], G.EOF, ): [ Production(G['X'], G.Epsilon), ], + ( G['T'], G['symbol'], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['T'], G['ε'], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['T'], G['('], ): [ Production(G['T'], Sentence(G['F'], G['Y'])), ], + ( G['Y'], G['symbol'], ): [ Production(G['Y'], Sentence(G['T'])), ], + ( G['Y'], G['ε'], ): [ Production(G['Y'], Sentence(G['T'])), ], + ( G['Y'], G['('], ): [ Production(G['Y'], Sentence(G['T'])), ], + ( G['Y'], G[')'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G.EOF, ): [ Production(G['Y'], G.Epsilon), ], + ( G['Y'], G['|'], ): [ Production(G['Y'], G.Epsilon), ], + ( G['F'], G['symbol'], ): [ Production(G['F'], Sentence(G['A'], G['Z'])), ], + ( G['F'], G['ε'], ): [ Production(G['F'], Sentence(G['A'], G['Z'])), ], + ( G['F'], G['('], ): [ Production(G['F'], Sentence(G['A'], G['Z'])), ], + ( G['Z'], G['*'], ): [ Production(G['Z'], Sentence(G['*'])), ], + ( G['Z'], G.EOF, ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['|'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['('], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G[')'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['symbol'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['Z'], G['ε'], ): [ Production(G['Z'], G.Epsilon), ], + ( G['A'], G['symbol'], ): [ Production(G['A'], Sentence(G['symbol'])), ], + ( G['A'], G['ε'], ): [ Production(G['A'], Sentence(G['ε'])), ], + ( G['A'], G['('], ): [ Production(G['A'], Sentence(G['('], G['E'], G[')'])), ] + } + + @property + def parser(self): + firsts = self.firsts + follows = self.follows + M = build_parsing_table(self.G, firsts, follows) + parser = metodo_predictivo_no_recursivo(self.G, M) + return parser \ No newline at end of file diff --git a/src/cool_compiler/cmp/nbpackage.py b/src/cool_compiler/cmp/nbpackage.py new file mode 100755 index 000000000..e89c62ad3 --- /dev/null +++ b/src/cool_compiler/cmp/nbpackage.py @@ -0,0 +1,87 @@ +import io, os, sys, types + +from IPython import get_ipython +from nbformat import read +from IPython.core.interactiveshell import InteractiveShell + +def find_notebook(fullname, path=None): + """find a notebook, given its fully qualified name and an optional path + + This turns "foo.bar" into "foo/bar.ipynb" + and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar + does not exist. + """ + name = fullname.rsplit('.', 1)[-1] + if not path: + path = [''] + for d in path: + nb_path = os.path.join(d, name + ".ipynb") + if os.path.isfile(nb_path): + return nb_path + # let import Notebook_Name find "Notebook Name.ipynb" + nb_path = nb_path.replace("_", " ") + if os.path.isfile(nb_path): + return nb_path + +class NotebookLoader(object): + """Module Loader for Jupyter Notebooks""" + def __init__(self, path=None): + self.shell = InteractiveShell.instance() + self.path = path + + def load_module(self, fullname): + """import a notebook as a module""" + path = find_notebook(fullname, self.path) + + print ("importing Jupyter notebook from %s" % path) + + # load the notebook object + with io.open(path, 'r', encoding='utf-8') as f: + nb = read(f, 4) + + + # create the module and add it to sys.modules + # if name in sys.modules: + # return sys.modules[name] + mod = types.ModuleType(fullname) + mod.__file__ = path + mod.__loader__ = self + mod.__dict__['get_ipython'] = get_ipython + sys.modules[fullname] = mod + + # extra work to ensure that magics that would affect the user_ns + # actually affect the notebook module's ns + save_user_ns = self.shell.user_ns + self.shell.user_ns = mod.__dict__ + + try: + for cell in nb.cells: + if cell.cell_type == 'code': + # transform the input to executable Python + code = self.shell.input_transformer_manager.transform_cell(cell.source) + # run the code in themodule + exec(code, mod.__dict__) + finally: + self.shell.user_ns = save_user_ns + return mod + +class NotebookFinder(object): + """Module finder that locates Jupyter Notebooks""" + def __init__(self): + self.loaders = {} + + def find_module(self, fullname, path=None): + nb_path = find_notebook(fullname, path) + if not nb_path: + return + + key = path + if path: + # lists aren't hashable + key = os.path.sep.join(path) + + if key not in self.loaders: + self.loaders[key] = NotebookLoader(path) + return self.loaders[key] + +sys.meta_path.append(NotebookFinder()) \ No newline at end of file diff --git a/src/cool_compiler/cmp/pycompiler.py b/src/cool_compiler/cmp/pycompiler.py new file mode 100755 index 000000000..3ef02deeb --- /dev/null +++ b/src/cool_compiler/cmp/pycompiler.py @@ -0,0 +1,512 @@ +import json + +class Symbol(object): + + def __init__(self, name, grammar): + self.Name = name + self.Grammar = grammar + + def __str__(self): + return self.Name + + def __repr__(self): + return repr(self.Name) + + def __add__(self, other): + if isinstance(other, Symbol): + return Sentence(self, other) + + raise TypeError(other) + + def __or__(self, other): + + if isinstance(other, (Sentence)): + return SentenceList(Sentence(self), other) + + raise TypeError(other) + + @property + def IsEpsilon(self): + return False + + def __len__(self): + return 1 + +class NonTerminal(Symbol): + + + def __init__(self, name, grammar): + super().__init__(name, grammar) + self.productions = [] + + + def __imod__(self, other): + + if isinstance(other, (Sentence)): + p = Production(self, other) + self.Grammar.Add_Production(p) + return self + + if isinstance(other, tuple): + assert len(other) > 1 + + if len(other) == 2: + other += (None,) * len(other[0]) + + assert len(other) == len(other[0]) + 2, "Debe definirse una, y solo una, regla por cada símbolo de la producción" + # assert len(other) == 2, "Tiene que ser una Tupla de 2 elementos (sentence, attribute)" + + if isinstance(other[0], Symbol) or isinstance(other[0], Sentence): + p = AttributeProduction(self, other[0], other[1:]) + else: + raise Exception("") + + self.Grammar.Add_Production(p) + return self + + if isinstance(other, Symbol): + p = Production(self, Sentence(other)) + self.Grammar.Add_Production(p) + return self + + if isinstance(other, SentenceList): + + for s in other: + p = Production(self, s) + self.Grammar.Add_Production(p) + + return self + + raise TypeError(other) + + @property + def IsTerminal(self): + return False + + @property + def IsNonTerminal(self): + return True + + @property + def IsEpsilon(self): + return False + +class Terminal(Symbol): + + def __init__(self, name, grammar): + super().__init__(name, grammar) + + @property + def IsTerminal(self): + return True + + @property + def IsNonTerminal(self): + return False + + @property + def IsEpsilon(self): + return False + +class EOF(Terminal): + + def __init__(self, Grammar): + super().__init__('$', Grammar) + +class Sentence(object): + + def __init__(self, *args): + self._symbols = tuple(x for x in args if not x.IsEpsilon) + self.hash = hash(self._symbols) + + def __len__(self): + return len(self._symbols) + + def __add__(self, other): + if isinstance(other, Symbol): + return Sentence(*(self._symbols + (other,))) + + if isinstance(other, Sentence): + return Sentence(*(self._symbols + other._symbols)) + + raise TypeError(other) + + def __or__(self, other): + if isinstance(other, Sentence): + return SentenceList(self, other) + + if isinstance(other, Symbol): + return SentenceList(self, Sentence(other)) + + raise TypeError(other) + + def __repr__(self): + return str(self) + + def __str__(self): + return ("%s " * len(self._symbols) % tuple(self._symbols)).strip() + + def __iter__(self): + return iter(self._symbols) + + def __getitem__(self, index): + return self._symbols[index] + + def __eq__(self, other): + return self._symbols == other._symbols + + def __hash__(self): + return self.hash + + @property + def IsEpsilon(self): + return False + +class SentenceList(object): + + def __init__(self, *args): + self._sentences = list(args) + + def Add(self, symbol): + if not symbol and (symbol is None or not symbol.IsEpsilon): + raise ValueError(symbol) + + self._sentences.append(symbol) + + def __iter__(self): + return iter(self._sentences) + + def __or__(self, other): + if isinstance(other, Sentence): + self.Add(other) + return self + + if isinstance(other, Symbol): + return self | Sentence(other) + + +class Epsilon(Terminal, Sentence): + + def __init__(self, grammar): + super().__init__('epsilon', grammar) + + + def __str__(self): + return "e" + + def __repr__(self): + return 'epsilon' + + def __iter__(self): + yield from () + + def __len__(self): + return 0 + + def __add__(self, other): + return other + + def __eq__(self, other): + return isinstance(other, (Epsilon,)) + + def __hash__(self): + return hash("") + + @property + def IsEpsilon(self): + return True + +class Production(object): + + def __init__(self, nonTerminal, sentence): + + self.Left = nonTerminal + self.Right = sentence + + def __str__(self): + + return '%s := %s' % (self.Left, self.Right) + + def __repr__(self): + return '%s -> %s' % (self.Left, self.Right) + + def __iter__(self): + yield self.Left + yield self.Right + + def __eq__(self, other): + return isinstance(other, Production) and self.Left == other.Left and self.Right == other.Right + + def __hash__(self): + return hash((self.Left, self.Right)) + + @property + def IsEpsilon(self): + return self.Right.IsEpsilon + +class AttributeProduction(Production): + + def __init__(self, nonTerminal, sentence, attributes): + if not isinstance(sentence, Sentence) and isinstance(sentence, Symbol): + sentence = Sentence(sentence) + super(AttributeProduction, self).__init__(nonTerminal, sentence) + + self.attributes = attributes + + def __str__(self): + return '%s := %s' % (self.Left, self.Right) + + def __repr__(self): + return '%s -> %s' % (self.Left, self.Right) + + def __iter__(self): + yield self.Left + yield self.Right + + + @property + def IsEpsilon(self): + return self.Right.IsEpsilon + + # sintetizar en ingles??????, pending aggrement + def syntetice(self): + pass + +class Grammar(): + + def __init__(self): + + self.Productions = [] + self.nonTerminals = [] + self.terminals = [] + self.startSymbol = None + # production type + self.pType = None + self.Epsilon = Epsilon(self) + self.EOF = EOF(self) + + self.symbDict = { '$': self.EOF } + + def NonTerminal(self, name, startSymbol = False): + + name = name.strip() + if not name: + raise Exception("Empty name") + + term = NonTerminal(name,self) + + if startSymbol: + + if self.startSymbol is None: + self.startSymbol = term + else: + raise Exception("Cannot define more than one start symbol.") + + self.nonTerminals.append(term) + self.symbDict[name] = term + return term + + def NonTerminals(self, names): + + ans = tuple((self.NonTerminal(x) for x in names.strip().split())) + + return ans + + + def Add_Production(self, production): + + if len(self.Productions) == 0: + self.pType = type(production) + + assert type(production) == self.pType, "The Productions most be of only 1 type." + + production.Left.productions.append(production) + self.Productions.append(production) + + + def Terminal(self, name): + + name = name.strip() + if not name: + raise Exception("Empty name") + + term = Terminal(name, self) + self.terminals.append(term) + self.symbDict[name] = term + return term + + def Terminals(self, names): + + ans = tuple((self.Terminal(x) for x in names.strip().split())) + + return ans + + + def __str__(self): + + mul = '%s, ' + + ans = 'Non-Terminals:\n\t' + + nonterminals = mul * (len(self.nonTerminals)-1) + '%s\n' + + ans += nonterminals % tuple(self.nonTerminals) + + ans += 'Terminals:\n\t' + + terminals = mul * (len(self.terminals)-1) + '%s\n' + + ans += terminals % tuple(self.terminals) + + ans += 'Productions:\n\t' + + ans += str(self.Productions) + + return ans + + def __getitem__(self, name): + try: + return self.symbDict[name] + except KeyError: + return None + + @property + def to_json(self): + + productions = [] + + for p in self.Productions: + head = p.Left.Name + + body = [] + + for s in p.Right: + body.append(s.Name) + + productions.append({'Head':head, 'Body':body}) + + d={'NonTerminals':[symb.Name for symb in self.nonTerminals], 'Terminals': [symb.Name for symb in self.terminals],\ + 'Productions':productions} + + # [{'Head':p.Left.Name, "Body": [s.Name for s in p.Right]} for p in self.Productions] + return json.dumps(d) + + @staticmethod + def from_json(data): + data = json.loads(data) + + G = Grammar() + dic = {'epsilon':G.Epsilon} + + for term in data['Terminals']: + dic[term] = G.Terminal(term) + + for noTerm in data['NonTerminals']: + dic[noTerm] = G.NonTerminal(noTerm) + + for p in data['Productions']: + head = p['Head'] + dic[head] %= Sentence(*[dic[term] for term in p['Body']]) + + return G + + def copy(self): + G = Grammar() + G.Productions = self.Productions.copy() + G.nonTerminals = self.nonTerminals.copy() + G.terminals = self.terminals.copy() + G.pType = self.pType + G.startSymbol = self.startSymbol + G.Epsilon = self.Epsilon + G.EOF = self.EOF + G.symbDict = self.symbDict.copy() + + return G + + @property + def IsAugmentedGrammar(self): + augmented = 0 + for left, right in self.Productions: + if self.startSymbol == left: + augmented += 1 + if augmented <= 1: + return True + else: + return False + + def AugmentedGrammar(self, force=False): + if not self.IsAugmentedGrammar or force: + + G = self.copy() + # S, self.startSymbol, SS = self.startSymbol, None, self.NonTerminal('S\'', True) + S = G.startSymbol + G.startSymbol = None + SS = G.NonTerminal('S\'', True) + if G.pType is AttributeProduction: + SS %= S + G.Epsilon, lambda x : x + else: + SS %= S + G.Epsilon + + return G + else: + return self.copy() + #endchange + +class Item: + + def __init__(self, production, pos, lookaheads=[]): + self.production = production + self.pos = pos + self.lookaheads = frozenset(look for look in lookaheads) + + def __str__(self): + s = str(self.production.Left) + " -> " + if len(self.production.Right) > 0: + for i,c in enumerate(self.production.Right): + if i == self.pos: + s += "." + s += str(self.production.Right[i]) + if self.pos == len(self.production.Right): + s += "." + else: + s += "." + s += ", " + str(self.lookaheads)[10:-1] + return s + + def __repr__(self): + return str(self) + + + def __eq__(self, other): + return ( + (self.pos == other.pos) and + (self.production == other.production) and + (set(self.lookaheads) == set(other.lookaheads)) + ) + + def __hash__(self): + return hash((self.production,self.pos,self.lookaheads)) + + @property + def IsReduceItem(self): + return len(self.production.Right) == self.pos + + @property + def NextSymbol(self): + if self.pos < len(self.production.Right): + return self.production.Right[self.pos] + else: + return None + + def NextItem(self): + if self.pos < len(self.production.Right): + return Item(self.production,self.pos+1,self.lookaheads) + else: + return None + + def Preview(self, skip=1): + unseen = self.production.Right[self.pos+skip:] + return [ unseen + (lookahead,) for lookahead in self.lookaheads ] + + def Center(self): + return Item(self.production, self.pos) \ No newline at end of file diff --git a/src/cool_compiler/cmp/scope.py b/src/cool_compiler/cmp/scope.py new file mode 100755 index 000000000..3dd5cf985 --- /dev/null +++ b/src/cool_compiler/cmp/scope.py @@ -0,0 +1,45 @@ +import itertools as itt + +class VariableInfo: + def __init__(self, name, vtype): + self.name = name + self.type = vtype + def set_type(self, typex): + self.type = typex + def __str__(self): + return self.name + +class Scope: + def __init__(self, parent=None): + self.name = "Program" + self.locals = [] + self.parent = parent + self.children = [] + self.index = 0 if parent is None else len(parent) + + def __len__(self): + return len(self.locals) + + def create_child(self, name=None): + child = Scope(self) + child.name = name + self.children.append(child) + return child + + def define_variable(self, vname, vtype): + info = VariableInfo(vname, vtype) + self.locals.append(info) + return info + + def find_variable(self, vname, index=None) -> VariableInfo: + locals = self.locals if index is None else itt.islice(self.locals, index) + try: + return next(x for x in locals if x.name == vname) + except StopIteration: + return self.parent.find_variable(vname, self.index) if self.parent is not None else None + + def is_defined(self, vname): + return self.find_variable(vname) is not None + + def is_local(self, vname): + return any(True for x in self.locals if x.name == vname) diff --git a/src/cool_compiler/cmp/semantic.py b/src/cool_compiler/cmp/semantic.py new file mode 100755 index 000000000..cf7d5523f --- /dev/null +++ b/src/cool_compiler/cmp/semantic.py @@ -0,0 +1,246 @@ +import itertools as itt +from collections import OrderedDict + + +class SemanticError(Exception): + @property + def text(self): + return self.args[0] + +class Attribute: + def __init__(self, name, typex): + self.name = name + self.type = typex + + def __str__(self): + return f'[attrib] {self.name} : {self.type.name};' + + def __repr__(self): + return str(self) + +class Method: + def __init__(self, name, param_names, params_types, return_type): + self.name = name + self.param_names = param_names + self.param_types = params_types + self.return_type = return_type + + def __str__(self): + params = ', '.join(f'{n}:{t.name}' for n,t in zip(self.param_names, self.param_types)) + return f'[method] {self.name}({params}): {self.return_type.name};' + + def __eq__(self, other): + return other.name == self.name and \ + other.param_types == self.param_types + +class Type: + def __init__(self, name:str): + self.name = name + self.attributes = [] + self.methods = [] + self.parent = None + + def set_parent(self, parent): + if self.parent is not None: + raise SemanticError(f'Parent type is already set for {self.name}.') + self.parent = parent + + def get_attribute(self, name:str): + try: + return next(attr for attr in self.attributes if attr.name == name) + + except StopIteration: + if self.parent is None: + raise SemanticError(f'Attribute "{name}" is not defined in {self.name}.') + try: + return self.parent.get_attribute(name) + except SemanticError: + raise SemanticError(f'Attribute "{name}" is not defined in {self.name}.') + + def define_attribute(self, name:str, typex): + try: + self.get_attribute(name) + except SemanticError: + attribute = Attribute(name, typex) + self.attributes.append(attribute) + return attribute + else: + raise SemanticError(f'Attribute "{name}" is already defined in {self.name}.') + + def get_method(self, name:str): + try: + return next(method for method in self.methods if method.name == name) + + except StopIteration: + if self.parent is None: + raise SemanticError(f'Method "{name}" is not defined in {self.name}.') + try: + return self.parent.get_method(name) + except SemanticError: + raise SemanticError(f'Method "{name}" is not defined in {self.name}.') + + def define_method(self, name:str, param_names:list, param_types:list, return_type): + if name in (method.name for method in self.methods): + raise SemanticError(f'Method "{name}" already defined in {self.name}') + + method = Method(name, param_names, param_types, return_type) + self.methods.append(method) + return method + + def all_attributes(self, clean=True): + plain = OrderedDict() if self.parent is None else self.parent.all_attributes(False) + for attr in self.attributes: + plain[attr.name] = (attr, self) + return plain.values() if clean else plain + + def all_methods(self, clean=True): + plain = OrderedDict() if self.parent is None else self.parent.all_methods(False) + for method in self.methods: + plain[method.name] = (method, self) + return plain.values() if clean else plain + + def conforms_to(self, other): + return other.bypass() or self == other or self.parent is not None and self.parent.conforms_to(other) + + def bypass(self): + return False + + def __str__(self): + output = f'type {self.name}' + parent = '' if self.parent is None else f' : {self.parent.name}' + output += parent + output += ' {' + output += '\n\t' if self.attributes or self.methods else '' + output += '\n\t'.join(str(x) for x in self.attributes) + output += '\n\t' if self.attributes else '' + output += '\n\t'.join(str(x) for x in self.methods) + output += '\n' if self.methods else '' + output += '}\n' + return output + + def __repr__(self): + return str(self) + + + def real_type(self, possible): + return self + + @property + def is_self_type(self): + return False + + @property + def is_auto_type(self): + return False + @property + def is_error_type(self): + return False + def __eq__(self,other): + return other.name == self.name + +class ErrorType(Type): + def __init__(self): + Type.__init__(self, '') + + def conforms_to(self, other): + return True + + def bypass(self): + return True + @property + def is_error_type(self): + return True + + def __eq__(self, other): + return isinstance(other, Type) + +class VoidType(Type): + def __init__(self): + Type.__init__(self, '') + + def conforms_to(self, other): + raise Exception('Invalid type: void type.') + + def bypass(self): + return True + + def __eq__(self, other): + return isinstance(other, VoidType) + +class IntType(Type): + def __init__(self): + Type.__init__(self, 'Int') + + def __eq__(self, other): + return other.name == self.name or isinstance(other, IntType) + +class Context: + def __init__(self, types = {}): + self.types = types + self.current_type = None + self.built_in_type = None + self.car = [chr(185),chr(186)] + + def create_type(self, name:str): + if name in self.types: + raise SemanticError(f'Type with the same name ({name}) already in context.') + typex = self.types[name] = Type(name) + return typex + + def get_type(self, name:str): + if any(name) and name[0] in self.car: + name = name[1:] + if name == "SELF_TYPE": + return self.current_type + try: + return self.types[name] + except KeyError: + raise SemanticError(f'Type "{name}" is not defined.') + + def __str__(self): + return '{\n\t' + '\n\t'.join(y for x in self.types.values() for y in str(x).split('\n')) + '\n}' + + def __repr__(self): + return str(self) + +class VariableInfo: + def __init__(self, name, vtype): + self.name = name + self.type = vtype + def set_type(self, typex): + self.type = typex + def __str__(self): + return self.name + +class Scope: + def __init__(self, parent=None): + self.locals = [] + self.parent = parent + self.children = {} + self.index = 0 if parent is None else len(parent) + + def __len__(self): + return len(self.locals) + + def create_child(self, node): + child = Scope(self) + self.children[node] = child + return child + + def define_variable(self, vname, vtype): + info = VariableInfo(vname, vtype) + self.locals.append(info) + return info + + def find_variable(self, vname, index=None): + locals = self.locals if index is None else itt.islice(self.locals, index) + try: + return next(x for x in locals if x.name == vname) + except StopIteration: + return self.parent.find_variable(vname, self.index) if self.parent is not None else None + + def is_defined(self, vname): + return self.find_variable(vname) is not None + + def is_local(self, vname): + return any(True for x in self.locals if x.name == vname) diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py new file mode 100755 index 000000000..e69de29bb diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py new file mode 100755 index 000000000..59643cc5b --- /dev/null +++ b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py @@ -0,0 +1,3 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJzNWN1um0gUvucp6BWwRSjx1SrSrBRt4iR20rRJW9VCCI1hbE+LgTBDGjvKY+1r7DPtmR9gjIm3q+5KexPDzPn9zjdnDuGIEW4xVOF8SawHtMIMc15ZZ2hKNudVVVTWNcJZZm0QZTRnHOcJsQiiObeWKCO5tUIfNyVRojka44wRa4o+VjWxPiOcbyyMtrS0OEckr9ekwhz2tUBZIl6XGbFYEwGvNieWTddlUXG73KQFt8hTQkpuX8k16QckSsyYtaiKtZ2sy6DmNGON1u9FzjHNSXUPmSUZCNrvxqegk5KFHcc0pzyOXUayhQ/pcML8Bc0hbJ9DCIxyWuRM7FQcHXmgZgvRQIki9WMsgpT82ywpW4i76sFr1tcYcu0cNMuPRYLndYarDai0woYget6ePL8sisre2jS3masi8F5AFlbdU3/u+bdiy1AKKCdr5srobQCAACwP7q3vQPqcVHHseL5zlT/ijKZ2UmQZSYSeXSxsZd4Riv1QwtMonEfott3rgg9wmrpzbz+rIKUswVXqOo6nKkBKRrMijw3DRjFkyDpiuSCT7gXSxS5FRLCKN7ZdEV5X+xqhFIxCx4lASjPqzNBwdXTLCpcrGY+M5AJJDgZnBXfB2reUVsi5vnP8Na6WNEdHwbFI+kLkH+dFSlwl/048OpIYjs9WuCTIKTNgJSdPsJLhOcmQ4/jfacpX6MhfEbpcCb55uqyZT3VZG/bs1JQi588/HJsu4Ans2AROnU3FznAoWRNEQqskIxAT32TwOi+yVJrJWleKt8oiFE0EJCKyx0LiVnp/xcn475yMDzrRVkm6bKyei8fMH2u8qPoFRskuhEZeh31fq8W+PaYd6DqsFLMVSZVzTZsL3SQqUlYxe1zGHROGCKbI4gVJRYBdQgFeUpLI4td88avgvGabVJZdS7Wks/GpC23J+4m+pI/Jtbtx4TTUxCeeKJR87jcEuQjs8Uy9JRzZ345kdaGN9FQ8mbTRh76RzUko7URCA179QVeap6JBQYLBP8qs7SBJXVUkb3urhGhdPBJtZbMGUkkQgFbqzc4LPtQsQtNeZNYw33N2UDVUfqLwKOoYM20ZA/dox5Z9s0YiFTBkmdNtkwyvaL7s1LQt3QnsRCYlZdTRX8hMlaiEJFE9wUzLZKkOo3f2LBGJVMc1L9aYF3lTnA7dG3UpdbePFBDeUtSq7SC2jYyzcovSBrR+171FMsGboC5TsOnewpsO+sYyr4kkK1hd7UcpwpuhkMngWBcceHpCz3vLwMbvK5oReybcb9EsKItShjBwHxm5Dd1W26Y0F8L+gERTp4uGk0+qQE/ymrxQ3W4W4LIkuXrXqZuji/vLkyeRyBc45kWcLnAHgsg+Qc+QVYZeRyrs8pD0i8BTFtAUHclfFksqoM+uBKoT1t25hTADvQkKRRVn6ucVLIXGfNdWNwpIDG5Qj3NbX44N9uWBPG48g/iXCssEoKI5zJBq57KBeqK2L0WaS3fiNW8/nOylUpk05bnslUu9i5tLeSrQJKB5Sp4ayUs0CQtB+PYc2Em4hXj8uVxt+m/ejTFwGbx580YOXTunpFNEIiHLvkdyoTuRE5H8tk0PHLxH4moRqfv3ftJx670kk84bx3UOTHXxsY9HJpmAGekxOoa/I4SP9dT7NoWFGuFR+z6yesMnyPZmlCQ8BT0R+vMYHowZ4mVPeTSoPGqUR7vKSZj5MMihUAVYceFHBSeeR5HqWOmTfy+tuyHsw7IvFPTNA+LqKZL+WjzvT3YK9wVBBd6CJTU49qpj7urx3f4iz3gtT0wHYAfdSBTxuX5p6wJ3pDsRpfIzb7dEQPEEdHLMD5Tq6H9dqhbXFnlzltL4HfsDY7m5p7FV0BqFNq+mtqADDkYHHIz2HPw7tWua2PHg6ap7FfupCg2ehzr6T9CvjUJ03nqIHcZp+Kv9jLKvBXwfiY92gaSY8mHkqSlbxcqse+d3V8JUwPJJwnqOytIdunA0PWqBwJ1Ia/bK0FKr8VigcI1cdxYyMeSJyVKoztRnyrsiV/O1XDwXOEyEZ3caplEgvhhgbIPrm9NHIppyKsSmgfhIYj0LcuvaM2rxKZxEzQWjo/H6NREyyIhVYRveySTvhMlP7ZgfSQwlbvEa5u813eouYk4QU2Sg7v7CmLszMIgpC6KYBmtSwSeVcUf2b89hqSF7ElR9VQ9YUXPFdCo5/0PRddlP4XusqEs1fYnVlVj9ER6Ji1aHv/LUN8USpmoEA4Ten8MX3jd4mKLE6kb/nRN/COaDhbDsq505dtojE5Nj17PuptRv/y3CuXslw3tUDlT1NSRj/3oXY5Pwj9HOfxPmaBpeA+P7NBZ7X9GVHm/UnNZejbOQ+uPdgWb/hlRC6Ktlf0AhHUyAap4G7cdknxfg5KGNYro31PaC7iYeNQddef4Hf+Y/eNZffhu9yA=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py new file mode 100755 index 000000000..d49df0ce5 --- /dev/null +++ b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py @@ -0,0 +1,3 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJxdUMFuwjAMvecrfGy3qoLrJN86YGViCO2GECrF1SLSpErcqf37OUWwsZPtZ/v5+TXetVC3Xd6NtWs7bciDbjvnGV4/FmqJmsmrE1oaWFnUQdvAla1JFbhxltQaDVm1QLJ9S75iUmdqgL4r00tx7CofKGmyMn1RoBuwjqEB56ekFAw8ce+tggaXSZMqKCWWEge8kSQnaWSRQ0EVAok2K1iZ5uwuZI88dpSJWmlfyWB4EJF03p37mrWzkSXT9ou8/HU+xgHCImrbZAZ/5xSMf6q8Yvb61DMFBYz74vCUrBOTPs/l5OV/vZ8d8N8J+U5e1tkOtIVFYrJ5PBn92OVv4ZN8q21lInR78LLXBx2giBBLjtO/hgYByASaZld4miy7b+0QV/k7NRyxLY6yGDO5swVhi54X0+bEj9vkknF6P3H3azXZFEekGWlmh7u1150HxkmQSP0BhJm25Q=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py new file mode 100755 index 000000000..02d672f4b --- /dev/null +++ b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py @@ -0,0 +1,10 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJytVVtr2zAUfvevEH2yqWfa14AeypKGlXlNL5SCMUZO5FTMlhRZbpZu++87ujiOm3QwGJRU56pzvu8cuVKiQUxTpYWoW8QaKZRGrK3ZkgaVMS4bmXSaDcbPgmvCOFUPVAcrWqGlaGSnaVGLJamLiqlWh/a3jUktX0g0CVCFnSZAEltlgKb4MFMYBUirHbiiBZbJl3YmW1YLHiD6Y0mldoZrUrc0QKxCC6OYJi3VBXWeJgMFszFUQqE5YhxJI6EUV9k8N6dp0skV0TRMIyNCIi40SpOlK6Xtk9kwVCpKvsOpT3t8oaK6UxxNR0C4VsO5a/zn7wDN8KPqoHBTV2nqmieAecM49GPrzcp8DEcZOW/tvLngj+MAnR/ht31hNUUzY5/1UNkkty7JQolVt9RMcJsDPePb5CuttDlLON+z9YsVrgCvZ4uXpwQ6B5W0qoGPXntUCEI3+ORUxNJaZ7/wNHkhalV4Nm569dWR2iNcjREWdS22AHHssB6P2GaEObXSX7DcnMJyk82TVhOlH3ZNKep3DvNkdnv9PxG/xxuPuIlmcbszCSjvGqoMEjJygMPAtjvYjm9DD86A7iBDu8udsKcN8pWYZjJm3nLI3oHxA7rcQxCCx/llDHfSKHKRQNVdv0pV6ZVQXFV+sErjkPuB2I0ltuxYvSokUS3j60KTsqZ7cmPP9pjkCo5OH8B+9xSTk7g/Y9LDvoBjj7oJoCagyhb5ZDTuafYc0zwhUlK+Ckn0fvCdHWfEwGr6hgynOx8uMTvlogd6Tt0z5ujwJg9ZaiFrqBYrUUhFVwxafRUFF4Wiyw4wfBWAXooNYx5Ef3aIWcHCyQY8xYAnNJTCRwAZt4lvkB0qTODRa+cdxdhR4FNLa5xT/BHrUCc42CbDrZ38J5zZnYvHWwmWpsEX8O8NZ0ZyC2kW396+xk+JFNK9SQRvs6bJ/bu/hi0ar5BRYkwm+2EGyV7aT3D/OUAHXwRkKjjHl8E7rVSM6/BsppRQCboq4csJPSZJcuaXxXNpgApGocNwLHCarWOSZxd+ee3bYGZJEb6mYU15uHDTHH26jO1f1Ff11A+V98hY7m9+21tOjNs/1u2lt/1sNsEfuhaMXQ=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) + +deprecated_metodo_predictivo_no_recursivo = metodo_predictivo_no_recursivo +def metodo_predictivo_no_recursivo(G, M=None, firsts=None, follows=None): + parser = deprecated_metodo_predictivo_no_recursivo(G, M, firsts, follows) + def updated(tokens): + return parser([t.token_type for t in tokens]) + return updated \ No newline at end of file diff --git a/src/cool_compiler/cmp/tools/__init__.py b/src/cool_compiler/cmp/tools/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/src/cool_compiler/cmp/tools/automata.py b/src/cool_compiler/cmp/tools/automata.py new file mode 100755 index 000000000..59643cc5b --- /dev/null +++ b/src/cool_compiler/cmp/tools/automata.py @@ -0,0 +1,3 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJzNWN1um0gUvucp6BWwRSjx1SrSrBRt4iR20rRJW9VCCI1hbE+LgTBDGjvKY+1r7DPtmR9gjIm3q+5KexPDzPn9zjdnDuGIEW4xVOF8SawHtMIMc15ZZ2hKNudVVVTWNcJZZm0QZTRnHOcJsQiiObeWKCO5tUIfNyVRojka44wRa4o+VjWxPiOcbyyMtrS0OEckr9ekwhz2tUBZIl6XGbFYEwGvNieWTddlUXG73KQFt8hTQkpuX8k16QckSsyYtaiKtZ2sy6DmNGON1u9FzjHNSXUPmSUZCNrvxqegk5KFHcc0pzyOXUayhQ/pcML8Bc0hbJ9DCIxyWuRM7FQcHXmgZgvRQIki9WMsgpT82ywpW4i76sFr1tcYcu0cNMuPRYLndYarDai0woYget6ePL8sisre2jS3masi8F5AFlbdU3/u+bdiy1AKKCdr5srobQCAACwP7q3vQPqcVHHseL5zlT/ijKZ2UmQZSYSeXSxsZd4Riv1QwtMonEfott3rgg9wmrpzbz+rIKUswVXqOo6nKkBKRrMijw3DRjFkyDpiuSCT7gXSxS5FRLCKN7ZdEV5X+xqhFIxCx4lASjPqzNBwdXTLCpcrGY+M5AJJDgZnBXfB2reUVsi5vnP8Na6WNEdHwbFI+kLkH+dFSlwl/048OpIYjs9WuCTIKTNgJSdPsJLhOcmQ4/jfacpX6MhfEbpcCb55uqyZT3VZG/bs1JQi588/HJsu4Ans2AROnU3FznAoWRNEQqskIxAT32TwOi+yVJrJWleKt8oiFE0EJCKyx0LiVnp/xcn475yMDzrRVkm6bKyei8fMH2u8qPoFRskuhEZeh31fq8W+PaYd6DqsFLMVSZVzTZsL3SQqUlYxe1zGHROGCKbI4gVJRYBdQgFeUpLI4td88avgvGabVJZdS7Wks/GpC23J+4m+pI/Jtbtx4TTUxCeeKJR87jcEuQjs8Uy9JRzZ345kdaGN9FQ8mbTRh76RzUko7URCA179QVeap6JBQYLBP8qs7SBJXVUkb3urhGhdPBJtZbMGUkkQgFbqzc4LPtQsQtNeZNYw33N2UDVUfqLwKOoYM20ZA/dox5Z9s0YiFTBkmdNtkwyvaL7s1LQt3QnsRCYlZdTRX8hMlaiEJFE9wUzLZKkOo3f2LBGJVMc1L9aYF3lTnA7dG3UpdbePFBDeUtSq7SC2jYyzcovSBrR+171FMsGboC5TsOnewpsO+sYyr4kkK1hd7UcpwpuhkMngWBcceHpCz3vLwMbvK5oReybcb9EsKItShjBwHxm5Dd1W26Y0F8L+gERTp4uGk0+qQE/ymrxQ3W4W4LIkuXrXqZuji/vLkyeRyBc45kWcLnAHgsg+Qc+QVYZeRyrs8pD0i8BTFtAUHclfFksqoM+uBKoT1t25hTADvQkKRRVn6ucVLIXGfNdWNwpIDG5Qj3NbX44N9uWBPG48g/iXCssEoKI5zJBq57KBeqK2L0WaS3fiNW8/nOylUpk05bnslUu9i5tLeSrQJKB5Sp4ayUs0CQtB+PYc2Em4hXj8uVxt+m/ejTFwGbx580YOXTunpFNEIiHLvkdyoTuRE5H8tk0PHLxH4moRqfv3ftJx670kk84bx3UOTHXxsY9HJpmAGekxOoa/I4SP9dT7NoWFGuFR+z6yesMnyPZmlCQ8BT0R+vMYHowZ4mVPeTSoPGqUR7vKSZj5MMihUAVYceFHBSeeR5HqWOmTfy+tuyHsw7IvFPTNA+LqKZL+WjzvT3YK9wVBBd6CJTU49qpj7urx3f4iz3gtT0wHYAfdSBTxuX5p6wJ3pDsRpfIzb7dEQPEEdHLMD5Tq6H9dqhbXFnlzltL4HfsDY7m5p7FV0BqFNq+mtqADDkYHHIz2HPw7tWua2PHg6ap7FfupCg2ehzr6T9CvjUJ03nqIHcZp+Kv9jLKvBXwfiY92gaSY8mHkqSlbxcqse+d3V8JUwPJJwnqOytIdunA0PWqBwJ1Ia/bK0FKr8VigcI1cdxYyMeSJyVKoztRnyrsiV/O1XDwXOEyEZ3caplEgvhhgbIPrm9NHIppyKsSmgfhIYj0LcuvaM2rxKZxEzQWjo/H6NREyyIhVYRveySTvhMlP7ZgfSQwlbvEa5u813eouYk4QU2Sg7v7CmLszMIgpC6KYBmtSwSeVcUf2b89hqSF7ElR9VQ9YUXPFdCo5/0PRddlP4XusqEs1fYnVlVj9ER6Ji1aHv/LUN8USpmoEA4Ten8MX3jd4mKLE6kb/nRN/COaDhbDsq505dtojE5Nj17PuptRv/y3CuXslw3tUDlT1NSRj/3oXY5Pwj9HOfxPmaBpeA+P7NBZ7X9GVHm/UnNZejbOQ+uPdgWb/hlRC6Ktlf0AhHUyAap4G7cdknxfg5KGNYro31PaC7iYeNQddef4Hf+Y/eNZffhu9yA=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/tools/evaluation.py b/src/cool_compiler/cmp/tools/evaluation.py new file mode 100755 index 000000000..d49df0ce5 --- /dev/null +++ b/src/cool_compiler/cmp/tools/evaluation.py @@ -0,0 +1,3 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJxdUMFuwjAMvecrfGy3qoLrJN86YGViCO2GECrF1SLSpErcqf37OUWwsZPtZ/v5+TXetVC3Xd6NtWs7bciDbjvnGV4/FmqJmsmrE1oaWFnUQdvAla1JFbhxltQaDVm1QLJ9S75iUmdqgL4r00tx7CofKGmyMn1RoBuwjqEB56ekFAw8ce+tggaXSZMqKCWWEge8kSQnaWSRQ0EVAok2K1iZ5uwuZI88dpSJWmlfyWB4EJF03p37mrWzkSXT9ou8/HU+xgHCImrbZAZ/5xSMf6q8Yvb61DMFBYz74vCUrBOTPs/l5OV/vZ8d8N8J+U5e1tkOtIVFYrJ5PBn92OVv4ZN8q21lInR78LLXBx2giBBLjtO/hgYByASaZld4miy7b+0QV/k7NRyxLY6yGDO5swVhi54X0+bEj9vkknF6P3H3azXZFEekGWlmh7u1150HxkmQSP0BhJm25Q=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/tools/parsing.py b/src/cool_compiler/cmp/tools/parsing.py new file mode 100755 index 000000000..d0275cbcb --- /dev/null +++ b/src/cool_compiler/cmp/tools/parsing.py @@ -0,0 +1,16 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJytVVtr2zAUfvevEH2yqWfa14AeypKGlXlNL5SCMUZO5FTMlhRZbpZu++87ujiOm3QwGJRU56pzvu8cuVKiQUxTpYWoW8QaKZRGrK3ZkgaVMS4bmXSaDcbPgmvCOFUPVAcrWqGlaGSnaVGLJamLiqlWh/a3jUktX0g0CVCFnSZAEltlgKb4MFMYBUirHbiiBZbJl3YmW1YLHiD6Y0mldoZrUrc0QKxCC6OYJi3VBXWeJgMFszFUQqE5YhxJI6EUV9k8N6dp0skV0TRMIyNCIi40SpOlK6Xtk9kwVCpKvsOpT3t8oaK6UxxNR0C4VsO5a/zn7wDN8KPqoHBTV2nqmieAecM49GPrzcp8DEcZOW/tvLngj+MAnR/ht31hNUUzY5/1UNkkty7JQolVt9RMcJsDPePb5CuttDlLON+z9YsVrgCvZ4uXpwQ6B5W0qoGPXntUCEI3+ORUxNJaZ7/wNHkhalV4Nm569dWR2iNcjREWdS22AHHssB6P2GaEObXSX7DcnMJyk82TVhOlH3ZNKep3DvNkdnv9PxG/xxuPuIlmcbszCSjvGqoMEjJygMPAtjvYjm9DD86A7iBDu8udsKcN8pWYZjJm3nLI3oHxA7rcQxCCx/llDHfSKHKRQNVdv0pV6ZVQXFV+sErjkPuB2I0ltuxYvSokUS3j60KTsqZ7cmPP9pjkCo5OH8B+9xSTk7g/Y9LDvoBjj7oJoCagyhb5ZDTuafYc0zwhUlK+Ckn0fvCdHWfEwGr6hgynOx8uMTvlogd6Tt0z5ujwJg9ZaiFrqBYrUUhFVwxafRUFF4Wiyw4wfBWAXooNYx5Ef3aIWcHCyQY8xYAnNJTCRwAZt4lvkB0qTODRa+cdxdhR4FNLa5xT/BHrUCc42CbDrZ38J5zZnYvHWwmWpsEX8O8NZ0ZyC2kW396+xk+JFNK9SQRvs6bJ/bu/hi0ar5BRYkwm+2EGyV7aT3D/OUAHXwRkKjjHl8E7rVSM6/BsppRQCboq4csJPSZJcuaXxXNpgApGocNwLHCarWOSZxd+ee3bYGZJEb6mYU15uHDTHH26jO1f1Ff11A+V98hY7m9+21tOjNs/1u2lt/1sNsEfuhaMXQ=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) + +deprecated_metodo_predictivo_no_recursivo = metodo_predictivo_no_recursivo +def metodo_predictivo_no_recursivo(G, M=None, firsts=None, follows=None): + parser = deprecated_metodo_predictivo_no_recursivo(G, M, firsts, follows) + def updated(tokens): + return parser([t.token_type for t in tokens]) + return updated + +exec(zlib.decompress(base64.b64decode('eJx9U8GO2jAQvfMVZi9JtCFarqiuVLUsRUilWranCEUmGcBaY0e2s3TV7b/X9iQhpaiXxJ4Zv3nzZqYUzBiyOfK9fYKqKeE70wb0bEQ2X5ePzzQKv2hEnuZffnye0wj/zrBe0Wi9cocK9qQouOS2KGIDYp8u0lfQO2WAPjJhIHFoxDuyBV10xy6i/XdmVlquJP31uzMclFWDa7FruKiK2rHk8lBYthMQJy2JWz7/KhDQjBsg35RdnmoBJ5AWqrnWSvfPi5IJ0dVwTg9gC+OFKXRQZliMZeULzR+27lw22ihNH9xRNbZuLM29WdWgma/F4P185ALIs27AA3gECzTg5JOpDyBCqRd2BFbRc46gwcz3fwk2qzWXNg4v0+jDZDJ5f3efj1HavZptE3wXhyRpj5tIZQmXQ6EDF4KQ/4QnA+ddkCojn3ZKW6dulmV36NdgGy2dsNI3kSBuatmBDvLkV9hdZW27MTSMGjK6qJexugZZxZcITBsEuKd5D+lTBti2I/d06m8grtPgBP83D4ZgImxq53ZJ0BxS7lT1Rp0pWPZKE/N22inhRdbgGmagin1MgtmQdFarOkYQ4pYPtB3aHcmA0RV5PSUkLES/Gq2wvaa9LoGfj9jeVmG9mo1uUbrJKOxu5mzabi7s2lABEsfRRU6HI4HK+Tb7wbteJ8fJQIwx6aUPCdI1uCbt1s5/llB7dxwt5SsTvGqLGY/HUTL6AyImjec='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) + +exec(zlib.decompress(base64.b64decode('eJyFVltP4zoQfu+v8D41OcfHWl6RLJ0KekEgqLg+dKtiGrf1ktiR7RS6iP9+ZuykSYE9ywOKLzPzzTffjLuypiDLomSVV7kjqiiN9eTEaC+UlvZG+t6queKNyR0rhXVKr5urS1OUlZeLlbLOO9osc7MUedxsHZQ7PFa5tI31mZdFL5MrIl9LobMkozo97pEdz9ilfPU3u+LJ5D2iVmRHlCOXRktiLNHGkx07c7C+lbZQWuRgRaz0ldWzeY/c824KSdojKzAbEqVJxqZWbpV8STASeeZfQE40HYINuWdVmQkvk2dYCeckQMbY92wZ3buFLJ3Kje41wTGjpLQmo9/pfYpRcYGBdwy/qqVXRrt5yBpDW+lcMkAsOX97j0DD/QHCWwETJ1J7aTEJ4u0OdyG/fLaCPIG3pSw9OZe7obXGhkM84vfcxcTbJDKWG/MsNlJkLm0AvwXArx1sFBbGUTR/TkMGr/QZAeVMwV2XpO8RfG5cZYE3e5QMYt0mh7T/NYAwV/zWVrJHXjZQeHKFCK/4SOQO9oj4VKc2/0lIRjDQgQRpdBSSBh+TJi+xT6YldJIGjGvjTQ1wSqNEOYqI/qycXzxLq2UewSD8usKdMxRbNEP5YemDdf8xbj6SAu6SJ4lF3qpMZijVx0/OH/s9MuDQB7+kRl6jugPzaVtvtO3qnvNpm1k47SKT4PdDDSKotG04UXlTCC+adrvxwBctqhyaHThfQGw4BnEFsp4qlWeLi+ujRW1ndDLu8JJLWDPnha0BdgWdcn5E+2MrikLYPS2iWheo3gwI0PxwVoBv2JyN2fBqND/UQdiD0zP+23iz7yB/wwOHZ9BrrbR5NKcoE98hfWbmKUq0y5kHNQHFPBCTtHcnKUXVwtmWzzxE2vA3f2zfGxlvUZsXfAudUgbV3vHN7GJey3eK5RwzX48m9/eY6XZSuaDrQxwXAQcha75X7AQU2xVSjYegDlCI6+CG4CBSGhusnQ7kBdCsEc2X8+FD7HUdu7b6Hy7gb8tEWWI7rsP6joksW3grtFNYlmTKLkUh6QuyysC6lVjyhexaeds/PDM3G7Xy1xKqL6dwAopd5iBLAmqN6+TTDVQuynoRdV07XHjxlMvkIQz/MX9gYzZoRFqrN2nStfzrlqjLrOgpFlrqqpAWOQshQ4Ee2FbaJ+PkcWmV9omi/R++D//0D0/67KdROnHeJq9xvqKbU1S6lyle6gdyT5nKXrmqo4VYsYCShyP83E+P2jwWOAySMxfZwBaJ26SE16TtobgHd0t2IVeeHzZbbQKpLKxcK4clfGAiPhGJpLFHKexdnVOcimlUSBhMjfG+G7pvT3P4W9fT4PZ6eHp3MqRl7bfjdvrh5wEJnXPK1qDWKMC04SfkNwUuur8T/hz7ZnI2uqXrr1I6NMR2rc2wI/7FIqhlIf3GZLX89rdHFIgKEqkH6nloZGBnhO/MaHY+5/yS9oOS/4nFw4P41WxAw69ytfTfvn2DoRqtLnv/ATLgLos='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/tools/regex.py b/src/cool_compiler/cmp/tools/regex.py new file mode 100755 index 000000000..85d74325a --- /dev/null +++ b/src/cool_compiler/cmp/tools/regex.py @@ -0,0 +1,3 @@ +import zlib, base64 +exec(zlib.decompress(base64.b64decode('eJytVsFu2zgQvesreFhDVE0IdY8BCNTZtVRg2yyaOKgdwxAYiYrZSKRK0qnttp+1v7HftCQlWbLWTXPYgwzyzXDem9Fw5FyKEqRlFRKlASsrITWYalGy9EpkFF0yTuTeLW/blZe3Z6p9KsqKFVS2R2NJypLIzkULUaiQbE1IoknjBv+IpujKPC2epIVQW0l7gOAp0ZQTzQTv4JJxVrLDAN1yu+U5SbRIspwEQ376RIqtO9QKbRCaVEQqOvS3IOMPrXNJtchEUkmasVSzJ5FwkUiabo3Xk+gObzUrVHtoLh4p975gk6uXFkQpMKsUKwS3NYRdjYMLD2Q0PyqCiha5BYGkeis5+AKVNrjCE5Sb11EovHq9RloSrphNSeFvPwJP4l74hvBmX96L4sV8CttlWNDdGfI3R/LJgBy+Riq4mBgNKe4YGwm/1y/WaTh2kGV7a+Oy1JR2I7JakaiotIKsMNqvwLBNGg/vI+6FbwhvbS84uq53f8FXuHBI/pzXNdjAz7vGR642Wde0/zf5yVUYiogi3LF6NrCkD3RnLoLpPnagEmq60yhG6pFVydcNM++yIql5oXNZ823wau2BOMbfdheuZ+EOxavdOsiFBDvA+Mr/7iP/lXmgeQLz/PO3v/7hAetwMA7AUljlLAdDGkB4Bg4hU24LXYLAZKQZ31Kz1nLvoM84jlcHIwTQXUorDf6k+5mUQjbWWtnBKPOV6zF/HRiL68miDrEJSVVRnsHPxnLc1Af933wUh7O/osDYmgJvXLnut6zIkod6bjl9MY7bnQdmOA6vBJ9TWVoq6M985CrngTmK0BQt0BLdnTop6M9BBKZgAZbgzjeuFfqAbtAlIujWuPb8voNXAIIA1DkBU1jLOcLz8QIVpLzPCNggdaFWb9bIMNBTcGLqtRjhajzr49dwYweEPRM4u0m8Hg19L+tjchjhaLx8IdXS6OqjUdQyTSzT8lmmaISn47sXMt2N8Ic++tERBc7wDMd0hEkfTWEjzRhu+wbZM9yMZ+PLoa5jk8RejAct4r3Hz38QYBw0A+Ha3sVm3iaJ+XbpJHHzFrlb+t9LGZmuqKfAJzeM7SJ0vtj9un0zGQTHn8Ja2xGBzitoGVNzOVpGe0lPIzcp9gIaqlQ82LnhxkZwdnKdpXwulQ0ezqT6yJmhVB+yFxu/hxu7mOPTTzXMkcPf4Xl4/IRZYIG7PwDwnUUe8dn/DXARdMk/ev8C0IsPHg=='))) +# Created by pyminifier (https://github.com/liftoff/pyminifier) diff --git a/src/cool_compiler/cmp/utils.py b/src/cool_compiler/cmp/utils.py new file mode 100755 index 000000000..2d844bdea --- /dev/null +++ b/src/cool_compiler/cmp/utils.py @@ -0,0 +1,223 @@ +from cmp.pycompiler import Production, Sentence, Symbol, EOF, Epsilon + +class ContainerSet: + def __init__(self, *values, contains_epsilon=False): + self.set = set(values) + self.contains_epsilon = contains_epsilon + + def add(self, value): + n = len(self.set) + self.set.add(value) + return n != len(self.set) + + def extend(self, values): + change = False + for value in values: + change |= self.add(value) + return change + + def set_epsilon(self, value=True): + last = self.contains_epsilon + self.contains_epsilon = value + return last != self.contains_epsilon + + def update(self, other): + n = len(self.set) + self.set.update(other.set) + return n != len(self.set) + + def epsilon_update(self, other): + return self.set_epsilon(self.contains_epsilon | other.contains_epsilon) + + def hard_update(self, other): + return self.update(other) | self.epsilon_update(other) + + def find_match(self, match): + for item in self.set: + if item == match: + return item + return None + + def __len__(self): + return len(self.set) + int(self.contains_epsilon) + + def __str__(self): + return '%s-%s' % (str(self.set), self.contains_epsilon) + + def __repr__(self): + return str(self) + + def __iter__(self): + return iter(self.set) + + def __nonzero__(self): + return len(self) > 0 + + def __eq__(self, other): + if isinstance(other, set): + return self.set == other + return isinstance(other, ContainerSet) and self.set == other.set and self.contains_epsilon == other.contains_epsilon + + +def inspect(item, grammar_name='G', mapper=None): + try: + return mapper[item] + except (TypeError, KeyError ): + if isinstance(item, dict): + items = ',\n '.join(f'{inspect(key, grammar_name, mapper)}: {inspect(value, grammar_name, mapper)}' for key, value in item.items() ) + return f'{{\n {items} \n}}' + elif isinstance(item, ContainerSet): + args = f'{ ", ".join(inspect(x, grammar_name, mapper) for x in item.set) } ,' if item.set else '' + return f'ContainerSet({args} contains_epsilon={item.contains_epsilon})' + elif isinstance(item, EOF): + return f'{grammar_name}.EOF' + elif isinstance(item, Epsilon): + return f'{grammar_name}.Epsilon' + elif isinstance(item, Symbol): + return f"G['{item.Name}']" + elif isinstance(item, Sentence): + items = ', '.join(inspect(s, grammar_name, mapper) for s in item._symbols) + return f'Sentence({items})' + elif isinstance(item, Production): + left = inspect(item.Left, grammar_name, mapper) + right = inspect(item.Right, grammar_name, mapper) + return f'Production({left}, {right})' + elif isinstance(item, tuple) or isinstance(item, list): + ctor = ('(', ')') if isinstance(item, tuple) else ('[',']') + return f'{ctor[0]} {("%s, " * len(item)) % tuple(inspect(x, grammar_name, mapper) for x in item)}{ctor[1]}' + else: + raise ValueError(f'Invalid: {item}') + +def pprint(item, header=""): + if header: + print(header) + + if isinstance(item, dict): + for key, value in item.items(): + print(f'{key} ---> {value}') + elif isinstance(item, list): + print('[') + for x in item: + print(f' {repr(x)}') + print(']') + else: + print(item) + +class Token: + """ + Basic token class. + + Parameters + ---------- + lex : str + Token's lexeme. + token_type : Enum + Token's type. + """ + + def __init__(self, lex, token_type): + self.lex = lex + self.token_type = token_type + + def __str__(self): + return f'{self.token_type}: {self.lex}' + + def __repr__(self): + return str(self) + + def __eq__(self,other): + if not isinstance(other,Token): return False + return self.lex == other.lex and self.token_type == other.token_type + + @property + def is_valid(self): + return True + +class UnknownToken(Token): + def __init__(self, lex): + Token.__init__(self, lex, None) + + def transform_to(self, token_type): + return Token(self.lex, token_type) + + @property + def is_valid(self): + return False + +def tokenizer(G, fixed_tokens): + def decorate(func): + def tokenize_text(text): + tokens = [] + for lex in text.split(): + try: + token = fixed_tokens[lex] + except KeyError: + token = UnknownToken(lex) + try: + token = func(token) + except TypeError: + pass + tokens.append(token) + tokens.append(Token('$', G.EOF)) + return tokens + + if hasattr(func, '__call__'): + return tokenize_text + elif isinstance(func, str): + return tokenize_text(func) + else: + raise TypeError('Argument must be "str" or a callable object.') + return decorate + +class DisjointSet: + def __init__(self, *items): + self.nodes = { x: DisjointNode(x) for x in items } + + def merge(self, items): + items = (self.nodes[x] for x in items) + try: + head, *others = items + for other in others: + head.merge(other) + except ValueError: + pass + + @property + def representatives(self): + return { n.representative for n in self.nodes.values() } + + @property + def groups(self): + return [[n for n in self.nodes.values() if n.representative == r] for r in self.representatives] + + def __len__(self): + return len(self.representatives) + + def __getitem__(self, item): + return self.nodes[item] + + def __str__(self): + return str(self.groups) + + def __repr__(self): + return str(self) + +class DisjointNode: + def __init__(self, value): + self.value = value + self.parent = self + + @property + def representative(self): + if self.parent != self: + self.parent = self.parent.representative + return self.parent + + def merge(self, other): + other.representative.parent = self.representative + + def __str__(self): + return str(self.value) + + def __repr__(self): + return str(self) \ No newline at end of file diff --git a/src/cool_compiler/cmp/visitor.py b/src/cool_compiler/cmp/visitor.py new file mode 100755 index 000000000..f96015194 --- /dev/null +++ b/src/cool_compiler/cmp/visitor.py @@ -0,0 +1,92 @@ +import inspect + +__all__ = ['on', 'when'] + +def result(cls): + def f(fn): + def ff(*args, **kword): + result = cls(*fn(*args, **kword)) + result.get_pos_to_error(args[1].lineno, args[1].index) + return result + ff.__name__ = fn.__name__ + return ff + return f + +def inmutable_visit(fn): + def f(*args, **kword): + fn(*args, **kword) + return args[1] + f.__name__ = fn.__name__ + return f + +def on(param_name): + def f(fn): + dispatcher = Dispatcher(param_name, fn) + return dispatcher + return f + + +def add(node_type, accion_class, result): + def f(fn): + frame = inspect.currentframe().f_back + def __init__(self,*args, **kword): + a = accion_class(self) + + @when(node_type, frame) + def visit(*args,**kw) : + node = result(*a.visit(*args, **kw)) + node.get_pos_to_error(args[0].lineno, args[0].index) + return node + + fn(self, *args, **kword) + return __init__ + return f + +def when(param_type, frame = None): + def f(fn): + nonlocal frame + frame = inspect.currentframe().f_back if frame is None else frame + func_name = fn.func_name if 'func_name' in dir(fn) else fn.__name__ + dispatcher = frame.f_locals[func_name] + if not isinstance(dispatcher, Dispatcher): + dispatcher = dispatcher.dispatcher + dispatcher.add_target(param_type, fn) + def ff(*args, **kw): + return dispatcher(*args, **kw) + ff.dispatcher = dispatcher + return ff + return f + + +class Dispatcher(object): + def __init__(self, param_name, fn): + frame = inspect.currentframe().f_back.f_back + top_level = frame.f_locals == frame.f_globals + self.param_index = self.__argspec(fn).args.index(param_name) + 1 + self.param_name = param_name + self.targets = {} + + def __call__(self, *args, **kw): + typ = args[self.param_index].__class__ + d = self.targets.get(typ) + if d is not None: + return d(*args, **kw) + else: + issub = issubclass + t = self.targets + ks = t.keys() + ans = [t[k](*args, **kw) for k in ks if issub(typ, k)] + if len(ans) == 1: + return ans.pop() + return ans + + def add_target(self, typ, target): + self.targets[typ] = target + + @staticmethod + def __argspec(fn): + # Support for Python 3 type hints requires inspect.getfullargspec + if hasattr(inspect, 'getfullargspec'): + return inspect.getfullargspec(fn) + else: + return inspect.getargspec(fn) diff --git a/src/cool_compiler/codegen/__dependency.py b/src/cool_compiler/codegen/__dependency.py new file mode 100755 index 000000000..e69de29bb diff --git a/src/cool_compiler/codegen/__init__.py b/src/cool_compiler/codegen/__init__.py new file mode 100755 index 000000000..b82ef15a0 --- /dev/null +++ b/src/cool_compiler/codegen/__init__.py @@ -0,0 +1,3 @@ +# from .v0_type_data_code.type_data_code_visitor import CILGenerate +from .v0_cool_to_cil.cool_to_cil_visitor import CoolToCIL +from .v1_mips_generate.mips_generate_visitor import MipsGenerate \ No newline at end of file diff --git a/src/cool_compiler/codegen/mips_code/dynamic_call_func.mips b/src/cool_compiler/codegen/mips_code/dynamic_call_func.mips new file mode 100644 index 000000000..bacc5c687 --- /dev/null +++ b/src/cool_compiler/codegen/mips_code/dynamic_call_func.mips @@ -0,0 +1,60 @@ +.data +Main_parents: .word 1 2 3 +Main: .word Main_parents f1 +endLine: .asciiz "\n" + +.text +.globl main +main: + +li $a0, 4 +li $v0, 9 +syscall +sw $v0, 0($sp) + +lw $t0, 0($sp) # Lee la instancia en la pila +la $t1, Main # Guarda en $t1 la direccion de Main +lw $t2, Main_parents # Gaurda en $t2 el primer valor de Main_parents +sw $t1, 0($t0) # Guarda en 0($t0) lo que esta en $t1 osea la direccion de Main +lw $t3, 0($t0) # Guarda en $t3 lo que esta en 0($t0) osea la direccionn de Main + +li $v0, 1 # system call #4 - print string +la $a0, Main # Imprime direccion de Main +syscall # execute + +li $v0, 4 # system call #4 - print string +la $a0, endLine +syscall + +li $v0, 1 # system call #4 - print string +la $a0, ($t2) # Imprime 1 primer elemento de Main_parents +syscall # execute + +li $v0, 4 # system call #4 - print string +la $a0, endLine +syscall # execute + +li $v0, 1 # system call #4 - print string +la $a0, 0($t3) # Imprime direccion de Main +syscall # execute + +li $v0, 4 # system call #4 - print string +la $a0, endLine +syscall # execute + +lw $t4, 4($t3) +jal $t4 + +li $v0, 4 # system call #4 - print string +la $a0, endLine +syscall # execute + +li $v0, 10 +syscall # execute + + +f1: +li $v0, 1 # system call #4 - print string +la $a0, 10 +syscall # execute +jr $ra \ No newline at end of file diff --git a/src/cool_compiler/codegen/mips_code/hello_word.mips b/src/cool_compiler/codegen/mips_code/hello_word.mips new file mode 100644 index 000000000..b4521a298 --- /dev/null +++ b/src/cool_compiler/codegen/mips_code/hello_word.mips @@ -0,0 +1,77 @@ +.data +Bool_parents: .word 1, 2, 0, +Bool: .word Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int: .word Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String: .word String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE: .word SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object: .word Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO: .word IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main: .word Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "Hello, World.\n" + +.text +.globl main +main: +#Parametro Return $ra en stackpoiner + 20 +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance stackpointer 12 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var @result stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +#Allocate a una class Main puntero en sp + 12 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +la $t0, Main +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data +lw $t0, 12($sp) #Buscando la instancia en la pila instance +lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor en la direccion de la memoria del objeto #Assignando el nombre del tipo en el campo type +lw $t0, 12($sp) #Saca de la pila instance +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance +jal Main_main #Call a la function Main_main +sw $s0, 4($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +li $v0, 10 +syscall + +Main_main: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var @result stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +la $t0, string_0 +sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 12($sp) #Saca de la pila self +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch out_string +lw $t0, 12($sp) #Saca de la pila param_0_to_out_string@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@0 #Agrega a la pila el paramentro 1 al StaticDispatch out_string +jal IO_out_string #Call a la function IO_out_string +sw $s0, 4($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 16($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 #Limpia la pila +jr $ra #Final de la function main + + +IO_out_string: +li $v0, 4 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra diff --git a/src/cool_compiler/codegen/mips_code/in_string.mips b/src/cool_compiler/codegen/mips_code/in_string.mips new file mode 100644 index 000000000..b13b77b91 --- /dev/null +++ b/src/cool_compiler/codegen/mips_code/in_string.mips @@ -0,0 +1,21 @@ + +.text +.globl main +main: + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 la instancia del nuevo string + + +move $a0, $v0 +li $v0, 8 +li $a1 , 1000 +syscall +move $s0 $a0 + +li $v0, 4 # system call #3 - print double +syscall # execute + +li $v0, 10 # system call #4 - print string +syscall # execute \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_ast.py b/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_ast.py new file mode 100644 index 000000000..d2f258206 --- /dev/null +++ b/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_ast.py @@ -0,0 +1,269 @@ +super_value = '' + +class Program: + def __init__(self) -> None: + self.ty_list = [] + self.types = {} + self.data_list = [] + self.data = {} + self.func_list = [] + self.functions = {} + + def __str__(self) -> str: + result = ".TYPE\n" + + for ty in self.ty_list: + result += str(self.types[ty]) + '\n' + + result += ".DATA\n" + for data in self.data_list: + result += str(self.data[data]) + '\n' + + result += ".FUNCTION\n" + for func in self.func_list: + result += str(self.functions[func]) + '\n' + + return result + + def try_add_data(self, name, value): + try: + _ = self.data[name] + except KeyError: + self.data[name] = Data(name, value) + + def add_data(self, name, value): + index = 0 + while f'{name}_{index}' in self.data_list: index += 1 + self.data_list.append(f'{name}_{index}') + self.data[self.data_list[-1]] = Data(self.data_list[-1], value) + return self.data_list[-1] + + def force_data(self, name, value): + self.data_list.append(name) + self.data[self.data_list[-1]] = Data(self.data_list[-1], value) + return self.data_list[-1] + + def add_type(self, type): + self.ty_list.append(type.name) + self.types[type.name] = type + + def add_func(self, func): + self.func_list.append(func.name) + self.functions[func.name] = func + +class Type: + def __init__(self, name) -> None: + self.name = name + self.attributes = [] + self.attr = {} + self.method_list = [] + self.methods = {} + + def attr_push(self, name, _name): + if not name in self.attributes: + self.attributes.append(name) + + self.attr[name] = _name + + def method_push(self, name, f): + try: + self.methods[name] + except KeyError: + self.method_list.append(name) + + self.methods[name] = f + + def __str__(self) -> str: + result = f'type {self.name}: ' + '{\n' + + for att in self.attributes: + result += '\tattribute ' + str(att) + ' '*(14 - len(str(att))) + '-> ' + str(self.attr[att]) + '\n' + + for func in self.method_list: + result += '\tfunction ' + str(func) + ' '*(15 - len(str(func))) + '-> ' + str(self.methods[func]) + '\n' + + return result + '}' + +class Data: + def __init__(self, name, value) -> None: + self.name = name + self.value = value + + def __str__(self) -> str: + return f'\tdata {self.name}: {self.value}' + +class Function: + def __init__(self, name) -> None: + self.name = name + self.var_dir = {} + self.param = [] + self.local = [] + self.expr = [] + + def get_name(self, name): + index = 0 + while True: + try: + _ = self.var_dir[f'{name}@{index}'] + index += 1 + except KeyError: + return f'{name}@{index}' + + def force_local(self,name, scope): + scope.define_variable(name, name) + self.var_dir[name] = 1 + self.local.append(name) + return name + + def force_parma(self,name, scope): + self.var_dir[name] = 1 + scope.define_variable(name, name) + self.param.append(name) + return name + + def param_push(self, name, scope): + new_name = self.get_name(name) + scope.define_variable(name, new_name) + self.var_dir[new_name] = 1 + self.param.append(new_name) + return new_name + + def local_push(self, name, scope): + new_name = self.get_name(name) + scope.define_variable(name, new_name) + self.var_dir[new_name] = 1 + self.local.append(new_name) + return new_name + + def expr_push(self, expr): + self.expr.append(expr) + + def __str__(self) -> str: + result = f'function {self.name}: ' + '{\n' + + for param in self.param: + result += f'\tPARAM {str(param)}\n' + + for local in self.local: + result += f'\tLOCAL {str(local)}\n' + + for exp in self.expr: + result += '\t' + str(exp) + '\n' + + return result + '}' + +class Expression: + def __init__(self, x = None, y = None, z = None) -> None: + self.x = x + self.y = y + self.z = z + + def try_set_value(self, name): + if self.x == super_value: + self.x = name + return True + return False + + def set_value(self, name): + if not self.x == super_value: + raise Exception("The expression is'nt set expression") + self.x = name + + @property + def can_fusion(self): + return False + + def __str__(self) -> str: + result = self.__class__.__name__ + ' ' + + if not self.x is None: + result += str(self.x) + " " + + if not self.y is None: + result += str(self.y) + " " + + if not self.z is None: + result += str(self.z) + " " + + return result + +class Assign(Expression): + @property + def can_fusion(self): + return True + +class GetAttr(Expression): + pass + +class SetAttr(Expression): + pass + +class Sum(Expression): + pass + +class Rest(Expression): + pass + +class Div(Expression): + pass + +class Mult(Expression): + pass + +class Less(Expression): + pass + +class LessOrEqual(Expression): + pass + +class Equals(Expression): + pass + +class CheckType(Expression): + pass + +class Return(Expression): + pass + +class Arg(Expression): + pass + +class VCall(Expression): + pass + +class Call(Expression): + pass + +class SimpleCall(Expression): + pass + +class New(Expression): + pass + +class Load(Expression): + pass + +class ALLOCATE(Expression): + pass + +class IfGoTo(Expression): + pass + +class GoTo(Expression): + pass + +class Label(Expression): + pass + +class TypeOf(Expression): + pass + +class Neg(Expression): + pass + +class Complemnet(Expression): + pass + +class Comment(Expression): + def __str__(self) -> str: + return "" \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_visitor.py b/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_visitor.py new file mode 100644 index 000000000..d243d681e --- /dev/null +++ b/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_visitor.py @@ -0,0 +1,520 @@ +from cool_compiler.cmp.scope import Scope +from cool_compiler.types.cool_type_build_in_manager import OBJECT_NAME, CoolTypeBuildInManager +from ...cmp import visitor +from ...semantic.v2_semantic_checking import semantic_checking_ast as AST +from . import cool_to_cil_ast as ASTR +from .cool_to_cil_ast import super_value +from .tools import BaseCoolToCIL + +CoolInt = CoolTypeBuildInManager().find("Int") +CoolBool = CoolTypeBuildInManager().find("Bool") +CoolStr = CoolTypeBuildInManager().find("String") +CoolObject = CoolTypeBuildInManager().find(OBJECT_NAME) + +class CoolToCIL(BaseCoolToCIL): + def __init__(self, error) -> None: + self.label_list = {} + self.type_dir = { + OBJECT_NAME: 1 + } + + @visitor.on('node') + def visit(node, scope: Scope): + pass + + @visitor.when(AST.Program) + def visit(self, node: AST.Program, scope: Scope = None): + self.program = ASTR.Program() + self.program.try_add_data('_______error______', 'Abort called from class ') + self.program.try_add_data('_______null_______', 'null') + self.program.try_add_data('_______endline_______', '\n') + self.program.try_add_data('_______void_str_______', '') + + scope = Scope() + + _dictt = CoolTypeBuildInManager().dictt + for _type in _dictt.values(): + self.create_type(_type, scope) + self.new_type_func.expr_push(ASTR.Return('self')) + self.program.add_func(self.new_type_func) + + for cls in node.class_list: + _ = [self.map_type(parent.name) for parent in self.parent_list(cls.type)] + + for cls in node.class_list: + self.visit(cls, scope) + + + + main = ASTR.Function('main') + main.force_local('self', scope) + # main.force_local(result, scope) + main.expr_push(ASTR.ALLOCATE('self', 'Main')) + main.expr_push(ASTR.Comment(f'Assignacion de la insformacion de tipo a Main')) + main.expr_push(ASTR.Load('_', 'Main')) + main.expr_push(ASTR.SetAttr('self', 'type_name', '_')) + main.expr_push(ASTR.Arg('self')) + main.expr_push(ASTR.SimpleCall('new_ctr_Main')) + main.expr_push(ASTR.Arg('self')) + main.expr_push(ASTR.SimpleCall('Main_main')) + # main.expr_push(ASTR.VCall(result, 'Main', 'main')) + main.expr_push(ASTR.Return(0)) + self.program.add_func(main) + + return self.program + + @visitor.when(AST.CoolClass) + def visit(self, node: AST.CoolClass, scope: Scope): + self.class_scope = scope.create_child(node.type.name) + + self.create_type(node.type, scope) + for feat in node.feature_list: + self.visit(feat, self.class_scope) + + + self.new_type_func.expr_push(ASTR.Return('self')) + self.program.add_func(self.new_type_func) + + def create_type(self, _type, scope): + self.currentType = ASTR.Type(_type.name) + self.currentClass = _type + + self.program.add_type(self.currentType) + + type_list = [] + for parent in self.parent_list(_type): + type_list.append(self.map_type(parent.name)) + self.currentType.attr_push('type_name', self.currentType.name) + for attr in parent.attributes: + self.currentType.attr_push(attr.name, f'{parent.name}@{attr.name}') + for func in parent.methods: + self.currentType.method_push(func.name, f'{parent.name}_{func.name}') + + self.program.force_data(f'{_type.name}_parents', type_list + [0]) + self.program.force_data(f'{_type.name}_Name', _type.name) + self.program.force_data(_type.name, + [f'{_type.name}_Name', len(self.currentType.attr), f'{_type.name}_parents'] + + [self.currentType.methods[key] for key in self.currentType.methods.keys()]) + + self.create_new_func_by_type(_type, scope) + + def create_new_func_by_type(self, _type, scope): + self.new_class_scope = scope.create_child(f'new_{_type.name}') + self.new_type_func = ASTR.Function(f'new_ctr_{_type.name}') + self.new_type_func.force_parma('self', self.new_class_scope) + # tn = self.new_type_func.local_push('type_name', self.new_class_scope) + + if not _type.parent is None: + self.new_type_func.expr_push(ASTR.Arg('self')) + self.new_type_func.expr_push(ASTR.SimpleCall(f'new_ctr_{_type.parent.name}')) + + # self.new_type_func.expr_push(ASTR.Comment(f'Assignacion de la insformacion de tipo a la instancia')) + # self.new_type_func.expr_push(ASTR.Load('_', _type.name)) + # self.new_type_func.expr_push(ASTR.SetAttr('self', 'type_name', '_')) + # self.new_type_func.expr_push(ASTR.Comment(f'FIN de la assignacion de la insformacion de tipo a la instancia')) + + @visitor.when(AST.AtrDef) + def visit(self, node: AST.AtrDef, scope: Scope): + try: + save_current_func = self.currentFunc + except AttributeError: + save_current_func = None + self.currentFunc = self.new_type_func + + if not node.expr in [None, []]: + + # attr_name = self.new_type_func.local_push(f'value_to_set_{node.name}', self.new_class_scope) + exp_list = [ASTR.Comment(f'Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}')] + exp_list += self.visit(node.expr, self.new_class_scope) + exp_list[-1].set_value("_") + exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.name], '_')) + exp_list.append(ASTR.Comment(f"Fin De la Asignacion")) + self.new_type_func.expr += exp_list + + elif node.type == CoolInt: + self.new_type_func.expr_push(ASTR.Assign('_', 0)) + self.new_type_func.expr_push(ASTR.VCall('_', f'__int__new__', '_')) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], '_')) + elif node.type == CoolBool: + self.new_type_func.expr_push(ASTR.Assign('_', 0)) + self.new_type_func.expr_push(ASTR.VCall('_', f'__int__new__', '_')) + self.new_type_func.expr_push(ASTR.VCall('_', f'__bool__new__', '_')) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], '_')) + elif node.type == CoolStr: + self.new_type_func.expr_push(ASTR.Load('_', '_______void_str_______')) + self.new_type_func.expr_push(ASTR.VCall('_', f'__str__new__', '_')) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], '_')) + else: + self.new_type_func.expr_push(ASTR.Load('_', '_______null_______')) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], '_')) + + self.currentFunc = save_current_func + + @visitor.when(AST.FuncDef) + def visit(self, node: AST.FuncDef, scope: Scope): + func_scope = scope.create_child(node.name) + self.currentFunc = ASTR.Function(f'{self.currentType.name}_{node.name}') + self.program.add_func(self.currentFunc) + + self.currentFunc.force_parma('self', func_scope) + for name, t_params in node.params: + self.currentFunc.param_push(name, func_scope) + + expr_list = self.visit(node.expr, func_scope) + if not any(expr_list): + self.visit(node.expr, func_scope) + # self.currentFunc.force_local(result, func_scope) + cond = expr_list[-1].try_set_value('_') + + expr_list.append(ASTR.Return('_' if cond else 'self')) + + self.currentFunc.expr = expr_list + + @visitor.when(AST.CastingDispatch) + def visit(self, node: AST.CastingDispatch, scope: Scope): + instance_expr_list = [ASTR.Comment(f"Evalua la Expresion para el CastingDispatch {node.id}")] + instance_expr_list += self.visit(node.expr, scope) + instance_name = self.currentFunc.local_push(f'instance_{node.type.name}_to_{node.id}', scope) + instance_expr_list[-1].set_value(instance_name) + instance_expr_list.append(ASTR.Comment(f"Fin de la exprecion previa al CastingDispatch {node.id}")) + + arg_list = [instance_name] + for i, param in enumerate(node.params): + instance_expr_list += [ASTR.Comment(f"Evalua el parametro {i} para el CastingDispatch {node.id}")] + instance_expr_list += self.visit(param, scope) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) + instance_expr_list[-1].set_value(param_name) + instance_expr_list.append(ASTR.Comment(f"Fin del paramentro {i} al CastingDispatch {node.id}")) + arg_list.append(param_name) + + if len(arg_list) == 1: + _list, new_name = self.try_funsion(instance_expr_list[0:-1], instance_name) + _list.append(instance_expr_list[-1]) + instance_expr_list = _list + arg_list[0] = new_name + + for i, arg in enumerate(arg_list): + instance_expr_list.append(ASTR.Arg(arg)) + + instance_expr_list.append(ASTR.VCall(super_value, node.type.name, node.id)) + return instance_expr_list + + @visitor.when(AST.Dispatch) + def visit(self, node: AST.Dispatch, scope: Scope): + instance_expr_list = [ASTR.Comment(f"Evalua la Expresion para el DinamicDispatch {node.id}")] + instance_expr_list += self.visit(node.expr, scope) + instance_name = self.currentFunc.local_push(f'instance_dynamic_to_{node.id}', scope) + instance_expr_list[-1].set_value(instance_name) + instance_expr_list.append(ASTR.Comment(f"Fin de la exprecion previa al DinamicDispatch {node.id}")) + + arg_list = [instance_name] + for i, param in enumerate(node.params): + instance_expr_list += [ASTR.Comment(f"Evalua el parametro {i} para el CastingDispatch {node.id}")] + instance_expr_list += self.visit(param, scope) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) + instance_expr_list[-1].set_value(param_name) + instance_expr_list.append(ASTR.Comment(f"Fin del paramentro {i} al CastingDispatch {node.id}")) + arg_list.append(param_name) + + if len(arg_list) == 1: + _list, new_name = self.try_funsion(instance_expr_list[0:-1], instance_name) + _list.append(instance_expr_list[-1]) + instance_expr_list = _list + arg_list[0] = new_name + instance_name = new_name + + for i, arg in enumerate(arg_list): + instance_expr_list.append(ASTR.Arg(arg)) + + instance_expr_list.append(ASTR.Call(super_value, instance_name, f'{node.expr.static_type.name}@{node.id}')) + return instance_expr_list + + @visitor.when(AST.StaticDispatch) + def visit(self, node: AST.StaticDispatch, scope: Scope): + instance_expr_list = [ASTR.Comment(f"StaticDispatch {node.id}")] + + arg_list = ['self'] + for i, param in enumerate(node.params): + instance_expr_list += [ASTR.Comment(f"Evalua el parametro {i} para el CastingDispatch {node.id}")] + instance_expr_list += self.visit(param, scope) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) + instance_expr_list[-1].set_value(param_name) + instance_expr_list.append(ASTR.Comment(f"Fin del paramentro {i} al CastingDispatch {node.id}")) + arg_list.append(param_name) + + for i, arg in enumerate(arg_list): + instance_expr_list.append(ASTR.Arg(arg)) + + instance_expr_list.append(ASTR.Call(super_value, 'self', f'{self.currentClass.name}@{node.id}')) + # instance_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) + return instance_expr_list + + @visitor.when(AST.Assing) + def visit(self, node: AST.Assing, scope: Scope): + exp_list = [ASTR.Comment(f'Asignando un nuevo valor a la variable {node.id}')] + exp_list += self.visit(node.expr, scope) + exp_list[-1].set_value('_') + + + var = scope.find_variable(node.id) + if not var is None: + exp_list.append(ASTR.Assign(var.type, '_')) + exp_list.append(ASTR.Assign(super_value, var.type)) + else: + exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.id], '_')) + exp_list.append(ASTR.GetAttr(super_value , 'self', self.currentType.attr[node.id])) + + return exp_list + + @visitor.when(AST.IfThenElse) + def visit(self, node: AST.IfThenElse, scope: Scope): + # cond_result = self.currentFunc.local_push(f'cond@if_else', scope) + expr_list = [ASTR.Comment(f'Evalua la condicion de un If')] + expr_list += self.visit(node.condition, scope) + expr_list[-1].set_value('_') + expr_list.append(ASTR.Comment(f'Fin de la evaluacion de la condicion de un IF')) + + label_then = self.new_name(f'then_{self.currentFunc.name}', self.label_list) + label_fin = self.new_name(f'fin_{self.currentFunc.name}', self.label_list) + expr_list.append(ASTR.IfGoTo('_', label_then)) + + expr_list.append(ASTR.Comment(f'Else case')) + else_list = self.visit(node.else_expr, scope) + else_list[-1].set_value('_') + expr_list += else_list + [ASTR.GoTo(label_fin), ASTR.Label(label_then)] + + expr_list.append(ASTR.Comment(f'Then case')) + then_list = self.visit(node.then_expr, scope) + then_list[-1].set_value('_') + + expr_list += then_list + [ASTR.Label(label_fin)] + expr_list.append(ASTR.Comment(f'Fin de un If')) + + return expr_list + [ASTR.Assign(super_value, '_')] + + @visitor.when(AST.While) + def visit(self, node: AST.While, scope: Scope): + while_cond = self.new_name('while_cond', self.label_list) + while_back = self.new_name('while_back', self.label_list) + + # result_local = self.currentFunc.local_push('result@while', scope) + + result_list = [ASTR.Comment(f'Inicio de un While'), ASTR.GoTo(while_cond), ASTR.Label(while_back)] + result_list += self.visit(node.loop_expr, scope) + result_list[-1].set_value('_') + result_list.append(ASTR.Comment(f'Fin del cuerpo e inicio de la condicion de un While')) + result_list.append(ASTR.Label(while_cond)) + + # cond_local = self.currentFunc.local_push('cond@while', scope) + result_list += self.visit(node.condition, scope) + result_list[-1].set_value("_") + # result_list.append(self.get_value('_', 'Bool')) + result_list.append(ASTR.IfGoTo('_', while_back)) + result_list.append(ASTR.Comment(f'Fin de la condicion de un While')) + + + # while return object + return result_list + [ASTR.Assign(super_value, 'self')] + + @visitor.when(AST.Block) + def visit(self, node: AST.Block, scope: Scope): + result_list = [] + result_list.append(ASTR.Comment(f'Inicio de una secuencia Block')) + _len = len(node.expr_list) - 1 + for i, expr in enumerate(node.expr_list): + if i == _len: result_step = super_value + else: result_step = '_' + result_list.append(ASTR.Comment(f'Inicio del paso {i} de una sequencia Block')) + result_list += self.visit(expr, scope) + result_list[-1].set_value(result_step) + + # result_list.append(ASTR.Comment(f'Fin de una sequencia Block')) + return result_list + + @visitor.when(AST.LetIn) + def visit(self, node: AST.LetIn, scope: Scope): + result_list = [] + let_scope = scope.create_child('let') + for name, atype, expr in node.assing_list: + local_name = self.currentFunc.force_local(name, let_scope) + if not expr is None: + result_list.append(ASTR.Comment(f'Eval Expression to Let {name}')) + result_list += self.visit(expr, let_scope) + result_list[-1].set_value(local_name) + result_list.append(ASTR.Comment(f'Fin de la asignacion Let {name}')) + elif atype == CoolInt: + result_list.append(ASTR.Assign('_', 0)) + result_list.append(ASTR.VCall('_', f'__int__new__', '_')) + result_list.append(ASTR.Assign(name, '_')) + elif atype == CoolBool: + result_list.append(ASTR.Assign('_', 0)) + result_list.append(ASTR.VCall('_', f'__int__new__', '_')) + result_list.append(ASTR.VCall('_', f'__bool__new__', '_')) + result_list.append(ASTR.Assign(name, '_')) + elif atype == CoolStr: + result_list.append(ASTR.Load('_', '_______void_str_______')) + result_list.append(ASTR.VCall('_', f'__str__new__', '_')) + result_list.append(ASTR.Assign(name, '_')) + else: + result_list.append(ASTR.Load('_', '_______null_______')) + result_list.append(ASTR.Assign(name, '_')) + + + return result_list + self.visit(node.expr, let_scope) + + @visitor.when(AST.Case) + def visit(self, node: AST.Case, scope: Scope): + expr_cond_list = [ASTR.Comment("Eval Expression To Case")] + expr_value = self.currentFunc.local_push('cond@expr@value', scope) + type_result = self.currentFunc.local_push('cond@type', scope) + expr_cond_list += self.visit(node.expr, scope) + expr_cond_list[-1].set_value(expr_value) + expr_cond_list.append(ASTR.TypeOf(type_result, expr_value)) + expr_cond_list.append(ASTR.Comment("Final Expression To Case")) + + + expr_list = [] + end_label = self.new_name('case_end', self.label_list) + + sorted_case = sorted(node.case_list, key=lambda a: self.map_type(a[1].name), reverse=True) + for name, atype , expr in sorted_case: + expr_cond_list.append(ASTR.Comment(f"Check Type To Case When Option Is {atype.name}")) + step_label = self.new_name(f'{atype.name}_step_case', self.label_list) + expr_cond_list.append(ASTR.Assign('_', self.map_type(atype.name))) + expr_cond_list.append(ASTR.CheckType('_', type_result, '_')) + expr_cond_list.append(ASTR.IfGoTo('_', step_label)) + + + expr_list.append(ASTR.Label(step_label)) + step_scope = scope.create_child('step_case') + self.currentFunc.force_local(name, step_scope) + expr_list.append(ASTR.Comment(f"Assigan el valor de la expresion a la var {name} del case")) + expr_list.append(ASTR.Assign(name, expr_value)) + expr_list.append(ASTR.Comment(f"Eval Expression Of {atype.name} Option")) + expr_list += self.visit(expr, step_scope) + expr_list[-1].set_value('_') + expr_list.append(ASTR.GoTo(end_label)) + + return ( + expr_cond_list + + expr_list + + [ASTR.Label(end_label)] + + [ASTR.Assign(super_value, '_')] + ) + + def binary_op(self, name, node, astr_node, scope: Scope): + op_1 = self.currentFunc.local_push(f'{name}@_a', scope) + op_2 = self.currentFunc.local_push(f'{name}@_b', scope) + + result_list = [ASTR.Comment(f'Evaluando el operado izquierdo de una operacion {name}')] + result_list += self.visit(node.left, scope) + result_list[-1].set_value(op_1) + result_list.append(ASTR.Comment(f'Resolucion del operado izquierdo de una operacion {name}')) + + result_list += [ASTR.Comment(f'Evaluando el operado derecho de una operacion {name}')] + result_list += self.visit(node.right, scope) + result_list[-1].set_value(op_2) + result_list.append(ASTR.Comment(f'Resolucion del operado derecha de una operacion {name}')) + + return result_list + [astr_node(super_value, op_1, op_2)] + + @visitor.when(AST.Sum) + def visit(self, node: AST.Sum, scope: Scope): + return self.binary_op('sum', node, ASTR.Sum, scope) + + @visitor.when(AST.Rest) + def visit(self, node: AST.Rest, scope: Scope): + return self.binary_op('rest', node, ASTR.Rest, scope) + + @visitor.when(AST.Mult) + def visit(self, node: AST.Mult, scope: Scope): + return self.binary_op('factor', node, ASTR.Mult, scope) + + @visitor.when(AST.Div) + def visit(self, node: AST.Div, scope: Scope): + return self.binary_op('div', node, ASTR.Div, scope) + + @visitor.when(AST.Less) + def visit(self, node: AST.Less, scope: Scope): + return self.binary_op('less', node, ASTR.Less, scope) + + @visitor.when(AST.LessOrEquals) + def visit(self, node: AST.LessOrEquals, scope: Scope): + return self.binary_op('leq', node, ASTR.LessOrEqual, scope) + + @visitor.when(AST.Equals) + def visit(self, node: AST.Equals, scope: Scope): + name = 'ref_eq' + if node.left.static_type in [CoolInt, CoolBool]: name = 'int_eq' + if node.left.static_type == CoolStr: name = 'str_eq' + + return self.binary_op(name, node, ASTR.Equals, scope) + + @visitor.when(AST.New) + def visit(self, node: AST.New, scope: Scope): + new = self.currentFunc.local_push(f'new_{node.item.name}', scope) + return [ + ASTR.Comment(f'Creando instancia de tipo {node.item.name}'), + ASTR.ALLOCATE(new, node.item.name), + ASTR.Comment(f'Assignacion de la insformacion de tipo a la instancia'), + ASTR.Load('_', node.item.name), + ASTR.SetAttr(new, 'type_name', '_'), + ASTR.Arg(new), + ASTR.New(super_value, node.item.name) + ] + + def unary_op(self, node, astr_node, scope: Scope): + result_list = [ASTR.Comment(f'Evaluando la expression de una operacion unaria')] + result_list += self.visit(node.item, scope) + result_list[-1].set_value('_') + result_list += [ASTR.Comment(f'FIN expression de una operacion unaria')] + + return result_list + [astr_node(super_value, '_')] + + @visitor.when(AST.Complement) + def visit(self, node: AST.Complement, scope: Scope): + return self.unary_op(node, ASTR.Complemnet, scope) + + @visitor.when(AST.Neg) + def visit(self, node: AST.Neg, scope: Scope): + return self.unary_op(node, ASTR.Neg, scope) + + @visitor.when(AST.Void) + def visit(self, node: AST.Void, scope: Scope): + op_1 = self.currentFunc.local_push('ref_eq@_a', scope) + null = self.currentFunc.local_push('ref_eq@_b', scope) + unary_list = self.visit(node.item, scope) + unary_list[-1].set_value(op_1) + + return ( + [ASTR.Load(null, "_______null_______"), ASTR.Comment("void check")] + + unary_list + + [ASTR.Equals(super_value, null, op_1)] + ) + + @visitor.when(AST.Id) + def visit(self, node: AST.Id, scope: Scope): + var = scope.find_variable(node.item) + if not var is None: + return [ASTR.Comment(f"Get Local Var {node.item}"),ASTR.Assign(super_value, var.type)] + else: + return [ASTR.Comment(f"Get Self Property {node.item}"),ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] + + @visitor.when(AST.Int) + def visit(self, node: AST.Int, scope: Scope): + return [ASTR.Assign('_', node.item), ASTR.VCall(super_value, '__int__new__', '_')] + + @visitor.when(AST.Bool) + def visit(self, node: AST.Bool, scope: Scope): + if node.item == 'true': value = 1 + else: value = 0 + return [ASTR.Assign('_', value), ASTR.VCall('_', '__int__new__', '_'), ASTR.VCall(super_value, '__bool__new__', '_')] + + @visitor.when(AST.Str) + def visit(self, node: AST.Str, scope: Scope): + name = self.program.add_data('string', node.item) + + return [ + ASTR.Load('_', name), + ASTR.VCall(super_value, '__str__new__', '_') + ] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_cool_to_cil/tools.py b/src/cool_compiler/codegen/v0_cool_to_cil/tools.py new file mode 100644 index 000000000..8a47c339a --- /dev/null +++ b/src/cool_compiler/codegen/v0_cool_to_cil/tools.py @@ -0,0 +1,40 @@ +from ...semantic.v2_semantic_checking import semantic_checking_ast as AST +from .cool_to_cil_ast import super_value + +class BaseCoolToCIL: + def __init__(self) -> None: + self.label_list = {} + + def parent_list(self, node: AST.CoolClass): + parent_list = [] + parent = node + while True: + if parent is None: break + parent_list.append(parent) + parent = parent.parent + + parent_list.reverse() + return parent_list + + + def new_name(self, name, _dict = None): + if _dict is None: _dict = self.label_list + index = 0 + while True: + try: + _ = _dict[f'{name}_{index}'] + index += 1 + except KeyError: + _dict[f'{name}_{index}'] = 1 + return f'{name}_{index}' + + def map_type(self, name): + try: return self.type_dir[name] + except KeyError: + self.type_dir[name] = len(self.type_dir.keys()) + 1 + return self.type_dir[name] + + def try_funsion(self, _list, var): + if not _list[-1].can_fusion: return _list, var + + if _list[-1].x == var: return _list[0:-1], _list[-1].y \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/__init__.py b/src/cool_compiler/codegen/v1_mips_generate/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/__init__.py b/src/cool_compiler/codegen/v1_mips_generate/general_macros/__init__.py new file mode 100644 index 000000000..933a6bce9 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/__init__.py @@ -0,0 +1,14 @@ +_list = ['int', 'bool', 'str'] + +def sys_macro_load(): + result = '' + + for _type in _list: + with open(f'cool_compiler/codegen/v1_mips_generate/general_macros//{_type}.mips') as mips: + text = mips.read() + mips.close() + result += text[text.index('#region'): text.index('#endregion')] + + return result + + diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/__registry_legend b/src/cool_compiler/codegen/v1_mips_generate/general_macros/__registry_legend new file mode 100644 index 000000000..b795517d9 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/__registry_legend @@ -0,0 +1,3 @@ +$s6 -> self +$s5 -> $ra +$s4 -> _ \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips b/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips new file mode 100644 index 000000000..a691dd358 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips @@ -0,0 +1,151 @@ +.data +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, +Bool_parents: .word 1, 7, 0 + +.text +.globl main +main: + +la $a0, Bool_parents +li $a1, 7 +jal __bool__check__type__ +move $a0, $v0 +li $v0, 1 # system call #4 - print string +syscall # execute + +li $v0, 10 # system call #4 - print string +syscall # execute + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int +li $t2, 1 +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** +sw $v0, ($sp) + +lw $a0, ($sp) +jal __bool__new__ +addi $sp, $sp, -4 +sw $v0, ($sp) + +lw $a0, 4($v0) +li $v0, 1 # system call #4 - print string +syscall + +lw $a0, ($sp) +la $a1, true +jal __bool__if_go_to__ + +li $v0, 1 # system call #4 - print string +li $a0, 33333333 +syscall # execute + +true: + +lw $a0, 4($sp) +li $t0, 0 +sw $t0, 4($a0) + +jal __bool__new__ + +lw $a0, 4($v0) +li $v0, 1 # system call #4 - print string +syscall + +lw $a0, 4($sp) +la $a1, false +jal __bool__if_go_to__ + + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int +li $t2, 10000 +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** +sw $v0, ($sp) + +lw $a0, ($sp) +jal __bool__new__ +addi $sp, $sp, -4 +sw $v0, ($sp) + + +false: +li $v0, 10 +syscall + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#endregion +########################################################################################################## diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/int.mips b/src/cool_compiler/codegen/v1_mips_generate/general_macros/int.mips new file mode 100644 index 000000000..2b5a50ef8 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/int.mips @@ -0,0 +1,327 @@ +.data +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, + +.text +.globl main +main: + jal __int__input__ + sw $v0, ($sp) + + move $a0, $v0 + jal __int__print__ # print number + + li $a0, -4 + jal __int__new__ + addi $sp, $sp, -4 + sw $v0, ($sp) + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__sum__ # print number + 4 + + move $a0, $v0 + jal __int__print__ + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__sub__ + + move $a0, $v0 + jal __int__print__ # print -4 - number + + lw $a1, ($sp) # -4 + lw $a0, 4($sp) # number + jal __int__sub__ + + move $a0, $v0 + jal __int__print__ # print number - -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__mul__ + + move $a0, $v0 + jal __int__print__ # print number * -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__div__ + + move $a0, $v0 + jal __int__print__ # print -4 / number + + lw $a1, ($sp) # -4 + lw $a0, 4($sp) # number + jal __int__div__ + + move $a0, $v0 + jal __int__print__ # print number/ -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__le__ + + move $a0, $v0 + jal __int__print__ # print -4 < number + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__leq__ + + move $a0, $v0 + jal __int__print__ # print -4 <= number + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__eq__ + move $s0, $v0 + + move $a0, $v0 + jal __int__print__ # print -4 == number + + move $a0, $s0 + jal __int__neg__ + + move $a0, $v0 + jal __int__print__ # print ! (-4 == numbe) + + lw $a0, 4($sp) # number + jal __int__complement__ + + move $a0, $v0 + jal __int__print__ # print -4 <= number + + li $v0, 10 + syscall + +#region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#endregion +########################################################################################################## diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/int_valor.mips b/src/cool_compiler/codegen/v1_mips_generate/general_macros/int_valor.mips new file mode 100644 index 000000000..8cf2f057d --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/int_valor.mips @@ -0,0 +1,235 @@ +.data +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, + +.text +.globl main +main: + jal __int__input__ + sw $v0, ($sp) + + move $a0, $v0 + jal __int__print__ # print number + + li $a0, -4 + addi $sp, $sp, -4 + sw $a0, ($sp) + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__sum__ # print number + 4 + + move $a0, $v0 + jal __int__print__ + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__sub__ + + move $a0, $v0 + jal __int__print__ # print -4 - number + + lw $a1, ($sp) # -4 + lw $a0, 4($sp) # number + jal __int__sub__ + + move $a0, $v0 + jal __int__print__ # print number - -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__mul__ + + move $a0, $v0 + jal __int__print__ # print number * -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__div__ + + move $a0, $v0 + jal __int__print__ # print -4 / number + + lw $a1, ($sp) # -4 + lw $a0, 4($sp) # number + jal __int__div__ + + move $a0, $v0 + jal __int__print__ # print number/ -4 + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__le__ + + move $a0, $v0 + jal __int__print__ # print -4 < number + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__leq__ + + move $a0, $v0 + jal __int__print__ # print -4 <= number + + lw $a0, ($sp) # -4 + lw $a1, 4($sp) # number + jal __int__eq__ + move $s0, $v0 + + move $a0, $v0 + jal __int__print__ # print -4 == number + + move $a0, $s0 + jal __int__neg__ + + move $a0, $v0 + jal __int__print__ # print ! (-4 == numbe) + + lw $a0, 4($sp) # number + jal __int__complement__ + + move $a0, $v0 + jal __int__print__ # print -4 <= number + + li $v0, 10 + syscall + +#region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +###################################################################################################### +__int__print__: +# En $s6 **self** +# En $a0 el valor del **Int** a pintar +# Return $v0 **self** + +li $v0, 1 +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 el valor del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el valor del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 valor del **Int** a sumando A +# En $a1 valor del **Int** a sumando B +# Return $v0 **value** A+B + +add $v0, $a0, $a1 #$a0 = A + B +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el valor del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 valor del **Int** a sumando A +# En $a1 valor del **Int** a sumando B +# Return $v0 **value** A-B +sub $v0, $a0, $a1 #$a0 = A - B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 el valor del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 valor del **Int** a sumando A +# En $a1 valor del **Int** a sumando B +# Return $v0 **value** A*B + +mul $v0, $a0, $a1 #$a0 = A * B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el valor del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 valor del **Int** a sumando A +# En $a1 valor del **Int** a sumando B +# Return $v0 **value** A/B + +div $v0, $a0, $a1 #$a0 = A/B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el valor del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 valor del **Int** a comparador A +# En $a1 valor del **Int** a comparador B +# Return $v0 **value** A < B + + +slt $v0, $a0, $a1 #$a0 = A < B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el **Valor** de la comparacion + +########################################################################################################## +__int__leq__: +# En $s6 **self** +# En $a0 valor del **Int** a comparador A +# En $a1 valor del **Int** a comparador B +# Return $v0 **value** A <= B + +sle $v0, $a0, $a1 #$a0 = A <= B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el **Valor** de la comparacion + +########################################################################################################## +__int__eq__: +# En $s6 **self** +# En $a0 valor del **Int** a comparador A +# En $a1 valor del **Int** a comparador B +# Return $v0 **value** A == B + +seq $v0, $a0, $a1 #$a0 = A == B + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el **Valor** de la comparacion + +########################################################################################################## +__int__complement__: +# En $s6 **self** +# En $a0 el valor del **Int** a operador A +# Return $v0 valor de ~A + + +li $t1, 4294967295 # guarda 2^31 + 1 +xor $v0, $t1, $a0 +add $v0, $v0, 1 + + +jr $ra #Esta funcion no tiene saltos internos y en $v0 esta el valor de ~A + +########################################################################################################## +__int__neg__: +# En $s6 **self** +# En $a0 el valor del **Int** a operador A +# Return $v0 **value** !A + +addi $a0, $a0, -1 #$a0 = A - 1 => if A == 0 then $a0 = -1 else $a0 = 0 +mul $v0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + + +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#endregion +########################################################################################################## diff --git a/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips b/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips new file mode 100644 index 000000000..93c3d932a --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips @@ -0,0 +1,340 @@ +.data +String_Name: .asciiz "String" +String: .word String_Name, 2, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, +T: .asciiz "" + + +.text +.globl main +main: + +jal __str__input__ + +move $s0, $v0 +move $a0, $v0 +jal __str__print__ + +jal __str__input__ +move $s1, $v0 +move $s6, $v0 + +jal __str__length__ + +lw $a0, 4($v0) +li $v0, 1 # system call #4 - print string +syscall + +move $s6, $s0 +move $a0, $s1 +jal __str__concat__ + +move $s6, $v0 +move $a0, $v0 +jal __str__print__ + +jal __str__length__ + +lw $a0, 4($v0) +li $v0, 1 # system call #4 - print string +syscall + +la $a0, T +jal __str__new__ + +move $a0, $v0 +move $a1, $s1 +jal __str__cmp__ + +lw $a0, 4($v0) +li $v0, 1 # system call #4 - print string +syscall # execute + +li $v0, 10 # system call #4 - print string +syscall # execute + + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + +#endregion +########################################################################################################## +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + + +######################################################################################################### \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mips_generate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mips_generate_ast.py new file mode 100644 index 000000000..a12e12a69 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/mips_generate_ast.py @@ -0,0 +1,164 @@ +from .general_macros import sys_macro_load + +class Program: + def __init__(self) -> None: + self.data = {} + self.func = {} + self.sys = sys_macro_load() + + + def __str__(self) -> str: + result = ".data\n" + + for key in self.data.keys(): + result += str(self.data[key]) + '\n' + + result += '\n.text\n.globl main\n' + result += str(self.func['main']) + '\n' + + for key in self.func.keys(): + if key == 'main': continue + result += str(self.func[key]) + '\n' + + result += '##########################################################################' + return result + str(self.sys) + +class Data: + def __init__(self, name, value) -> None: + self.name = name + self.value = value + + def __str__(self) -> str: + if type(self.value) == type(str()) : + replace_ = self.value.replace('\n', '\\n') + return f"{self.name}: .asciiz \"{replace_}\"" + + if type(self.value) == type([]): + result = f'{self.name}: .word ' + for item in self.value: + result += str(item) + ', ' + return result + + return f'{self.name}: .word \"{str(self.value)}\"' + +class Func: + def __init__(self, name, comment = "") -> None: + self.name = name + self.cmd = [] + self.comment = comment + + def __str__(self) -> str: + result = f'{self.name}: #{self.comment}\n' + for cmd in self.cmd: + try: + if cmd.is_comment: + result = result[0:-1] + ' ' * 10 + str(cmd) + '\n' + except AttributeError: + result += str(cmd) + '\n' + return result + +class LiteralMips: + def __init__(self, text) -> None: + self.text = text + + def __str__(self) -> str: + return self.text + +class Header_Comment: + def __init__(self, msg) -> None: + self.msg = msg + + def __str__(self) -> str: + return f'#{self.msg}' + +class Label: + def __init__(self,label) -> None: + self.label = label + + def __str__(self) -> str: + return f'{self.label}:' + +class SysCall : + def __init__(self) -> None: + pass + + def __str__(self) -> str: + return f'{"syscall"}' + +################################################################################# +class UnaryOp: + def __init__(self, cmd, op, comment = '') -> None: + self.op = op + self.cmd = cmd + self.comment = comment + + def __str__(self) -> str: + return f'{self.cmd} {self.op} #{self.comment}' + +class Jal(UnaryOp): + def __init__(self,dest, comment = '') -> None: + super().__init__('jal',dest, comment) + +class Jr(UnaryOp): + def __init__(self,dest, comment = '') -> None: + super().__init__('jr',dest, comment) + +class Jump(UnaryOp): + def __init__(self,dest, comment = '') -> None: + super().__init__('j',dest, comment) + +################################################################################# +class BinaryOp: + def __init__(self, cmd ,registry, memory_dir, comment = '') -> None: + self.registry = registry + self.memory_dir = memory_dir + self.cmd = cmd + self.comment = comment + + + def __str__(self) -> str: + return f'{self.cmd} {self.registry}, {self.memory_dir} #{self.comment}' + +class LW(BinaryOp): + def __init__(self, registry, memory_dir, comment = '') -> None: + super().__init__('lw', registry, memory_dir, comment) + +class LI(BinaryOp): + def __init__(self, registry, memory_dir, comment = '') -> None: + super().__init__('li', registry, memory_dir, comment) + +class LA(BinaryOp): + def __init__(self, registry, memory_dir, comment = '') -> None: + super().__init__('la', registry, memory_dir, comment) + +class Move(BinaryOp): + def __init__(self, registry, memory_dir, comment = '') -> None: + super().__init__('move', registry, memory_dir, comment) + +class SW(BinaryOp): + def __init__(self, registry, memory_dir, comment = '') -> None: + super().__init__('sw', registry, memory_dir, comment) + +################################################################################### +class TernaryOp: + def __init__(self, cmd, dest, op1, op2, comment = '') -> None: + self.op1 = op1 + self.op2 = op2 + self.dest = dest + self.cmd = cmd + self.comment = comment + + def __str__(self) -> str: + return f'{self.cmd} {self.dest}, {self.op1}, {self.op2} #{self.comment}' + +class Seq(TernaryOp): + def __init__(self ,r_dest, r_src_1, r_src_2, comment = '') -> None: + super().__init__( 'seq' ,r_dest, r_src_1, r_src_2, comment) + +class Beq(TernaryOp): + def __init__(self ,r_dest, r_src_1, r_src_2, comment = '') -> None: + super().__init__( 'beq' ,r_dest, r_src_1, r_src_2, comment) + +class AddI(TernaryOp): + def __init__(self,dest,op1,op2, comment = '') -> None: + super().__init__('addi',dest,op1,op2, comment) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py b/src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py new file mode 100644 index 000000000..daa104782 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py @@ -0,0 +1,291 @@ +from ..v0_cool_to_cil import cool_to_cil_ast as AST +from . import mips_generate_ast as ASTR +from ...cmp import visitor +from .stack import Stack +from .native_funcion import CoolNativeFunctions + +class MipsGenerate: + def __init__(self, _) -> None: + self.func_list = ['main'] + self.native_func = CoolNativeFunctions() + + @visitor.on('node') + def visit(node): + pass + + @visitor.when(AST.Program) + def visit(self, node: AST.Program): + self.cil_data = node.data + self.cil_type = node.types + self.cil_func = node.functions + + self.new_program = ASTR.Program() + + for data_label in self.cil_data.keys(): + self.new_program.data[data_label] = ASTR.Data(data_label, self.cil_data[data_label].value) + + for func in self.func_list: + try: self.new_program.func[func] = self.native_func.call(func) + except AttributeError: self.visit(self.cil_func[func]) + + for func in list(self.cil_func.keys()) + self.native_func.method_list: + if func in self.func_list: continue + self.new_program.func[func] = ASTR.Func(func, + "Esta funcion no se invoca en la ejecucion del programa") + + return self.new_program + + @visitor.when(AST.Function) + def visit(self, node: AST.Function): + new_func = ASTR.Func(node.name) + self.stack = Stack(node) + + for param in node.param: + new_func.cmd += self.stack.def_param(param) + + for _local in node.local: + new_func.cmd += self.stack.def_local(_local) + + new_func.cmd += self.stack.def_local('$ra') + new_func.cmd += self.stack.write_local('$ra','$ra', f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {node.name}") + + for expr in node.expr: + new_func.cmd += self.visit(expr) + + self.new_program.func[new_func.name] = new_func + + @visitor.when(AST.ALLOCATE) + def visit(self, node: AST.ALLOCATE): + memory_dir = node.x + _type = node.y + + attr_list = self.cil_type[_type].attributes + _len = len(attr_list) * 4 + + result = [ASTR.Header_Comment(f"Allocate a una class {_type}")] + for i, attr in enumerate(attr_list): + result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {i * 4}')) + + return result + [ + ASTR.LI('$a0', _len), + ASTR.LI('$v0', 9), + ASTR.SysCall() + ] + self.stack.write_local('$v0', memory_dir, f'Guardando en la variable local {memory_dir} puntero de la instancia de la clase {_type}') + + @visitor.when(AST.GetAttr) + def visit(self, node: AST.GetAttr): + memory_dest = node.x + memory_dir_instance = node.y + attr_name = node.z.split('@') + _type = attr_name[0] + attr = attr_name[1] + + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + + result = self.stack.read_local('$t0', memory_dir_instance, f'Instancia de la clase {_type}') + result += [ASTR.LW('$t1', f'{attr_plus}($t0)', f'Lee la propiedad {attr}')] + result += self.stack.write_local('$t1', memory_dest, f'Guarda el valor de la propiedad {attr} en la variable local {memory_dest}') + return result + + @visitor.when(AST.SetAttr) + def visit(self, node: AST.SetAttr): + if node.y == 'type_name': + attr_plus = 0 + attr = 'type_name' + _type = "" + else: + attr_name = node.y.split('@') + _type = attr_name[0] + attr = attr_name[1] + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + + memory_dir_instance = node.x + memory_dir_value = node.z + + result = self.stack.read_local('$t0', memory_dir_instance, f'Instancia de la clase {_type}') + result += self.stack.read_local('$t1', memory_dir_value, f'Guarda el valor que se le asignara a la propieded {attr}') + result += [ASTR.SW('$t1', f'{attr_plus}($t0)', f'Setea la propiedad {attr} con el valor de {memory_dir_value}')] + + return result + + @visitor.when(AST.Arg) + def visit(self, node: AST.Arg): + return self.stack.push(node.x) + + def call(self, func, memory_dest): + self.stack.clean() + + return [ASTR.Jal(func)] + self.stack.write_local('$v0', memory_dest, f'Asigna el resultado de la funcion') + + @visitor.when(AST.SimpleCall) + def visit(self, node: AST.SimpleCall): + if not node.x in self.func_list: self.func_list.append(node.x) + return self.call(node.x, 'self')[0: -1] + + @visitor.when(AST.VCall) + def visit(self, node: AST.VCall): + memory_dest = node.x + _type = node.y + try: + func = self.cil_type[_type].methods[node.z] + if not func in self.func_list: self.func_list.append(func) + + return self.call(func, memory_dest) + except KeyError: + if '__new__' in node.y: return self.call_magic_method(node.y, node.z, node.x) + raise KeyError(node.z) + + @visitor.when(AST.New) + def visit(self, node: AST.New): + func = f'new_ctr_{node.y}' + if not func in self.func_list: self.func_list.append(func) + return self.call(f'new_ctr_{node.y}', node.x) + + @visitor.when(AST.Call) + def visit(self, node: AST.Call): + memory_dest = node.x + _type, func_name = node.z.split('@') + + self.func_list += [func for func in self.cil_func.keys() + if func_name in func and not func in self.func_list] + + self.func_list += [func for func in self.native_func.method_list + if func_name in func and not func in self.func_list] + + func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 12 + _result = self.stack.read_local('$t0', node.y) + _result.append(ASTR.LW('$t1', '0($t0)', f"Leyendo el tipo dinamico de la instancia que hereda de {_type}")) + _result.append(ASTR.LW('$t3', f'{func_address}($t1)', f"Buscando el metodo dinamico para la funcion {func_name}")) + + return _result + self.call('$t3', memory_dest) + + @visitor.when(AST.Return) + def visit(self, node: AST.Return): + if node.x == 0: + return [ASTR.LI('$v0', 10), ASTR.SysCall()] + + memory_dest = node.x + _result = self.stack.read_local('$v0', memory_dest, f'Return {memory_dest}') + _result += self.stack.read_local('$ra', '$ra', 'Lee $ra de la pila para retornar a la funcion anterior') + + return _result + self.stack.close() + [ASTR.Jr('$ra')] + + @visitor.when(AST.Load) + def visit(self, node: AST.Load): + memory_dest = node.x + data_label = node.y + + return [ASTR.LA('$t0', data_label)] + self.stack.write_local('$t0', memory_dest) + + @visitor.when(AST.Label) + def visit(self, node: AST.Label): + return [ASTR.Label(node.x)] + + @visitor.when(AST.GoTo) + def visit(self,node:AST.GoTo): + label = node.x + return [ASTR.Jump (label)] + + @visitor.when(AST.Assign) + def visit(self,node:AST.Assign): + if node.x == node.y: return [] + if type(node.y) == type(int()): return [ASTR.LI('$s4', node.y)] + memory_dest = node.x + dir_value = node.y + _result = self.stack.read_local('$t0', dir_value) + return _result + self.stack.write_local('$t0', memory_dest) + + def call_magic_method(self, func, *memory_dir): + result = self.stack.read_local('$s6', 'self', f'Guarda self') + + for i, param in enumerate(memory_dir[0: -1]): + result += self.stack.read_local(f'$a{i}', param, f"Guarda el parametro {i} -> {param}") + + result.append(ASTR.Jal(func)) + return result + self.stack.write_local('$v0', memory_dir[-1]) + + @visitor.when(AST.Sum) + def visit(self,node:AST.Sum): + return self.call_magic_method('__int__sum__', node.y, node.z, node.x) + + @visitor.when(AST.Rest) + def visit(self,node:AST.Rest): + return self.call_magic_method('__int__sub__', node.y, node.z, node.x) + + @visitor.when(AST.Mult) + def visit(self,node:AST.Mult): + return self.call_magic_method('__int__mul__', node.y, node.z, node.x) + + @visitor.when(AST.Div) + def visit(self,node:AST.Div): + return self.call_magic_method('__int__div__', node.y, node.z, node.x) + + @visitor.when(AST.Less) + def visit(self,node:AST.Less): + cmp = self.call_magic_method('__int__le__', node.y, node.z, node.x) + int_to_bool = self.call_magic_method('__bool__new__', node.x) + return cmp + [ASTR.Move('$a0', '$v0')] + int_to_bool + + @visitor.when(AST.LessOrEqual) + def visit(self,node:AST.LessOrEqual): + cmp = self.call_magic_method('__int__leq__', node.y, node.z, node.x) + int_to_bool = self.call_magic_method('__bool__new__', node.x) + return cmp + [ASTR.Move('$a0', '$v0')] + int_to_bool + + @visitor.when(AST.Complemnet) + def visit(self,node:AST.Complemnet): + return self.call_magic_method('__int__complement__', node.y, node.x) + + @visitor.when(AST.Neg) + def visit(self,node:AST.Neg): + cmp = self.call_magic_method('__int__neg__', node.y, node.x) + int_to_bool = self.call_magic_method('__bool__new__', node.x) + return cmp + [ASTR.Move('$a0', '$v0')] + int_to_bool + + @visitor.when(AST.IfGoTo) + def visit(self,node:AST.IfGoTo): + result = [ASTR.Header_Comment('Check Condition And Try Jump')] + result += self.stack.read_local('$t0', node.x, f"Guarda el parametro 0 -> {node.x}") + result += [ASTR.LW(f'$t1', "4($t0)", f"Lee la propiedad **value** del bool")] + result += [ASTR.LI(f'$t0', 1, f"Carga un 1 para comparar")] + result += [ASTR.Beq('$t0', '$t1', node.y)] + return result + + @visitor.when(AST.Equals) + def visit(self,node:AST.Equals): + if 'int_eq' in node.y: + cmp = self.call_magic_method('__int__eq__', node.y, node.z, node.x) + int_to_bool = self.call_magic_method('__bool__new__', node.x) + return cmp + [ASTR.Move('$a0', '$v0')] + int_to_bool + elif 'str_eq' in node.y: + cmp = self.call_magic_method('__str__cmp__', node.y, node.z, node.x) + int_to_bool = self.call_magic_method('__bool__new__', node.x) + return cmp + [ASTR.Move('$a0', '$v0')] + int_to_bool + elif 'ref_eq' in node.y: + _result = self.stack.read_local('$t0', node.y) + _result += self.stack.read_local('$t1', node.z) + _result += [ASTR.Seq('$a0','$t1','$t0')] + return (_result + + self.call_magic_method('__int__new__', node.x) + + [ASTR.Move('$a0', '$v0')] + + self.call_magic_method('__bool__new__', node.x)) + + assert False, "La comparacion no es correcta" + + @visitor.when(AST.CheckType) + def visit(self, node: AST.CheckType): + result = self.call_magic_method('__bool__check__type__', node.y, node.z, node.x) + result += [ASTR.Move('$a0', '$v0')] + self.call_magic_method('__int__new__', node.x) + result += [ASTR.Move('$a0', '$v0')] + self.call_magic_method('__bool__new__', node.x) + return result + + @visitor.when(AST.TypeOf) + def visit(self, node: AST.TypeOf): + result = self.stack.read_local('$t0', node.y) + result += [ASTR.LW('$t1', '($t0)', 'Lee la propiedad **type** de la instancia')] + result += [ASTR.LW('$t0', '8($t1)', 'Lee la propiedad **parents** de la propiedad **type**')] + return result + self.stack.write_local('$t0', node.x) + + @visitor.when(AST.Comment) + def visit(self, node: AST.Comment): + return [ASTR.Header_Comment(node.x)] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/native_funcion.py b/src/cool_compiler/codegen/v1_mips_generate/native_funcion.py new file mode 100644 index 000000000..5244f1e4f --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/native_funcion.py @@ -0,0 +1,165 @@ +import inspect +from . import mips_generate_ast as ASTR +from ..v0_cool_to_cil import cool_to_cil_ast as AST +from .stack import Stack + + +class CoolNativeFunctions: + def __init__(self) -> None: + self.method_list = [ + "IO_out_string", + "IO_in_int", + "IO_in_string", + "IO_out_int", + "String_length", + "String_concat", + "String_substr", + "Object_copy", + "Object_type_name", + "Object_abort"] + + def call(self, func): + method_to_call = getattr(self, func.lower()) + self.node = AST.Function(func) + return method_to_call() + + # @property + # def method_list(self): + # return [method for method in inspect.getmembers(self, predicate=inspect.ismethod)] + + def call_magic_method(self, func,*memory_dir): + new_func = ASTR.Func(self.node.name) + self.node.param = memory_dir + self.stack = Stack(self.node) + result = [] + + for param in ['self'] + list(self.node.param): + result += self.stack.def_param(param) + + result += self.stack.def_local('$ra') + result += self.stack.write_local('$ra','$ra', f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {self.node.name}") + + result += self.stack.read_local('$s6', 'self', f'Guarda self') + + for i, param in enumerate(memory_dir): + result += self.stack.read_local(f'$a{i}', param, f"Guarda el parametro {i} -> {param}") + + result.append(ASTR.Jal(func)) + result += self.stack.read_local('$ra', '$ra') + result += self.stack.close() + result.append(ASTR.Jr('$ra')) + new_func.cmd = result + return new_func + + def io_out_string(self): + return self.call_magic_method('__str__print__','string') + + def io_out_int(self): + return self.call_magic_method('__int__print__','number') + + def io_in_string(self): + return self.call_magic_method('__str__input__') + + def io_in_int(self): + return self.call_magic_method('__int__input__') + + + def string_length(self): + return self.call_magic_method('__str__length__') + + def string_concat(self): + return self.call_magic_method('__str__concat__', 'string') + + def string_substr(self): + return self.call_magic_method('__str__substr__', 'index', 'count') + + def object_abort(self): + new_func = ASTR.Func(self.node.name) + self.stack = Stack(self.node) + result = self.stack.def_param('self') + result += self.stack.def_local('$ra') + result += self.stack.write_local('$ra','$ra', f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {self.node.name}") + result += self.stack.read_local('$s6', 'self', f'Guarda self') + + result.append(ASTR.LA('$a0', '_______error______')) + result.append(ASTR.Jal('__str__new__')) + result.append(ASTR.Move('$a0', '$v0')) + result.append(ASTR.Jal('__str__print__', 'Print "Abort called from class "')) + + result.append(ASTR.LW('$t0', '($s6)', 'Read type property of self')) + result.append(ASTR.LW('$a0', '($t0)', 'Read type_name of self type')) + result.append(ASTR.Jal('__str__new__')) + result.append(ASTR.Move('$a0', '$v0')) + result.append(ASTR.Jal('__str__print__', 'Type class"')) + + result.append(ASTR.LA('$a0', '_______endline_______')) + result.append(ASTR.Jal('__str__new__')) + result.append(ASTR.Move('$a0', '$v0')) + result.append(ASTR.Jal('__str__print__', 'Print "endline"')) + + new_func.cmd = result + [ASTR.LI('$v0', 10), ASTR.SysCall()] + return new_func + + def object_type_name(self): + new_func = ASTR.Func(self.node.name) + self.stack = Stack(self.node) + result = self.stack.def_param('self') + result += self.stack.def_local('$ra') + result += self.stack.write_local('$ra','$ra', f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {self.node.name}") + result += self.stack.read_local('$s6', 'self', f'Guarda self') + + result.append(ASTR.LW('$t0', '($s6)', 'Read type property of self')) + result.append(ASTR.LW('$a0', '($t0)', 'Read type_name of self type')) + result.append(ASTR.Jal('__str__new__')) + + result += self.stack.read_local('$ra', '$ra') + result += self.stack.close() + result.append(ASTR.Jr('$ra')) + new_func.cmd = result + return new_func + + + def object_clone(self): + new_func = ASTR.Func(self.node.name) + self.stack = Stack(self.node) + result = self.stack.def_param('self') + result += self.stack.def_local('$ra') + result += self.stack.write_local('$ra','$ra', f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {self.node.name}") + result += self.stack.read_local('$s6', 'self', f'Guarda self') + + result.append(ASTR.LiteralMips(""" + lw $t0, ($s6) #Read type property of self + lw $t1, 4($t0) #Read type_account of self types + mul $t1, $t1, 4 + + move $a0, $t1 #tamaño que ocupa en el heap + li $v0, 9 + syscall #En $v0 la nueva instancia + + move $t0, $s6 #Crear puntero a self + move $t2, $v0 #Crear puntero al clone + li $t3, 0 #Crear contador de propiedades + + __object__loop_clone__: + lw $t5, ($t0) #Lee una propiedad de self + sw $t5, ($t2) #Escribe la propiedad en el clone + addi $t3, $t3, 4 #Aumenta el contador de props + beq $t3, $t1, __end__clone__ + addi $t0, $t0, 4 #Mueve el puntero de self + addi $t3, $t3, 4 #Mueve el puntero del clone + j __object__loop_clone__ + + __end__clone__: + """)) + + + result += self.stack.read_local('$ra', '$ra') + result += self.stack.close() + result.append(ASTR.Jr('$ra')) + new_func.cmd = result + return new_func + + + + + diff --git a/src/cool_compiler/codegen/v1_mips_generate/stack.py b/src/cool_compiler/codegen/v1_mips_generate/stack.py new file mode 100644 index 000000000..e97298fa5 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/stack.py @@ -0,0 +1,65 @@ +from cool_compiler.cmp.visitor import result +from . import mips_generate_ast as ASTR + +class Stack: + def __init__(self, node) -> None: + self.name = node.name + self.init_size = len(node.param) + len(node.local) + 1 + self.list = [] + self.local_push = 0 + + def push(self, name): + self.local_push += 1 + + if name == '_': + _result = [ASTR.Move('$t0', '$s4', f'Lee el valor de la operacion anterior')] + elif type(name) == type(int()): + _result = [ASTR.LI('$t0', name, f'Guarda en valor entero')] + else: + _result = [ASTR.LW('$t0', f'{self.index(name)}($sp)', f'Lee el valor de la var {name}')] + + self.list.append(name) + return _result + [ + ASTR.AddI('$sp', '$sp', -4), + ASTR.SW('$t0', '0($sp)', f'Push a la pila con {name}')] + + @property + def initial_index(self): + return (self.init_size - len(self.list)) * 4 + + def index(self, name): + return (len(self.list) - self.list.index(name) - 1) * 4 + + def clean(self): + self.list = self.list[0: len(self.list) - self.local_push] + assert self.list[-1] == '$ra', "El ultimo de la pila no es $ra" + self.local_push = 0 + + def close(self): + if not any(self.list): return [] + result = len(self.list) * 4 + self.local_push + self.list = [] + return [ASTR.AddI('$sp', '$sp', result)] + + def def_param(self, name): + self.list.append(name) + return [ASTR.Header_Comment(f'Parametro {name} en stackpoiner + {self.initial_index}')] + + def def_local(self, name): + self.list.append(name) + return [ASTR.AddI('$sp', '$sp', -4, f'Push local var {name} stackpointer {self.initial_index}')] + + def write_local(self, registry, name, commnet = ''): + if name == '_': + return [ASTR.Move(f'$s4', registry, commnet)] + # if name == 'self': + # return [ASTR.Move(f'$s6', registry, commnet)] + return [ASTR.SW(registry, f'{self.index(name)}($sp)', commnet)] + + def read_local(self, registry, name, commnet = ''): + if name == '_': + return [ASTR.Move(registry, f'$s4', commnet)] + # if name == 'self': + # return [ASTR.Move(registry, f'$s6', commnet)] + return [ASTR.LW(registry, f'{self.index(name)}($sp)', commnet)] \ No newline at end of file diff --git a/src/cool_compiler/error/__init__.py b/src/cool_compiler/error/__init__.py new file mode 100755 index 000000000..e70df5f3a --- /dev/null +++ b/src/cool_compiler/error/__init__.py @@ -0,0 +1 @@ +from .error import CoolError \ No newline at end of file diff --git a/src/cool_compiler/error/error.py b/src/cool_compiler/error/error.py new file mode 100755 index 000000000..4ad9b7749 --- /dev/null +++ b/src/cool_compiler/error/error.py @@ -0,0 +1,53 @@ +from cool_compiler.types.build_in_types import self + + +class CoolError: + def __init__(self, code : str) -> None: + self._list = [] + self.code = code + self.pos = None + self.text = None + + def any(self): + if any(self._list): + for msg in self._list: + print(msg) + return True + return False + + def __call__(self, lineno, index): + self.pos = (lineno, self.find_column(index)) + return self + + def find_column(self, index): + last_cr = self.code.rfind('\n', 0, index) + if last_cr < 0: + last_cr = 0 + column = (index - last_cr) + return column if column != 0 else 1 + + def __add(self, etype, text): + self._list.append(f'{self.pos} - {etype}: {text}') + + def get_handler(self, lineno, index) -> self: + l = lineno + 0 + i = index + 0 + return lambda : self.__call__(l,i) + + def add_lexical(self, text): + self.__add("LexicographicError", text) + + def add_syntactic(self, text): + self.__add("SyntacticError", text) + + def add_name_error(self, text): + self.__add("NameError", text) + + def add_type_error(self, basee, ttype = ''): + self.__add("TypeError", f'{basee} {ttype}') + + def add_attribute_error(self, ttype, attr): + self.__add("AttributeError", f'{attr} in {ttype} type') + + def add_semantic_error(self, text): + self.__add("SemanticError", text) \ No newline at end of file diff --git a/src/cool_compiler/lexer/.ipynb_checkpoints/cool_lexer-checkpoint.py b/src/cool_compiler/lexer/.ipynb_checkpoints/cool_lexer-checkpoint.py new file mode 100755 index 000000000..034d36093 --- /dev/null +++ b/src/cool_compiler/lexer/.ipynb_checkpoints/cool_lexer-checkpoint.py @@ -0,0 +1,105 @@ +from sly import Lexer +from sly.lex import LexError +from .comment_lexer import CoolComment +from .string_lexer import CoolString +import re + +class CoolLexer(Lexer): + def __init__(self, error=None) -> None: + super().__init__() + self.cool_error = error + + tokens = { + CLASS, INHERITS, + IF, THEN, ELSE, FI, + LET, IN, + WHILE, LOOP, POOL, + CASE, OF, ESAC, + ISVOID, NEW, NOT, + TRUE, FALSE, + ID, NUMBER, TYPE, + ARROW, LOGICAR, LESS_OR, + STRING + } + + literals = { + '{','}', '@', '.', ',', ';', + '=', '<', '~', '+', '-', + '*', '/', '(', ')', ':', + } + + ignore = r' ' + ignore_tab = r'\t' + ignore_comment = r'\(\*' + ignore_newline = r'\n' + ignore_line = r'--.*\n' + + keyword = [ "class", 'inherits', + 'if', 'then', 'else', 'fi', + 'let', 'in', + 'while', 'loop', 'pool', + 'case', 'of' , 'esac', + 'isvoid', 'new', 'not', + 'true','false' + ] + + ID = r'[a-zA-Z][a-zA-Z0-9_]*' + NUMBER = r'\d+' + ARROW = r'<-' + LOGICAR = r'=>' + LESS_OR = r'<=' + STRING = r'\"' + + def ID(self, token): + if token.value.lower() in self.keyword: + token.type = token.value.upper() + elif not token.value[0].islower(): + token.type = "TYPE" + + return token + + def ignore_line(self, token): + self.lineno += 1 + + def ignore_newline(self,token): + self.lineno += 1 + + def ignore_comment(self,token): + lexer = CoolComment(self) + _bool, pos, line = lexer.comment_analizer() + self.lineno += line + + if _bool: + self.index = len(self.text) + self.cool_error(self.lineno, self.index) + self.cool_error.add_lexical("EOF in comment") + + else: self.index += pos + + def STRING(self, token): + lexer = CoolString(self) + result, pos, line = lexer.string_analizer() + self.lineno += line + token.value = result + + if pos == 0: + self.index = len(self.text) + self.cool_error(self.lineno, self.index) + self.cool_error.add_lexical("EOF in string constant") + + else : + self.index += pos + + return token + + def NUMBER(self, token): + token.value = int(token.value) + return token + + def error(self, token): + self.cool_error(token.lineno, token.index) + self.cool_error.add_lexical(f'Unknown character {token.value[0]}') + self.index += 1 + + + diff --git a/src/cool_compiler/lexer/__dependency.py b/src/cool_compiler/lexer/__dependency.py new file mode 100755 index 000000000..6a747410d --- /dev/null +++ b/src/cool_compiler/lexer/__dependency.py @@ -0,0 +1,2 @@ +from ..common_name import tem as Tokens +from ..common_name import literls as Literls diff --git a/src/cool_compiler/lexer/__init__.py b/src/cool_compiler/lexer/__init__.py new file mode 100755 index 000000000..03209d807 --- /dev/null +++ b/src/cool_compiler/lexer/__init__.py @@ -0,0 +1 @@ +from .cool_lexer import CoolLexer \ No newline at end of file diff --git a/src/cool_compiler/lexer/__main__.py b/src/cool_compiler/lexer/__main__.py new file mode 100755 index 000000000..534790c46 --- /dev/null +++ b/src/cool_compiler/lexer/__main__.py @@ -0,0 +1,7 @@ +from .cool_lexer import CoolLexer + + +data = '''a(*(*(**)*)*)a*)e*)eeeee(*a*)''' +lexer = CoolLexer() +for tok in lexer.tokenize(data): + print(tok) \ No newline at end of file diff --git a/src/cool_compiler/lexer/comment_lexer.py b/src/cool_compiler/lexer/comment_lexer.py new file mode 100755 index 000000000..b69e293c2 --- /dev/null +++ b/src/cool_compiler/lexer/comment_lexer.py @@ -0,0 +1,40 @@ +from sly import Lexer, lex + +class CoolComment(Lexer): + tokens = { TEXT } + + ignore_open = r'\(\*' + ignore_close = r'\*\)' + ignore_newline = r'\n' + TEXT = r'.' + + def __init__(self, lexer ): + self.lexer = lexer + self.pos = 0 + self.count_new_line = 0 + self.s = 0 + self.len = 0 + + def ignore_open(self, token): + self.s += 1 + + def ignore_close(self, token): + self.s -= 1 + if not self.s > 0: + self.index = self.len + self.pos = token.index + + def ignore_newline(self, token): + self.count_new_line += 1 + + def comment_analizer(self): + text = self.lexer.text[self.lexer.index-2:] + self.len = len(text) + for last in self.tokenize(text): + pass + + return self.s > 0, self.pos, self.count_new_line + + + + diff --git a/src/cool_compiler/lexer/cool_lexer.py b/src/cool_compiler/lexer/cool_lexer.py new file mode 100755 index 000000000..ca5aeccb7 --- /dev/null +++ b/src/cool_compiler/lexer/cool_lexer.py @@ -0,0 +1,104 @@ +from sly import Lexer +from .comment_lexer import CoolComment +from .string_lexer import CoolString +import re + +class CoolLexer(Lexer): + def __init__(self, error=None) -> None: + super().__init__() + self.cool_error = error + + tokens = { + CLASS, INHERITS, + IF, THEN, ELSE, FI, + LET, IN, + WHILE, LOOP, POOL, + CASE, OF, ESAC, + ISVOID, NEW, NOT, + TRUE, FALSE, + ID, NUMBER, TYPE, + ARROW, LOGICAR, LESS_OR, + STRING + } + + literals = { + '{','}', '@', '.', ',', ';', + '=', '<', '~', '+', '-', + '*', '/', '(', ')', ':', + } + + ignore = r' ' + ignore_tab = r'\t' + ignore_comment = r'\(\*' + ignore_newline = r'\n' + ignore_line = r'--.*\n' + + keyword = [ "class", 'inherits', + 'if', 'then', 'else', 'fi', + 'let', 'in', + 'while', 'loop', 'pool', + 'case', 'of' , 'esac', + 'isvoid', 'new', 'not', + 'true','false' + ] + + ID = r'[a-zA-Z][a-zA-Z0-9_]*' + NUMBER = r'\d+' + ARROW = r'<-' + LOGICAR = r'=>' + LESS_OR = r'<=' + STRING = r'\"' + + def ID(self, token): + if token.value.lower() in self.keyword: + token.type = token.value.upper() + elif not token.value[0].islower(): + token.type = "TYPE" + + return token + + def ignore_line(self, token): + self.lineno += 1 + + def ignore_newline(self,token): + self.lineno += 1 + + def ignore_comment(self,token): + lexer = CoolComment(self) + _bool, pos, line = lexer.comment_analizer() + self.lineno += line + + if _bool: + self.index = len(self.text) + self.cool_error(self.lineno, self.index) + self.cool_error.add_lexical("EOF in comment") + + else: self.index += pos + + def STRING(self, token): + lexer = CoolString(self) + result, pos, line = lexer.string_analizer() + self.lineno += line + token.value = result + + if pos == 0: + self.index = len(self.text) + self.cool_error(self.lineno, self.index) + self.cool_error.add_lexical("EOF in string constant") + + else : + self.index += pos + + return token + + def NUMBER(self, token): + token.value = int(token.value) + return token + + def error(self, token): + self.cool_error(token.lineno, token.index) + self.cool_error.add_lexical(f'Unknown character {token.value[0]}') + self.index += 1 + + + diff --git a/src/cool_compiler/lexer/string_lexer.py b/src/cool_compiler/lexer/string_lexer.py new file mode 100755 index 000000000..01b0344cf --- /dev/null +++ b/src/cool_compiler/lexer/string_lexer.py @@ -0,0 +1,86 @@ +from re import S +from sly import Lexer, lex + +class CoolString(Lexer): + tokens = { TEXT, BACKNEWL, + FORMFEED, TAB, BACKESPACE, NEWLINE + } + + + ignore_newline = r'\n' + ignore_close = r'"' + ignore_null = r'\0' + + FORMFEED = r'\\f' + TAB = r'\\t' + BACKESPACE= r'\\b' + NEWLINE = r'\\n' + CHARTER =r'\\.' + BACKNEWL = r'\\ *\n' + TEXT = r'.' + + def __init__(self, lexer ): + self.lexer = lexer + self.pos = 0 + self.count_new_line = 0 + self.len = 0 + + def ignore_close(self, token): + self.index = self.len + self.pos = token.index + 1 + + def ignore_newline(self, token): + index = self.lexer.index + token.index + lineno = self.lexer.lineno + self.count_new_line + self.lexer.cool_error(lineno, index) + self.lexer.cool_error.add_lexical("Unterminated string constant") + self.index = self.len + self.pos = token.index + + def ignore_null(self, token): + index = self.lexer.index + token.index + lineno = self.lexer.lineno + self.count_new_line + self.lexer.cool_error(lineno, index) + self.lexer.cool_error.add_lexical("String contains null character") + + + def FORMFEED(self, token): + token.value = '\f' + return token + + def TAB(self, token): + token.value = '\t' + return token + + def BACKESPACE(self, token): + token.value = '\b' + return token + + def NEWLINE(self, token): + token.value = '\n' + return token + + def CHARTER(self, token): + token.value = token.value[1:] + return token + + def BACKNEWL(self, token): + self.count_new_line += 1 + token.value ="\n" + return token + + + + def string_analizer(self): + text = self.lexer.text[self.lexer.index:] + self.len = len(text) + _list = [] + for t in self.tokenize(text): + _list.append(t.value) + + result = ''.join(_list) + return result, self.pos, self.count_new_line + + + + diff --git a/src/cool_compiler/parser/__dependency.py b/src/cool_compiler/parser/__dependency.py new file mode 100755 index 000000000..5cea93ba9 --- /dev/null +++ b/src/cool_compiler/parser/__dependency.py @@ -0,0 +1 @@ +from ..lexer import CoolLexer as CoolTokens \ No newline at end of file diff --git a/src/cool_compiler/parser/__init__.py b/src/cool_compiler/parser/__init__.py new file mode 100755 index 000000000..be490ce94 --- /dev/null +++ b/src/cool_compiler/parser/__init__.py @@ -0,0 +1,2 @@ +from .cool_parser import CoolParser +from .factory_decored import factory, decored, Tester, NodesName \ No newline at end of file diff --git a/src/cool_compiler/parser/__main__.py b/src/cool_compiler/parser/__main__.py new file mode 100755 index 000000000..9bffe317e --- /dev/null +++ b/src/cool_compiler/parser/__main__.py @@ -0,0 +1,2 @@ +def parser(tokens): + pass \ No newline at end of file diff --git a/src/cool_compiler/parser/cool_parser.py b/src/cool_compiler/parser/cool_parser.py new file mode 100755 index 000000000..516ef50a2 --- /dev/null +++ b/src/cool_compiler/parser/cool_parser.py @@ -0,0 +1,287 @@ +from sly import Parser +from .__dependency import CoolTokens +from .factory_decored import NodesName + +class CoolParser(Parser): + tokens = CoolTokens.tokens + start = 'program' + precedence = ( + ('right', 'ARROW'), + ('left','NOT'), + ('nonassoc', '=','<','LESS_OR'), + ('left', '+', '-'), + ('left', '*', '/'), + ('left', "ISVOID"), + ('left', '~'), + ('left', '@'), + ('right', 'IN'), + ('left', '.'), + + ) + def __init__(self, factory, errors): + self.factory = factory + self.cool_error = errors + self.lte = None + + def error(self, token): + tok = next(self.tokens, None) + if self.lte is None or not self.lte == token : + if token is None: + try: + tok = self.symstack[-1] + self.cool_error(tok.lineno, tok.index) + except AttributeError: + self.cool_error.pos = (0, 0) + self.cool_error.add_syntactic(f"ERROR at or near EOF") + return + else: + char = token.value + self.cool_error(token.lineno, token.index) + self.cool_error.add_syntactic(f"ERROR at or near {char}") + self.lte = tok + return tok + + @_("") + def epsilon(self, prod): + pass + + @_('class_list') + def program(self, prod): + return self.factory( NodesName.Program, prod.class_list ) + + @_("cclass epsilon") + def class_list(self, prod): + return [prod.cclass] + + @_('cclass class_list') + def class_list(self, prod): + return [prod.cclass] + prod.class_list + + @_('CLASS TYPE "{" class_feature "}" ";" ') + def cclass(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Class, prod.TYPE, None, prod.class_feature ) + + @_('CLASS TYPE INHERITS TYPE "{" class_feature "}" ";"') + def cclass(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Class, prod.TYPE0, prod.TYPE1, prod.class_feature ) + + @_('def_atr ";" class_feature') + def class_feature(self, prod): + return [prod.def_atr] + prod.class_feature + + @_('def_func ";" class_feature') + def class_feature(self, prod): + return [prod.def_func] + prod.class_feature + + @_('epsilon') + def class_feature(self, prod): + return [] + + @_('ID ":" TYPE') + def def_atr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.DefAtr, prod.ID, prod.TYPE, None ) + + @_('ID ":" TYPE ARROW expr') + def def_atr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.DefAtr, prod.ID, prod.TYPE, prod.expr ) + + @_('ID "(" param_list ")" ":" TYPE "{" expr "}"') + def def_func(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.DefFunc, prod.ID, prod.param_list, prod.TYPE, prod.expr ) + + @_('ID "(" ")" ":" TYPE "{" expr "}"') + def def_func(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.DefFunc, prod.ID, [], prod.TYPE, prod.expr ) + + @_('ID ":" TYPE "," param_list') + def param_list(self, prod): + return [( prod.ID, prod.TYPE )] + prod.param_list + + @_('ID ":" TYPE') + def param_list(self, prod): + return [( prod.ID, prod.TYPE )] + + @_('ID ARROW expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Assing, prod.ID, prod.expr) + + @_('expr "@" TYPE "." ID "(" expr_list ")"', 'expr "@" TYPE "." ID "(" ")"' ) + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + try: + return self.factory( NodesName.CastingDispatch, prod.expr, prod.TYPE, prod.ID, prod.expr_list) + except AttributeError: + return self.factory( NodesName.CastingDispatch, prod.expr, prod.TYPE, prod.ID, []) + + @_('expr "." ID "(" expr_list ")"', 'expr "." ID "(" ")"') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + try: + return self.factory( NodesName.Dispatch, prod.expr, prod.ID, prod.expr_list) + except: + return self.factory( NodesName.Dispatch, prod.expr, prod.ID, []) + + @_('ID "(" expr_list ")"', 'ID "(" ")"') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + try: + return self.factory( NodesName.StaticDispatch, prod.ID, prod.expr_list ) + except AttributeError: + return self.factory( NodesName.StaticDispatch, prod.ID, [] ) + + @_('expr "," expr_list') + def expr_list(self, prod): + return [prod.expr] + prod.expr_list + + @_('expr') + def expr_list(self, prod): + return [prod.expr] + + @_('IF expr THEN expr ELSE expr FI') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.IfThenElse, prod.expr0, prod.expr1, prod.expr2) + + @_('WHILE expr LOOP expr POOL') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.While, prod.expr0, prod.expr1) + + @_('"{" block_list "}"') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Block, prod.block_list) + + @_('expr ";" block_list') + def block_list(self, prod): + return [prod.expr] + prod.block_list + + @_('expr ";" epsilon') + def block_list(self, prod): + return [prod.expr] + + @_('LET let_list IN expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.LetIn, prod.let_list, prod.expr) + + @_('let_assign "," let_list') + def let_list(self, prod): + return [prod.let_assign] + prod.let_list + + @_('let_assign epsilon') + def let_list(self, prod): + return [prod.let_assign] + + @_('ID ":" TYPE ARROW expr') + def let_assign(self, prod): + return (prod.ID, prod.TYPE, prod.expr) + + @_('ID ":" TYPE') + def let_assign(self, prod): + return (prod.ID, prod.TYPE, None) + + @_('CASE expr OF case_list ESAC') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Case, prod.case_list, prod.expr) + + @_('ID ":" TYPE LOGICAR expr ";" case_list') + def case_list(self, prod): + return [( prod.ID, prod.TYPE, prod.expr )] + prod.case_list + + @_('ID ":" TYPE LOGICAR expr ";"') + def case_list(self, prod): + return [( prod.ID, prod.TYPE, prod.expr )] + + @_('NEW TYPE') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.New, prod.TYPE ) + + @_('ISVOID expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.IsVoid, prod.expr ) + + @_('expr "+" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Sum, prod.expr0, prod.expr1 ) + + @_('expr "-" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Rest, prod.expr0, prod.expr1 ) + + @_('expr "*" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Mult, prod.expr0, prod.expr1 ) + + @_('expr "/" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Div, prod.expr0, prod.expr1 ) + + @_('"~" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Complement, prod.expr ) + + @_('expr "<" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Less, prod.expr0, prod.expr1 ) + + @_('expr LESS_OR expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.LessOrEquals, prod.expr0, prod.expr1 ) + + @_('expr "=" expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Equals, prod.expr0, prod.expr1 ) + + @_('NOT expr') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Neg, prod.expr ) + + @_('"(" expr ")"') + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return prod.expr + + @_("ID") + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.IdExpr, prod.ID) + + @_("NUMBER") + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Int, prod.NUMBER) + + @_("STRING") + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Str, prod.STRING) + + @_("TRUE") + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Bool, prod.TRUE) + + @_("FALSE") + def expr(self, prod): + self.factory.get_pos_to_errors(prod.lineno, prod.index) + return self.factory( NodesName.Bool, prod.FALSE) \ No newline at end of file diff --git a/src/cool_compiler/parser/factory_decored.py b/src/cool_compiler/parser/factory_decored.py new file mode 100755 index 000000000..e099844fc --- /dev/null +++ b/src/cool_compiler/parser/factory_decored.py @@ -0,0 +1,65 @@ +import inspect +from enum import Enum + +def factory(cls): + def call(cls, name_node, *args): + return cls.__dict_decored[name_node](cls, *args) + cls.__call__ = call + return cls + +def factory_tester(cls): + def call(cls, name_node, *args): + pass + cls.__call__ = call + return cls + +def decored(string): + def fn(fn): + frame = inspect.currentframe().f_back + try: + _dict = frame.f_locals['__dict_decored'] + _dict[string] = fn + except KeyError: + frame.f_locals['__dict_decored'] = { string : fn } + + return fn + return fn + +class NodesName(Enum): + Id = "Id" + Type = "Type" + Program = "Program" + Class = "Class" + DefAtr = "DefAtr" + DefFunc = "DefFunc" + Assing = "Assing" + CastingDispatch = "CastingDispatch" + Dispatch= "Dispatch" + StaticDispatch = "StaticDispatch" + IfThenElse = "IfThenElse" + While = "While" + Block = "Block" + LetIn = "LetIn" + Case = "Case" + New = "New" + IsVoid = "IsVoid" + Sum = "Sum" + Rest = "Rest" + Mult = "Mult" + Div = "Div" + Complement = "Complement" + Less = "Less" + LessOrEquals = "LessOrEquals" + Equals = "Equals" + Neg = "Neg" + IdExpr = "IdExpr" + Int = "Int" + Str = "Str" + Bool = "Bool" + +@factory_tester +class Tester: + + @decored("CLASS") + def fclass(self, name, parent, feature): + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/.DS_Store b/src/cool_compiler/semantic/.DS_Store new file mode 100644 index 000000000..6397e4c0a Binary files /dev/null and b/src/cool_compiler/semantic/.DS_Store differ diff --git a/src/cool_compiler/semantic/__dependency.py b/src/cool_compiler/semantic/__dependency.py new file mode 100755 index 000000000..806761518 --- /dev/null +++ b/src/cool_compiler/semantic/__dependency.py @@ -0,0 +1,13 @@ +from ..parser import factory as factory +from ..parser import decored as decored +from ..parser import NodesName as Nodes +from ..types import Type as Type +from ..types import SemanticError as SemanticError +from ..types import ErrorType as ErrorType +from ..types import Int as Int +from ..types import Bool as Bool +from ..types import String as Str +from ..types import Object as Object +from ..types import Self as Self +from ..types import CoolTypeBuildInManager as CoolTypeBuildInManager +from ..error import CoolError diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py new file mode 100755 index 000000000..fd4d3a5af --- /dev/null +++ b/src/cool_compiler/semantic/__init__.py @@ -0,0 +1,3 @@ +from .v0_parser_return.factory_parser_return_visitor import CoolFactory +from .v1_create_type.create_type_visitor import CoolCreateType as CreateType +from .v2_semantic_checking.semantic_checking_visitor import CoolSemanticChecking as SemanticChecking \ No newline at end of file diff --git a/src/cool_compiler/semantic/ast_print.py b/src/cool_compiler/semantic/ast_print.py new file mode 100755 index 000000000..0e179bbc9 --- /dev/null +++ b/src/cool_compiler/semantic/ast_print.py @@ -0,0 +1,250 @@ +from .ASTs import ast0_factory_return as AST_init +from .ASTs import ast1_create_type_return as AST_result +from ..cmp import visitor + +class ASTPrint: + def __init__(self, error) -> None: + self.cool_error = error + + @visitor.on("node") + def visit(self, node, str): + pass + + @visitor.when(AST_init.Program) + #@visitor.result(AST_result.Program) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Program, tabs = 0): + ans = '\t' * tabs + f'\\__ProgramNode [ ... ]' + statements = '\n'.join(self.visit(child, tabs + 1) for child in node.class_list) + return f'{ans}\n{statements}' + + @visitor.when(AST_init.CoolClass) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.CoolClass, tabs): + parent = '' if node.parent is None else f": {node.parent}" + ans = '\t' * tabs + f'\\__ClassDeclarationNode: class {node.name} {parent} {{ ... }}' + features = '\n'.join(self.visit(child, tabs + 1) for child in node.feature_list) + return f'{ans}\n{features}' + + @visitor.when(AST_init.AtrDef) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.AtrDef, tabs): + ans = '\t' * tabs + f'\\__AttrDeclarationNode: {node.name} : {node.type}' + expr = '' if node.expr is None else self.visit(node.expr, tabs + 1) + return f'{ans}\n{expr}' + + @visitor.when(AST_init.FuncDef) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.FuncDef, tabs): + params = ', '.join(':'.join(param) for param in node.params) + ans = '\t' * tabs + f'\\__FuncDeclarationNode: {node.name}({params}) : {node.return_type} -> ' + body = self.visit(node.expr, tabs + 1) + return f'{ans}\n{body}' + + @visitor.when(AST_init.CastingDispatch) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.CastingDispatch, tabs): + ans = '\t' * tabs + f'\\__CastingDispatch: {node.type} @ {node.id} \\__Object:' + obj = self.visit(node.expr, tabs + 1) + param = '\t' * tabs + f'\\__Params:' + params = '\n'.join( self.visit(param, tabs + 1) for param in node.params) + return f'{ans}\n{obj}\n{param}\n{params}' + + @visitor.when(AST_init.Dispatch) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Dispatch, tabs): + ans = '\t' * tabs + f'\\__Dispatch: {node.id} \\__Object:' + obj = self.visit(node.expr, tabs + 1) + param = '\t' * tabs + f'\\__Params:' + params = '\n'.join( self.visit(param, tabs + 1) for param in node.params) + return f'{ans}\n{obj}\n{param}\n{params}' + + @visitor.when(AST_init.StaticDispatch) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.StaticDispatch, tabs): + ans = '\t' * tabs + f'\\__StaticDispatch: {node.id} \\__Params:' + params = '\n'.join( self.visit(param, tabs + 1) for param in node.params) + return f'{ans}\n{params}' + + @visitor.when(AST_init.Assing) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Assing, tabs): + ans = '\t' * tabs + f'\\__AssignNode: {node.id} = ' + expr = self.visit(node.expr, tabs + 1) + return f'{ans}\n{expr}' + + @visitor.when(AST_init.IfThenElse) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.IfThenElse, tabs): + _if = '\t' * tabs + f'\\__IfNode:' + cond = self.visit(node.condition, tabs + 1) + then = '\t' * tabs + f'\\__Then:' + then_expr = self.visit(node.then_expr, tabs + 1) + _else = '\t' * tabs + f'\\__Else:' + else_expr = self.visit(node.else_expr, tabs + 1) + return f'{_if}\n{cond}\n{then}\n{then_expr}\n{_else}\n{else_expr}' + + + @visitor.when(AST_init.While) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.While, tabs): + _while = '\t' * tabs + f'\\__WhileNode:' + cond = self.visit(node.condiction, tabs + 1) + loop = '\t' * tabs + f'\\__Loop:' + body = self.visit(node.loop_expr, tabs + 1) + pool = '\t' * tabs + f'\\__Pool:' + return f'{_while}\n{cond}\n{loop}\n{body}\n{pool}' + + @visitor.when(AST_init.Block) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Block, tabs): + block = '\t' * tabs + f'\\__BlocksNode:' + _list = '\n'.join(self.visit(expr, tabs + 1 ) for expr in node.expr_list) + return f'{block}\n{_list}' + + @visitor.when(AST_init.LetIn) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.LetIn, tabs): + ans = '\t' * tabs + f'\\__LetNode:' + var_list = '\n'.join('\t' * (tabs + 1) + idx + " : " + typ + "\n" + self.visit(exp, tabs + 1) for idx, typ, exp in node.assing_list) + expr = '\t' * tabs + f'\\__In:\n' + self.visit(node.expr, tabs + 2) + return f'{ans}\n{var_list}\n{expr}' + + @visitor.when(AST_init.Case) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Case, tabs): + case = '\t' * tabs + f'\\__CaseNode:' + expr = self.visit(node.expr, tabs + 1) + _list = '\t' * tabs + f'\\__OptionsList:' + list_case = '\n'.join(self.visit(case, tabs + 1) for case in node.case_list) + return f'{case}\n{expr}\n{_list}\n{list_case}' + + + @visitor.when(AST_init.Sum) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Sum, tabs): + ans = '\t' * tabs + f'\\__ Sum ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + + @visitor.when(AST_init.Rest) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Rest, tabs): + ans = '\t' * tabs + f'\\__ Rest ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.Mult) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Mult, tabs): + ans = '\t' * tabs + f'\\__ Mult ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.Div) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Div, tabs): + ans = '\t' * tabs + f'\\__ Div ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.Less) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Less, tabs): + ans = '\t' * tabs + f'\\__ Less ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.LessOrEquals) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.LessOrEquals, tabs): + ans = '\t' * tabs + f'\\__ LOrE ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.Equals) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Equals, tabs): + ans = '\t' * tabs + f'\\__ Equals ' + left = self.visit(node.left, tabs + 1) + right = self.visit(node.right, tabs + 1) + return f'{ans}\n{left}\n{right}' + + @visitor.when(AST_init.Void) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Void, tabs): + exp = self.visit(node.item, tabs + 1) + return '\t' * tabs + f'\\__ Void\n {exp}' + + + @visitor.when(AST_init.New) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.New, tabs): + return '\t' * tabs + f'\\__ InstantiateNode: new {node.item}()' + + @visitor.when(AST_init.Complement) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Complement, tabs): + exp = self.visit(node.item, tabs + 1) + return '\t' * tabs + f'\\__Complemnt\n {exp}' + + @visitor.when(AST_init.Neg) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Neg, tabs): + exp = self.visit(node.item, tabs + 1) + return '\t' * tabs + f'\\__Neg\n {exp}' + + @visitor.when(AST_init.Id) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Id, tabs): + return '\t' * tabs + f'\\__ Id:{node.item}' + + @visitor.when(AST_init.Int) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Int, tabs): + return '\t' * tabs + f'\\__ Int:{node.item}' + + + @visitor.when(AST_init.Bool) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Bool, tabs): + return '\t' * tabs + f'\\__ Bool:{node.item}' + + @visitor.when(AST_init.Str) + #@visitor.result(AST_result.CoolClass) + #@visitor.inmutable_visit + def visit(self, node: AST_init.Str, tabs): + return '\t' * tabs + f'\\__ Str:{node.item}' diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py new file mode 100755 index 000000000..953075c26 --- /dev/null +++ b/src/cool_compiler/semantic/tools.py @@ -0,0 +1,92 @@ +from cool_compiler.cmp.visitor import result +from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object, CoolError +from ..cmp.scope import Scope + +class VisitBase: + def __init__(self, error) -> None: + self.cool_error = error + self.current_type : Type = None + + def get_type(self, type_name, error_handler): + find_result = find_type(type_name, self.global_types) + return find_result.get_value( if_fail_do= error_handler().add_type_error ) + + def visit_all(self, list_node, *args): + result = [] + for n in list_node: + result.append(self.visit(n, *args)) + + return result + + def get_se_handler(self, node): + return self.cool_error.get_handler(node.lineno, node.index) + + + def get_parent_type(self, node, error_handler): + if node.parent is None: return Object() + + find_result = find_type(node.parent, self.global_types) + parent_type = find_result.get_value( if_fail_do= error_handler().add_semantic_error ) + + if parent_type.is_shield or parent_type.name == self.current_type.name: + error_handler().add_semantic_error( f"class {self.current_type.name} can't be inherited from {parent_type.name}" ) + return ErrorType() + + return parent_type + + def type_checking(self, t_base : Type, t_type : Type): + if t_base.is_self_type : t_base = self.current_type + if t_type.is_self_type : t_type = self.current_type + + if not t_type.conforms_to(t_base): + return False + + return True + + +class Result: + def __init__(self, succ, result, error) -> None: + self.succ = succ + self.result = result + self.error = error + + def get_value(self, if_fail_do = None): + if self.succ: return self.result + + if_fail_do(self.error) + return self.result + + @staticmethod + def ok(result): + return Result(True, result, "") + + @staticmethod + def fail(error, neutro = None): + return Result(False, neutro, error) + + +def find_type(name, global_types) -> Result: + if name in global_types: + return Result.ok( global_types[name] ) + try: + return Result.ok( CoolTypeBuildInManager().find(name) ) + except SemanticError as se: + return Result.fail( se.text, neutro = ErrorType() ) + +def parent_common(t1: Type, t2: Type): + while True: + if None is t1: return Object() + if None is t2: return Object() + if t1.conforms_to(t2): return t2 + if t2.conforms_to(t1): return t1 + + t1 = t1.parent + t2 = t2.parent + +def find_variable(self, name, scope: Scope, node) -> Result: + try: + v = scope.find_variable(name) + return Result.ok (v.type) + except SemanticError: + self.cool_error(node.lineno, node.index).add_name_error(name) + return Result.fail(name, neutro = ErrorType() ) diff --git a/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_ast.py b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_ast.py new file mode 100755 index 000000000..c1a62c21e --- /dev/null +++ b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_ast.py @@ -0,0 +1,147 @@ +class Node: + def get_pos_to_error(self, lineno, index): + self.lineno = lineno + self.index = index + +#################################################################### +class Program(Node): + def __init__(self, class_list, class_name_list) -> None: + self.class_list = class_list + self.names_list = class_name_list + +class CoolClass(Node): + def __init__(self, name, parent, feature_list) -> None: + self.name = name + self.parent = parent + self.feature_list = feature_list + +###################################################################### +class Feature(Node): + pass + +class AtrDef(Feature): + def __init__(self, name, atype, expr) -> None: + self.name = name + self.type = atype + self.expr = expr + +class FuncDef(Feature): + def __init__(self, name, param_list, return_type, expr) -> None: + self.name = name + self.params = param_list + self.return_type = return_type + self.expr = expr + +######################################################################## +class Expresion(Node): + pass + +class CastingDispatch(Expresion): + def __init__(self, expr, atype, idf, params) -> None: + self.expr = expr + self.type = atype + self.id = idf + self.params = params + +class Dispatch(Expresion): + def __init__(self, expr, idf, params) -> None: + self.expr = expr + self.id = idf + self.params = params + +class StaticDispatch(Expresion): + def __init__(self, idf, params) -> None: + self.id = idf + self.params = params + +####################################################################### +class Statement(Expresion): + pass + +class Assing(Statement): + def __init__(self, name, expr) -> None: + self.id = name + self.expr = expr + +class IfThenElse(Statement): + def __init__(self, condition, then_expr, else_expr) -> None: + self.condition = condition + self.then_expr = then_expr + self.else_expr = else_expr + +class While(Statement): + def __init__(self, condition, loop_expr) -> None: + self.condition = condition + self.loop_expr = loop_expr + +class Block(Statement): + def __init__(self, expr_list) -> None: + self.expr_list = expr_list + +class LetIn(Statement): + def __init__(self, assing_list, expr) -> None: + self.assing_list = assing_list + self.expr = expr + +class Case(Statement): + def __init__(self, case_list, expr) -> None: + self.case_list = case_list + self.expr = expr + +################################################################## +class Binary(Expresion): + def __init__(self, left, right) -> None: + self.left = left + self.right = right + +class Sum(Binary): + pass + +class Rest(Binary): + pass + +class Mult(Binary): + pass + +class Div(Binary): + pass + +class Less(Binary): + pass + +class LessOrEquals(Binary): + pass + +class Equals(Binary): + pass + +########################################################### +class Atomic(Expresion): + def __init__(self, item) -> None: + self.item = item + +class Void(Atomic): + pass + +class New(Atomic): + pass + +class Complement(Atomic): + pass + +class Neg(Atomic): + pass + +class Id(Atomic): + pass + +class Int(Atomic): + pass + +class Str(Atomic): + pass + +class Bool(Atomic): + pass + + diff --git a/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py new file mode 100755 index 000000000..98b65d251 --- /dev/null +++ b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py @@ -0,0 +1,166 @@ +from ..__dependency import factory, decored, Nodes +from .factory_parser_return_ast import * + +@factory +class CoolFactory: + def __init__(self, errors) -> None: + self.global_names = [] + self.cool_error = errors + + def get_pos_to_errors(self, lineno, index): + self.lineno = lineno + self.index = index + + def compose(fn): + def ffn(*args, **kword): + node = fn(*args, **kword) + node.get_pos_to_error(args[0].lineno, args[0].index) + return node + return ffn + + @decored(Nodes.Program) + @compose + def program(self, class_list): + return Program(class_list, self.global_names) + + @decored(Nodes.Class) + @compose + def cool_class(self, name, parent, features): + self.global_names.append((name, self.lineno, self.index)) + return CoolClass(name,parent,features) + +################################################################ + @decored(Nodes.DefAtr) + @compose + def defatr(self, name, atype, expr): + return AtrDef(name, atype, expr) + + @decored(Nodes.DefFunc) + @compose + def deffunc(self, name, params, return_type, expr): + return FuncDef(name, params, return_type, expr) + +################################################################ + @decored(Nodes.CastingDispatch) + @compose + def casting_dispatch(self, expr, atype, idx, params): + return CastingDispatch(expr, atype, idx, params) + + @decored(Nodes.Dispatch) + @compose + def dispatch(self, expr, idx, params): + return Dispatch(expr, idx, params) + + @decored(Nodes.StaticDispatch) + @compose + def static_dispatch(self, idx, params): + return StaticDispatch(idx, params) + +################################################################ + @decored(Nodes.Assing) + @compose + def asssing(self, idx, expr): + return Assing(idx, expr) + + @decored(Nodes.IfThenElse) + @compose + def if_then_else(self, cond, then, eelse): + return IfThenElse(cond, then, eelse) + + @decored(Nodes.While) + @compose + def wwhile(self, cond, expr): + return While(cond, expr) + + @decored(Nodes.Block) + @compose + def block(self, expr_list): + return Block(expr_list) + + @decored(Nodes.LetIn) + @compose + def let_in(self, assing_list, expr): + return LetIn(assing_list, expr) + + @decored(Nodes.Case) + @compose + def case(self, case_list, expr): + return Case(case_list, expr) + +################################################################ + @decored(Nodes.Sum) + @compose + def sum(self, left, right): + return Sum(left,right) + + @decored(Nodes.Rest) + @compose + def rest(self, left, right): + return Rest(left,right) + + @decored(Nodes.Mult) + @compose + def mult(self, left, right): + return Mult(left,right) + + @decored(Nodes.Div) + @compose + def div(self, left, right): + return Div(left,right) + + @decored(Nodes.Less) + @compose + def less(self, left, right): + return Less(left,right) + + @decored(Nodes.LessOrEquals) + @compose + def less_or_equals(self, left, right): + return LessOrEquals(left,right) + + @decored(Nodes.Equals) + @compose + def equals(self, left, right): + return Equals(left,right) + +############################################################### + + @decored(Nodes.IsVoid) + @compose + def is_void(self, item): + return Void(item) + + @decored(Nodes.New) + @compose + def new(self, item): + return New(item) + + @decored(Nodes.Complement) + @compose + def complement(self, item): + return Complement(item) + + @decored(Nodes.Neg) + @compose + def neg(self, item): + return Neg(item) + + @decored(Nodes.IdExpr) + @compose + def idexpr(self, item): + return Id(item) + + @decored(Nodes.Int) + @compose + def intt(self, item): + return Int(item) + + @decored(Nodes.Str) + @compose + def string(self, item): + return Str(item) + + @decored(Nodes.Bool) + @compose + def boool(self, item): + return Bool(item) \ No newline at end of file diff --git a/src/cool_compiler/semantic/v1_create_type/create_type_ast.py b/src/cool_compiler/semantic/v1_create_type/create_type_ast.py new file mode 100644 index 000000000..152258a7f --- /dev/null +++ b/src/cool_compiler/semantic/v1_create_type/create_type_ast.py @@ -0,0 +1,145 @@ +from ..__dependency import Type + +class Node: + def get_pos_to_error(self, lineno, index): + self.lineno = lineno + self.index = index + +class Program(Node): + def __init__(self, class_list) -> None: + self.class_list = class_list + +class CoolClass(Node): + def __init__(self, typee, parent_type, feature_list) -> None: + self.type : Type = typee + self.parent_type : Type = parent_type + self.feature_list = feature_list + +###################################################################### +class Feature(Node): + pass + +class AtrDef(Feature): + def __init__(self, name, atype, expr) -> None: + self.name = name + self.type = atype + self.expr = expr + +class FuncDef(Feature): + def __init__(self, name, param_list, return_type, expr) -> None: + self.name = name + self.params = param_list + self.return_type = return_type + self.expr = expr + +######################################################################## +class Expresion(Node): + pass + +class CastingDispatch(Expresion): + def __init__(self, expr, atype, idf, params) -> None: + self.expr = expr + self.type = atype + self.id = idf + self.params = params + +class Dispatch(Expresion): + def __init__(self, expr, idf, params) -> None: + self.expr = expr + self.id = idf + self.params = params + +class StaticDispatch(Expresion): + def __init__(self, idf, params) -> None: + self.id = idf + self.params = params + +####################################################################### +class Statement(Expresion): + pass + +class Assing(Statement): + def __init__(self, name, expr) -> None: + self.id = name + self.expr = expr + +class IfThenElse(Statement): + def __init__(self, condition, then_expr, else_expr) -> None: + self.condition = condition + self.then_expr = then_expr + self.else_expr = else_expr + +class While(Statement): + def __init__(self, condition, loop_expr) -> None: + self.condition = condition + self.loop_expr = loop_expr + +class Block(Statement): + def __init__(self, expr_list) -> None: + self.expr_list = expr_list + +class LetIn(Statement): + def __init__(self, assing_list, expr) -> None: + self.assing_list = assing_list + self.expr = expr + +class Case(Statement): + def __init__(self, expr, case_list) -> None: + self.case_list = case_list + self.expr = expr + +####################################################################### +class Binary(Expresion): + def __init__(self, left, right) -> None: + self.left = left + self.right = right + +class Sum(Binary): + pass + +class Rest(Binary): + pass + +class Mult(Binary): + pass + +class Div(Binary): + pass + +class Less(Binary): + pass + +class LessOrEquals(Binary): + pass + +class Equals(Binary): + pass + +####################################################################### +class Atomic(Expresion): + def __init__(self, item) -> None: + self.item = item + +class Void(Atomic): + pass + +class New(Atomic): + pass + +class Complement(Atomic): + pass + +class Neg(Atomic): + pass + +class Id(Atomic): + pass + +class Int(Atomic): + pass + +class Str(Atomic): + pass + +class Bool(Atomic): + pass diff --git a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py new file mode 100644 index 000000000..5492462ef --- /dev/null +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -0,0 +1,305 @@ +from os import confstr +from ...cmp import visitor +from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str, Self, CoolTypeBuildInManager +from ..v0_parser_return import factory_parser_return_ast as AST +from . import create_type_ast as ASTR +from ..tools import VisitBase, find_type + +class CoolCreateType(VisitBase): + def __init__(self, errors) -> None: + super().__init__(errors) + self.global_types = CoolTypeBuildInManager().dictt + + + def get_parent_type(self, node, error_handler): + if node.parent is None: return Object() + + find_result = find_type(node.parent, self.global_types) + parent_type = find_result.get_value( if_fail_do= error_handler().add_type_error ) + + if parent_type.is_shield or parent_type.name == self.current_type.name: + error_handler().add_semantic_error( f"class {self.current_type.name} can't be inherited from {parent_type.name}" ) + return ErrorType() + + return parent_type + + @visitor.on("node") + def visit(node): + pass + + @visitor.when(AST.Program) + @visitor.result(ASTR.Program) + def visit(self, node : AST.Program) : + for name, lineno, index in node.names_list: + if name in self.global_types: + self.cool_error(lineno, index) + self.cool_error.add_semantic_error(f"{name} is already defined") + else: self.global_types[name] = Type(name) + + class_list = self.visit_all(node.class_list) + + return class_list, + + @visitor.when(AST.CoolClass) + @visitor.result(ASTR.CoolClass) + def visit(self, node : AST.CoolClass) : + self.current_type = self.global_types[node.name] + + error_handler = self.get_se_handler(node) + + parent_type = self.get_parent_type(node, error_handler) + try: + if parent_type.conforms_to(self.current_type): + error_handler().add_semantic_error(f"class {self.current_type.name} has circular inheritance") + parent_type = ErrorType() + self.current_type.set_parent(parent_type) + except AttributeError: pass + except SemanticError as se: + error_handler().add_semantic_error(se.text) + + feature_list = self.visit_all(node.feature_list) + + return self.current_type, parent_type, feature_list + + @visitor.when(AST.AtrDef) + @visitor.result(ASTR.AtrDef) + def visit(self, node : AST.AtrDef) : + error_handler = self.get_se_handler(node) + + atype = self.get_type(node.type, error_handler) + try: self.current_type.define_attribute(node.name, atype) + except SemanticError as se: + error_handler().add_semantic_error(se.text) + + expr = self.visit(node.expr) + return node.name, atype, expr + + @visitor.when(AST.FuncDef) + @visitor.result(ASTR.FuncDef) + def visit(self, node : AST.FuncDef) : + error_handler = self.get_se_handler(node) + + return_type = self.get_type(node.return_type, error_handler) + + params = [] + for name, ptype in node.params: + param_type = self.get_type(ptype, error_handler) + params.append((name, param_type)) + + try: self.current_type.define_method(node.name, params, return_type) + except SemanticError as se: + error_handler().add_semantic_error(se.text) + + expr = self.visit(node.expr) + return node.name, params, return_type, expr + + @visitor.when(AST.CastingDispatch) + @visitor.result(ASTR.CastingDispatch) + def visit(self, node: AST.CastingDispatch): + error = self.get_se_handler(node) + return tuple([ + self.visit(node.expr), + self.get_type(node.type, error), + node.id, + self.visit_all(node.params) + ]) + + @visitor.when(AST.Dispatch) + @visitor.result(ASTR.Dispatch) + def visit(self, node: AST.Dispatch): + return tuple([ + self.visit(node.expr), + node.id, + self.visit_all(node.params) + ]) + + @visitor.when(AST.StaticDispatch) + @visitor.result(ASTR.StaticDispatch) + def visit(self, node: AST.StaticDispatch): + return tuple([ + node.id, + self.visit_all(node.params) + ]) + + @visitor.when(AST.Assing) + @visitor.result(ASTR.Assing) + def visit(self, node: AST.Assing): + error_handler = self.get_se_handler(node) + if node.id == 'self': + error_handler().add_semantic_error("Self assign intro let") + + return tuple([ + node.id, + self.visit(node.expr) + ]) + + @visitor.when(AST.IfThenElse) + @visitor.result(ASTR.IfThenElse) + def visit(self, node: AST.IfThenElse): + return tuple([ + self.visit(node.condition), + self.visit(node.then_expr), + self.visit(node.else_expr), + ]) + + @visitor.when(AST.While) + @visitor.result(ASTR.While) + def visit(self, node: AST.While): + return tuple([ + self.visit(node.condition), + self.visit(node.loop_expr), + ]) + + @visitor.when(AST.While) + @visitor.result(ASTR.While) + def visit(self, node: AST.While): + return tuple([ + self.visit(node.condition), + self.visit(node.loop_expr), + ]) + + + @visitor.when(AST.Block) + @visitor.result(ASTR.Block) + def visit(self, node: AST.Block): + return tuple([ + self.visit_all(node.expr_list), + ]) + + @visitor.when(AST.LetIn) + @visitor.result(ASTR.LetIn) + def visit(self, node : AST.LetIn) : + error_handler = self.get_se_handler(node) + + assing_list = [] + for name, atype, expr in node.assing_list: + if name == 'self': + error_handler().add_semantic_error("Self assign intro let") + rtype = self.get_type(atype, error_handler) + assing_list.append((name, rtype, self.visit(expr))) + + return assing_list, self.visit(node.expr) + + @visitor.when(AST.Case) + @visitor.result(ASTR.Case) + def visit(self, node : AST.Case) : + error_handler = self.get_se_handler(node) + + case_list = [] + sett = set() + for name, atype, expr in node.case_list: + branch_error_handler = self.get_se_handler(expr) + rtype = self.get_type(atype, branch_error_handler) + sett.add(str(rtype)) + case_list.append((name, rtype, self.visit(expr))) + if len(sett) != len(case_list): branch_error_handler().add_semantic_error(f"Type {rtype.name} branch duplicate ") + + + return self.visit(node.expr), case_list + + @visitor.when(AST.Sum) + @visitor.result(ASTR.Sum) + def visit(self, node: AST.Sum): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Rest) + @visitor.result(ASTR.Rest) + def visit(self, node: AST.Rest): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Mult) + @visitor.result(ASTR.Mult) + def visit(self, node: AST.Mult): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Div) + @visitor.result(ASTR.Div) + def visit(self, node: AST.Div): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Less) + @visitor.result(ASTR.Less) + def visit(self, node: AST.Less): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.LessOrEquals) + @visitor.result(ASTR.LessOrEquals) + def visit(self, node: AST.LessOrEquals): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Equals) + @visitor.result(ASTR.Equals) + def visit(self, node: AST.Equals): + return tuple([ + self.visit(node.left), + self.visit(node.right), + ]) + + @visitor.when(AST.Void) + @visitor.result(ASTR.Void) + def visit(self, node: AST.Void): + return tuple([ + self.visit(node.item), + ]) + + @visitor.when(AST.New) + @visitor.result(ASTR.New) + def visit(self, node: AST.New): + error = self.get_se_handler(node) + return tuple([ + self.get_type(node.item, error), + ]) + + @visitor.when(AST.Complement) + @visitor.result(ASTR.Complement) + def visit(self, node: AST.Complement): + return tuple([ + self.visit(node.item), + ]) + + @visitor.when(AST.Neg) + @visitor.result(ASTR.Neg) + def visit(self, node: AST.Neg): + return tuple([ + self.visit(node.item), + ]) + + @visitor.when(AST.Id) + @visitor.result(ASTR.Id) + def visit(self, node: AST.Id): + return tuple([ + node.item, + ]) + + @visitor.when(AST.Int) + @visitor.result(ASTR.Int) + def visit(self, node: AST.Int): + return node.item, + + @visitor.when(AST.Bool) + @visitor.result(ASTR.Bool) + def visit(self, node: AST.Bool): + return node.item, + + @visitor.when(AST.Str) + @visitor.result(ASTR.Str) + def visit(self, node: AST.Str): + return node.item, diff --git a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py new file mode 100644 index 000000000..6d24d97ff --- /dev/null +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py @@ -0,0 +1,159 @@ +class Node: + def __init__(self, static_type = None) -> None: + self.static_type = static_type + + def get_pos_to_error(self, lineno, index): + self.lineno = lineno + self.index = index + +#################################################################### +class Program(Node): + def __init__(self, class_list) -> None: + self.class_list = class_list + +class CoolClass(Node): + def __init__(self, typee, parent_typee, feature_list) -> None: + self.type = typee + self.parent_type = parent_typee + self.feature_list = feature_list + +###################################################################### +class Feature(Node): + pass + +class AtrDef(Feature): + def __init__(self, name, atype, expr) -> None: + self.name = name + self.type = atype + self.expr = expr + +class FuncDef(Feature): + def __init__(self, name, param_list, return_type, expr) -> None: + self.name = name + self.params = param_list + self.return_type = return_type + self.expr = expr + +######################################################################## +class Expresion(Node): + pass + +class CastingDispatch(Expresion): + + def __init__(self, expr, atype, idf, params, static_type) -> None: + super().__init__(static_type) + self.expr = expr + self.type = atype + self.id = idf + self.params = params + +class Dispatch(Expresion): + def __init__(self, expr, idf, params, static_type) -> None: + super().__init__(static_type) + self.expr = expr + self.id = idf + self.params = params + +class StaticDispatch(Expresion): + def __init__(self, idf, params, static_type) -> None: + super().__init__(static_type) + self.id = idf + self.params = params + +####################################################################### +class Statement(Expresion): + pass + +class Assing(Statement): + def __init__(self, name, expr, static_type) -> None: + super().__init__(static_type) + self.id = name + self.expr = expr + +class IfThenElse(Statement): + def __init__(self, condition, then_expr, else_expr, static_type) -> None: + super().__init__(static_type) + self.condition = condition + self.then_expr = then_expr + self.else_expr = else_expr + +class While(Statement): + def __init__(self, condition, loop_expr, static_type) -> None: + super().__init__(static_type) + self.condition = condition + self.loop_expr = loop_expr + +class Block(Statement): + def __init__(self, expr_list, static_type) -> None: + super().__init__(static_type) + self.expr_list = expr_list + +class LetIn(Statement): + def __init__(self, assing_list, expr, static_type) -> None: + super().__init__(static_type) + self.assing_list = assing_list + self.expr = expr + +class Case(Statement): + def __init__(self, expr, case_list, static_type) -> None: + super().__init__(static_type) + self.case_list = case_list + self.expr = expr + +################################################################## +class Binary(Expresion): + def __init__(self, left, right, static_type) -> None: + super().__init__(static_type) + self.left = left + self.right = right + +class Sum(Binary): + pass + +class Rest(Binary): + pass + +class Mult(Binary): + pass + +class Div(Binary): + pass + +class Less(Binary): + pass + +class LessOrEquals(Binary): + pass + +class Equals(Binary): + pass + +########################################################### +class Atomic(Expresion): + def __init__(self, item, static_type) -> None: + super().__init__(static_type) + self.item = item + +class Void(Atomic): + pass + +class New(Atomic): + pass + +class Complement(Atomic): + pass + +class Neg(Atomic): + pass + +class Id(Atomic): + pass + +class Int(Atomic): + pass + +class Str(Atomic): + pass + +class Bool(Atomic): + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py new file mode 100644 index 000000000..5068834f1 --- /dev/null +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -0,0 +1,423 @@ +from os import name +from cool_compiler.types.cool_type_build_in_manager import CoolTypeBuildInManager +from ..tools import VisitBase, parent_common +from ...cmp import visitor +from ..__dependency import SemanticError, Object, ErrorType, Int, Bool, Str +from ..v1_create_type import create_type_ast as AST +from . import semantic_checking_ast as ASTR +from ...cmp.scope import Scope + + +CoolInt = CoolTypeBuildInManager().find("Int") +CoolBool = CoolTypeBuildInManager().find("Bool") +CoolStr = CoolTypeBuildInManager().find("String") + +class CoolSemanticChecking(VisitBase): + def __init__(self, errors) -> None: + super().__init__(errors) + + @visitor.on("node") + def visit(node, scope): + pass + + @visitor.when(AST.Program) + @visitor.result(ASTR.Program) + def visit(self, node : AST.Program, scope = Scope()) : + return self.visit_all(node.class_list, scope), + + @visitor.when(AST.CoolClass) + @visitor.result(ASTR.CoolClass) + def visit(self, node : AST.CoolClass, scope: Scope) : + cls_scope : Scope = scope.create_child(f"Class {node.type.name}") + self.current_type = node.type + error_handler = self.get_se_handler(node) + + if node.parent_type.conforms_to(node.type): + error_handler().add_semantic_error(f"class {self.current_type.name} has circular inheritance") + + cls_scope.define_variable('self', self.current_type) + for name, a_type in node.type.ite_attributes: + if not cls_scope.is_local(name): + cls_scope.define_variable(name, a_type) + + feature_list = self.visit_all(node.feature_list, cls_scope) + return node.type, node.parent_type, feature_list + + @visitor.when(AST.AtrDef) + @visitor.result(ASTR.AtrDef) + def visit(self, node: AST.AtrDef, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + try: + attr = self.current_type.parent.get_attribute(node.name) + if not self.type_checking(attr.type, node.type): + error_handler().add_semantic_error(f"the {node.name} attribute breaks the polymorphism rule") + except SemanticError as se: + pass + + expr = self.visit(node.expr, scope) + if expr and not self.type_checking(node.type, expr.static_type): + error_handler().add_type_error(f"can't save {expr.static_type.name} into {node.type.name}") + + return node.name, node.type, expr + + @visitor.when(AST.FuncDef) + @visitor.result(ASTR.FuncDef) + def visit(self, node: AST.FuncDef, scope : Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + try: + func = self.current_type.parent.get_method(node.name) + + if len(func.params) != len(node.params): + error_handler().add_semantic_error(f"the {node.name} function breaks the polymorphism rule because parmas number") + + for tuple_param_node, tuple_param_func in zip(node.params, func.params): + name, t_params = tuple_param_node + _, t_base_params = tuple_param_func + if not self.type_checking(t_base_params, t_params): + error_handler().add_semantic_error(f"the {name} parameters of the {node.name} function breaks the polymorphism rule") + + if not self.type_checking(func.return_type, node.return_type): + error_handler().add_semantic_error(f"the {node.name} function breaks the polymorphism rule") + except SemanticError as se: + pass + + new_scope : Scope = scope.create_child(f"Func {node.name}") + for param, p_type in node.params: + new_scope.define_variable(param, p_type) + + expr = self.visit(node.expr, new_scope) + if not self.type_checking(node.return_type, expr.static_type): + error_handler().add_type_error(f"Can't return {expr.static_type.name} where method in definition return {node.return_type.name}") + + return node.name, node.params, node.return_type, expr + + @visitor.when(AST.CastingDispatch) + @visitor.result(ASTR.CastingDispatch) + def visit(self, node: AST.CastingDispatch, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + expr = self.visit(node.expr, scope) + if not self.type_checking(node.type, expr.static_type): + error_handler().add_type_error(node.type.name, expr.static_type.name ) + + params = [] + for p in node.params: + params.append(self.visit(p,scope)) + + static_type = ErrorType() + try: + func = node.type.get_method(node.id) + if len(func.params) != len(params): + error_handler().add_semantic_error(f"The method {node.id} called with wrong number of arguments") + + for tupl, exp in zip(func.params, params): + if not self.type_checking(tupl[1], exp.static_type): + error_handler().add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + error_handler().add_attribute_error(node.type.name, node.id ) + + return expr, node.type, node.id, params, expr.static_type.real_type(self.current_type) if static_type.is_self_type else static_type.real_type(self.current_type) + + @visitor.when(AST.Dispatch) + @visitor.result(ASTR.Dispatch) + def visit(self, node: AST.Dispatch, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + expr = self.visit(node.expr, scope) + + params = [] + for p in node.params: + params.append(self.visit(p,scope)) + + static_type = ErrorType() + try: + func = expr.static_type.get_method(node.id) + + if len(func.params) != len(params): + error_handler().add_semantic_error(f"The method {node.id} called with wrong number of arguments") + + for tupl, exp in zip(func.params, params): + if not self.type_checking(tupl[1], exp.static_type): + error_handler().add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + error_handler().add_attribute_error(expr.static_type.name, node.id ) + + return expr, node.id, params, expr.static_type.real_type(self.current_type) if static_type.is_self_type else static_type.real_type(self.current_type) + + @visitor.when(AST.StaticDispatch) + @visitor.result(ASTR.StaticDispatch) + def visit(self, node: AST.StaticDispatch, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + params = [] + for p in node.params: + params.append(self.visit(p,scope)) + + static_type = ErrorType() + try: + func = self.current_type.get_method(node.id) + + if len(func.params) != len(params): + error_handler().add_semantic_error(f"The method {node.id} called with wrong number of arguments") + + for tupl, exp in zip(func.params, params): + if not self.type_checking(tupl[1], exp.static_type): + error_handler().add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + error_handler().add_attribute_error(self.current_type.name, node.id ) + + return node.id, params, static_type.real_type(self.current_type) + + @visitor.when(AST.Assing) + @visitor.result(ASTR.Assing) + def visit(self, node: AST.Assing, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + try: + v = scope.find_variable(node.id) + static_type = v.type + except SemanticError: + error_handler().add_name_error(node.id) + static_type = ErrorType() + + expr = self.visit(node.expr, scope) + if not self.type_checking(static_type, expr.static_type): + error_handler().add_type_error(f"Can't assign {expr.static_type.name} intro {static_type.name}") + + return node.id, expr, expr.static_type.real_type(self.current_type) + + @visitor.when(AST.IfThenElse) + @visitor.result(ASTR.IfThenElse) + def visit(self, node: AST.IfThenElse, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + cond = self.visit(node.condition, scope) + if not self.type_checking(CoolBool, cond.static_type): + error_handler().add_type_error("Bool", cond.static_type.name) + + then_expr = self.visit(node.then_expr, scope) + else_expr = self.visit(node.else_expr, scope) + + return cond, then_expr, else_expr, parent_common(then_expr.static_type, else_expr.static_type).real_type(self.current_type) + + @visitor.when(AST.While) + @visitor.result(ASTR.While) + def visit(self, node: AST.While, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + cond = self.visit(node.condition, scope) + if not self.type_checking(CoolBool, cond.static_type): + error_handler().add_type_error("Bool", cond.static_type.name) + + return cond, self.visit(node.loop_expr, scope), Object() + + @visitor.when(AST.Block) + @visitor.result(ASTR.Block) + def visit(self, node: AST.Block, scope: Scope) -> ASTR.Node: + block_list= [] + for b in node.expr_list: + block_list.append(self.visit(b, scope)) + + return block_list, block_list[-1].static_type.real_type(self.current_type) + + @visitor.when(AST.LetIn) + @visitor.result(ASTR.LetIn) + def visit(self, node: AST.LetIn, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + new_scope = scope.create_child("LetIn") + + assing_list = [] + for name, atype, expr in node.assing_list: + if expr: + exp = self.visit(expr, new_scope) + + if not self.type_checking(atype, exp.static_type): + error_handler().add_type_error(atype.name, exp.static_type.name) + else: exp = None + + assing_list.append((name, atype, exp)) + new_scope.define_variable(name,atype) + + expr = self.visit(node.expr, new_scope) + return assing_list, expr, expr.static_type.real_type(self.current_type) + + @visitor.when(AST.Case) + @visitor.result(ASTR.Case) + def visit(self, node: AST.Case, scope: Scope) -> ASTR.Node: + expr_cond = self.visit(node.expr, scope) + + static_type = None + case_list = [] + for name, atype , expr in node.case_list: + new_scope = scope.create_child(f'Case {name}') + new_scope.define_variable(name, atype) + exp = self.visit(expr, new_scope) + + if static_type is None: static_type = exp.static_type + else: static_type = parent_common(static_type, exp.static_type) + case_list.append((name, atype, exp)) + + return expr_cond, case_list, static_type.real_type(self.current_type) + + @visitor.when(AST.Sum) + @visitor.result(ASTR.Sum) + def visit(self, node: AST.Sum, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolInt + + @visitor.when(AST.Rest) + @visitor.result(ASTR.Rest) + def visit(self, node: AST.Rest, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolInt + + @visitor.when(AST.Mult) + @visitor.result(ASTR.Mult) + def visit(self, node: AST.Mult, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolInt + + @visitor.when(AST.Div) + @visitor.result(ASTR.Div) + def visit(self, node: AST.Div, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolInt + + @visitor.when(AST.Less) + @visitor.result(ASTR.Less) + def visit(self, node: AST.Less, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolBool + + @visitor.when(AST.LessOrEquals) + @visitor.result(ASTR.LessOrEquals) + def visit(self, node: AST.LessOrEquals, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + left = self.visit(node.left, scope) + if not self.type_checking(CoolInt, left.static_type): + error_handler().add_type_error("Int", left.static_type.name) + + right = self.visit(node.right, scope) + if not self.type_checking(CoolInt, right.static_type): + error_handler().add_type_error("Int", right.static_type.name) + + return left, right, CoolBool + + @visitor.when(AST.Equals) + @visitor.result(ASTR.Equals) + def visit(self, node: AST.Equals, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + list_type = [ CoolInt, CoolBool, CoolStr] + + if left.static_type in list_type or right.static_type in list_type: + if not left.static_type == right.static_type: + error_handler().add_type_error(left.static_type.name, right.static_type.name) + + return left, right, CoolBool + + @visitor.when(AST.Void) + @visitor.result(ASTR.Void) + def visit(self, node: AST.Void, scope: Scope) -> ASTR.Node: + return self.visit(node.item, scope), CoolBool + + @visitor.when(AST.New) + @visitor.result(ASTR.New) + def visit(self, node: AST.New, scope: Scope) -> ASTR.Node: + return node.item, node.item + + @visitor.when(AST.Complement) + @visitor.result(ASTR.Complement) + def visit(self, node: AST.Complement, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + expr = self.visit(node.item, scope) + if not self.type_checking(CoolInt, expr.static_type): + error_handler().add_type_error("Int", expr.static_type.name) + return expr, CoolInt + + @visitor.when(AST.Neg) + @visitor.result(ASTR.Neg) + def visit(self, node: AST.Neg, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + expr = self.visit(node.item, scope) + if not self.type_checking(CoolBool, expr.static_type): + error_handler().add_type_error("Bool", expr.static_type.name) + return expr, CoolBool + + @visitor.when(AST.Id) + @visitor.result(ASTR.Id) + def visit(self, node: AST.Id, scope: Scope) -> ASTR.Node: + error_handler = self.get_se_handler(node) + + try: + v = scope.find_variable(node.item) + return node.item, v.type + except AttributeError: pass + except SemanticError: pass + + error_handler().add_name_error(node.item) + return node.item, ErrorType() + + @visitor.when(AST.Int) + @visitor.result(ASTR.Int) + def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: + return node.item, CoolInt + + @visitor.when(AST.Bool) + @visitor.result(ASTR.Bool) + def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: + return node.item, CoolBool + + @visitor.when(AST.Str) + @visitor.result(ASTR.Str) + def visit(self, node: AST.Str, scope: Scope) -> ASTR.Node: + return node.item, CoolStr \ No newline at end of file diff --git a/src/cool_compiler/types/__init__.py b/src/cool_compiler/types/__init__.py new file mode 100755 index 000000000..77c276552 --- /dev/null +++ b/src/cool_compiler/types/__init__.py @@ -0,0 +1,4 @@ +from .type import * +from .build_in_types import * +from .error_type import ErrorType +from .cool_type_build_in_manager import CoolTypeBuildInManager \ No newline at end of file diff --git a/src/cool_compiler/types/build_in_types/__init__.py b/src/cool_compiler/types/build_in_types/__init__.py new file mode 100755 index 000000000..e427adaa9 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/__init__.py @@ -0,0 +1,9 @@ +from .bool import Bool +from .int import Int +from .str import String + + +from .self import Self +from .object import Object +from .io import IO + diff --git a/src/cool_compiler/types/build_in_types/bool.py b/src/cool_compiler/types/build_in_types/bool.py new file mode 100755 index 000000000..1031c2ed2 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/bool.py @@ -0,0 +1,16 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type +from ..tools import type_body_def + +@build_in_type +class Bool(Type): + def __init__(self): + super().__init__("Bool") + type_body_def(self) + + @property + def is_shield(self): + return True + + def value(self): + self.define_attribute("value", self) \ No newline at end of file diff --git a/src/cool_compiler/types/build_in_types/int.py b/src/cool_compiler/types/build_in_types/int.py new file mode 100755 index 000000000..8391a6510 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/int.py @@ -0,0 +1,16 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type +from ..tools import type_body_def + +@build_in_type +class Int(Type): + def __init__(self): + super().__init__("Int") + type_body_def(self) + + @property + def is_shield(self): + return True + + def value(self): + self.define_attribute("value", self) \ No newline at end of file diff --git a/src/cool_compiler/types/build_in_types/io.py b/src/cool_compiler/types/build_in_types/io.py new file mode 100755 index 000000000..052fbb50c --- /dev/null +++ b/src/cool_compiler/types/build_in_types/io.py @@ -0,0 +1,21 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type +from ..tools import type_body_def +from . import * +@build_in_type +class IO(Type): + def __init__(self): + super().__init__("IO") + type_body_def(self) + + def out_string(self): + self.define_method("out_string", [("x", String())], Self()) + + def out_int(self): + self.define_method("out_int", [("x", Int())], Self()) + + def in_string(self): + self.define_method("in_string", [], String()) + + def in_int(self): + self.define_method("in_int", [], Int()) diff --git a/src/cool_compiler/types/build_in_types/object.py b/src/cool_compiler/types/build_in_types/object.py new file mode 100755 index 000000000..ff9921a7f --- /dev/null +++ b/src/cool_compiler/types/build_in_types/object.py @@ -0,0 +1,19 @@ +from ..cool_type_build_in_manager import build_in_type, OBJECT_NAME +from ..type import Type +from ..tools import type_body_def +from . import * + +@build_in_type +class Object(Type): + def __init__(self): + super().__init__(OBJECT_NAME) + type_body_def(self) + + def copy(self): + self.define_method("copy", [], Self()) + + def abort(self): + self.define_method("abort", [], self ) + + def type_name(self): + self.define_method("type_name", [], String()) \ No newline at end of file diff --git a/src/cool_compiler/types/build_in_types/self.py b/src/cool_compiler/types/build_in_types/self.py new file mode 100755 index 000000000..433be9786 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/self.py @@ -0,0 +1,18 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type + +@build_in_type +class Self(Type): + def __init__(self): + super().__init__("SELF_TYPE") + + @property + def is_shield(self): + return True + + @property + def is_self_type(self): + return True + + def real_type(self, possible): + return possible \ No newline at end of file diff --git a/src/cool_compiler/types/build_in_types/str.py b/src/cool_compiler/types/build_in_types/str.py new file mode 100755 index 000000000..d3ceae608 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/str.py @@ -0,0 +1,27 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type +from ..tools import type_body_def +from . import * + +@build_in_type +class String(Type): + def __init__(self): + super().__init__("String") + type_body_def(self) + + @property + def is_shield(self): + return True + + def value(self): + self.define_attribute("value", self) + + def length(self): + self.define_method("length", [], Int()) + + def concat(self): + self.define_method("concat", [("s", self)], self) + + def substr(self): + self.define_method("substr", [("i", Int()), ("l", Int())], self ) + diff --git a/src/cool_compiler/types/cool_type_build_in_manager.py b/src/cool_compiler/types/cool_type_build_in_manager.py new file mode 100755 index 000000000..4bd48be1d --- /dev/null +++ b/src/cool_compiler/types/cool_type_build_in_manager.py @@ -0,0 +1,41 @@ +from .tools import SemanticError +import inspect + +OBJECT_NAME = 'Object' + +def type_body_def(cls): + for n, f in inspect.getmembers(cls, predicate=inspect.ismethod): + if n == '__init__': continue + if n in cls.__dict__: f() + +class Singleton(type): + _instances = None + def __call__(cls, *args, **kwargs): + if cls._instances is None: + cls._instances = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instances + +def build_in_type(cls): + manager = CoolTypeBuildInManager() + manager.dictt[cls.__name__] = cls() + return cls + +class CoolTypeBuildInManager(metaclass=Singleton): + def __init__(self) -> None: + self.dictt = {} + + def all_inherence_of_object(self): + obj = self.dictt[OBJECT_NAME] + + for key in self.dictt.keys(): + if key != OBJECT_NAME and self.dictt[key].parent is None: + self.dictt[key].parent = obj + + def __iter__(self): + return self.dictt.__iter__() + + def find(self, name:str): + try: + return self.dictt[name] + except KeyError: + raise SemanticError(f'Type "{name}" is not defined.') \ No newline at end of file diff --git a/src/cool_compiler/types/error_type.py b/src/cool_compiler/types/error_type.py new file mode 100755 index 000000000..b33d94788 --- /dev/null +++ b/src/cool_compiler/types/error_type.py @@ -0,0 +1,18 @@ +from .type import Type + +class ErrorType(Type): + def __init__(self): + Type.__init__(self, '') + + def conforms_to(self, other): + return True + + def bypass(self): + return True + + @property + def is_error_type(self): + return True + + def __eq__(self, other): + return isinstance(other, Type) \ No newline at end of file diff --git a/src/cool_compiler/types/tools.py b/src/cool_compiler/types/tools.py new file mode 100755 index 000000000..006fb02a8 --- /dev/null +++ b/src/cool_compiler/types/tools.py @@ -0,0 +1,35 @@ +class SemanticError(Exception): + @property + def text(self): + return self.args[0] + +class Attribute: + def __init__(self, name, typex): + self.name = name + self.type = typex + + def __str__(self): + return f'[attrib] {self.name} : {self.type.name};' + + def __repr__(self): + return str(self) + +class Method: + def __init__(self, name, params, return_type): + self.name = name + self.params = params + self.return_type = return_type + + def __str__(self): + params = ', '.join(f'{n}:{t.name}' for n,t in self.params) + return f'[method] {self.name}({params}): {self.return_type.name};' + + def __eq__(self, other): + return other.name == self.name and \ + other.param_types == self.param_types + +import inspect +def type_body_def(cls): + for n, f in inspect.getmembers(cls, predicate=inspect.ismethod): + if n == '__init__': continue + if n in cls.__class__.__dict__: f() diff --git a/src/cool_compiler/types/type.py b/src/cool_compiler/types/type.py new file mode 100755 index 000000000..63c3ba0d2 --- /dev/null +++ b/src/cool_compiler/types/type.py @@ -0,0 +1,136 @@ +from collections import OrderedDict +from .tools import * + + +class Type: + def __init__(self, name:str): + self.name = name + self.attributes = [] + self.methods = [] + self.parent = None + + @property + def is_shield(self): + return False + + @property + def is_self_type(self): + return False + + @property + def is_auto_type(self): + return False + + @property + def is_error_type(self): + return False + + def bypass(self): + return False + + + def real_type(self, possible): + return self + + def conforms_to(self, other): + return other.bypass() or self == other or self.parent is not None and self.parent.conforms_to(other) + + def __eq__(self,other): + return other.name == self.name +################################################################################################################# + @property + def ite_attributes(self): + for attr in self.attributes: + yield attr.name, attr.type + if not self.parent is None: + for attr in self.parent.ite_attributes: + yield attr + + def set_parent(self, parent): + if self.parent is not None: + raise SemanticError(f'Parent type is already set for {self.name}.') + self.parent = parent + + def get_attribute(self, name:str) -> Attribute: + try: + return next(attr for attr in self.attributes if attr.name == name) + + except StopIteration: + if self.parent is None: + raise SemanticError(f'Attribute "{name}" is not defined in {self.name}.') + try: + return self.parent.get_attribute(name) + except SemanticError: + raise SemanticError(f'Attribute "{name}" is not defined in {self.name}.') + + def define_attribute(self, name:str, typex): + if name == "self": + raise SemanticError("Can't define attribute with name self") + try: + self.get_attribute(name) + except SemanticError: + attribute = Attribute(name, typex) + self.attributes.append(attribute) + return attribute + else: + raise SemanticError(f'Attribute "{name}" is already defined in {self.name}.') + + def get_method(self, name:str) -> Method: + try: + return next(method for method in self.methods if method.name == name) + + except StopIteration: + if self.parent is None: + raise SemanticError(f'Method "{name}" is not defined in {self.name}.') + try: + return self.parent.get_method(name) + except SemanticError: + raise SemanticError(f'Method "{name}" is not defined in {self.name}.') + + def define_method(self, name:str, params:list, return_type): + if name in (method.name for method in self.methods): + raise SemanticError(f'Method "{name}" already defined in {self.name}') + + names = ['self'] + for _name, _t in params: + if _name in names: + raise SemanticError(f"Formal parameter a is multiply defined") + names.append(_name) + + method = Method(name, params, return_type) + self.methods.append(method) + return method + + def all_attributes(self, clean=True): + plain = OrderedDict() if self.parent is None else self.parent.all_attributes(False) + for attr in self.attributes: + plain[attr.name] = (attr, self) + return plain.values() if clean else plain + + def all_methods(self, clean=True): + plain = OrderedDict() if self.parent is None else self.parent.all_methods(False) + for method in self.methods: + plain[method.name] = (method, self) + return plain.values() if clean else plain + + + + def __str__(self): + output = f'type {self.name}' + parent = '' if self.parent is None else f' : {self.parent.name}' + output += parent + output += ' {' + output += '\n\t' if self.attributes or self.methods else '' + output += '\n\t'.join(str(x) for x in self.attributes) + output += '\n\t' if self.attributes else '' + output += '\n\t'.join(str(x) for x in self.methods) + output += '\n' if self.methods else '' + output += '}\n' + return output + + def __repr__(self): + return str(self) + + + + \ No newline at end of file diff --git a/src/coolc.sh b/src/coolc.sh index 3088de4f9..83bf211e0 100755 --- a/src/coolc.sh +++ b/src/coolc.sh @@ -8,4 +8,5 @@ echo "LINEA_CON_NOMBRE_Y_VERSION_DEL_COMPILADOR" # TODO: Recuerde cambiar echo "Copyright (c) 2019: Nombre1, Nombre2, Nombre3" # TODO: líneas a los valores correctos # Llamar al compilador -echo "Compiling $INPUT_FILE into $OUTPUT_FILE" +python -m cool_compiler $INPUT_FILE $OUTPUT_FILE +#echo "Compiling $INPUT_FILE into $OUTPUT_FILE" diff --git a/src/makefile b/src/makefile old mode 100644 new mode 100755 index 30df993f5..7ad327735 --- a/src/makefile +++ b/src/makefile @@ -1,7 +1,7 @@ .PHONY: clean main: - # Compiling the compiler :) + rm -rf test.mips && python -m cool_compiler test.cl clean: rm -rf build/* @@ -10,3 +10,20 @@ clean: test: pytest ../tests -v --tb=short -m=${TAG} +cool_compiler: + python3.8 -m cool_compiler + +codegen: + python3.8 cool_compiler/codegen/__main__.py + +lexer: + python3.8 cool_compiler/lexer/__main__.py + +parser: + python3.8 cool_compiler/parser/__main__.py + +semantic: + python3.8 cool_compiler/semantic/__main__.py + +exec: + spim -file test.mips \ No newline at end of file diff --git a/src/test.cl b/src/test.cl new file mode 100755 index 000000000..7b8bf3363 --- /dev/null +++ b/src/test.cl @@ -0,0 +1,381 @@ +(* + * Cool program reading descriptions of weighted directed graphs + * from stdin. It builds up a graph objects with a list of vertices + * and a list of edges. Every vertice has a list of outgoing edges. + * + * INPUT FORMAT + * Every line has the form vertice successor* + * Where vertice is an int, and successor is vertice,weight + * + * An empty line or EOF terminates the input. + * + * The list of vertices and the edge list is printed out by the Main + * class. + * + * TEST + * Once compiled, the file g1.graph can be fed to the program. + * The output should look like this: + +nautilus.CS.Berkeley.EDU 53# spim -file graph.s _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 8($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $v0, 8($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Parse_read_input: # +#Parametro self en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var g stackpointer 52 +addi $sp, $sp, -4 #Push local var new_Graph@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var line stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_add_vertice@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_parse_line@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_add_vertice@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_and@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_and@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_and@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_read_input +#Eval Expression to Let g +#Creando instancia de tipo Graph +#Allocate a una class Graph +#atributo type_name en puntero + 0 +#atributo vertices en puntero + 4 +#atributo edges en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 48($sp) #Guardando en la variable local new_Graph@0 puntero de la instancia de la clase Graph +#Assignacion de la insformacion de tipo a la instancia +la $t0, Graph # +move $s4, $t0 # +lw $t0, 48($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 48($sp) #Lee el valor de la var new_Graph@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Graph@0 +jal new_ctr_Graph # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let g +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let line +#StaticDispatch in_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +sw $v0, 44($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let line +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch add_vertice +#Get Local Var g +lw $t0, 52($sp) # +sw $t0, 40($sp) # +#Fin de la exprecion previa al DinamicDispatch add_vertice +#Evalua el parametro 0 para el CastingDispatch add_vertice +#StaticDispatch parse_line +#Evalua el parametro 0 para el CastingDispatch parse_line +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch parse_line +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 40($sp) #Lee el valor de la var param_0_to_parse_line@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_parse_line@0 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion parse_line +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch add_vertice +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_add_vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_add_vertice@0 +lw $t0, 36($sp) #Lee el valor de la var param_0_to_add_vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_add_vertice@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Graph +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion add_vertice +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable line +#StaticDispatch in_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 44($sp) # +lw $t0, 44($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evalua la Expresion para el DinamicDispatch and +#Get Self Property boolop +lw $t0, 56($sp) #Instancia de la clase Parse +lw $t1, 4($t0) #Lee la propiedad boolop +sw $t1, 28($sp) #Guarda el valor de la propiedad boolop en la variable local instance_dynamic_to_and@0 +#Fin de la exprecion previa al DinamicDispatch and +#Evalua el parametro 0 para el CastingDispatch and +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 56($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +sw $v0, 16($sp) # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch and +#Evalua el parametro 1 para el CastingDispatch and +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 56($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +sw $v0, 4($sp) # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch and +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_and@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_and@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_and@0 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de BoolOp +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion and +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 56($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var g +lw $t0, 52($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 60 # +jr $ra # + +Graph_print_V: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_print_V +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property vertices +lw $t0, 8($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +sw $t1, 4($sp) #Guarda el valor de la propiedad vertices en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Graph_print_E: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_print_E +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property edges +lw $t0, 8($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +sw $t1, 4($sp) #Guarda el valor de la propiedad edges en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_BoolOp: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_BoolOp +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Graph: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var new_VList@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var new_EList@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Graph +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +#Assignando el resultado de la expression al atributo vertices de la clase Graph +#Creando instancia de tipo VList +#Allocate a una class VList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 8($sp) #Guardando en la variable local new_VList@0 puntero de la instancia de la clase VList +#Assignacion de la insformacion de tipo a la instancia +la $t0, VList # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 8($sp) #Lee el valor de la var new_VList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_VList@0 +jal new_ctr_VList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 12($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded vertices +sw $t1, 4($t0) #Setea la propiedad vertices con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo edges de la clase Graph +#Creando instancia de tipo EList +#Allocate a una class EList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_EList@0 puntero de la instancia de la clase EList +#Assignacion de la insformacion de tipo a la instancia +la $t0, EList # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_EList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_EList@0 +jal new_ctr_EList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 12($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded edges +sw $t1, 8($t0) #Setea la propiedad edges con el valor de _ +#Fin De la Asignacion +lw $v0, 12($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +IO_in_string: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_string +lw $s6, 4($sp) #Guarda self +jal __str__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Parse_parse_line: # +#Parametro self en stackpoiner + 88 +#Parametro s@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var v stackpointer 80 +addi $sp, $sp, -4 #Push local var new_Vertice@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var succ stackpointer 60 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@1 stackpointer 56 +addi $sp, $sp, -4 #Push local var weight stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@2 stackpointer 48 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_add_out@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var new_Edge@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_number@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_init@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_2_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_add_out@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_parse_line +#Eval Expression to Let v +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Vertice +#Allocate a una class Vertice +#atributo type_name en puntero + 0 +#atributo num en puntero + 4 +#atributo out en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 76($sp) #Guardando en la variable local new_Vertice@0 puntero de la instancia de la clase Vertice +#Assignacion de la insformacion de tipo a la instancia +la $t0, Vertice # +move $s4, $t0 # +lw $t0, 76($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 76($sp) #Lee el valor de la var new_Vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Vertice@0 +jal new_ctr_Vertice # +sw $v0, 72($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Local Var s +lw $t0, 84($sp) # +sw $t0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 72($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch init +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 68($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let v +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Inicio de un While +j while_cond_1 # +while_back_1: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let succ +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 56($sp) #Guarda el valor de la propiedad rest en la variable local param_0_to_a2i@1 +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) #Lee el valor de la var param_0_to_a2i@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@1 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let succ +#Eval Expression to Let weight +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 48($sp) #Guarda el valor de la propiedad rest en la variable local param_0_to_a2i@2 +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 52($sp) #Lee el valor de la var param_0_to_a2i@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@2 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let weight +#Evalua la Expresion para el DinamicDispatch add_out +#Get Local Var v +lw $t0, 80($sp) # +sw $t0, 44($sp) # +#Fin de la exprecion previa al DinamicDispatch add_out +#Evalua el parametro 0 para el CastingDispatch add_out +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Edge +#Allocate a una class Edge +#atributo type_name en puntero + 0 +#atributo from en puntero + 4 +#atributo to en puntero + 8 +#atributo weight en puntero + 12 +li $a0, 16 # +li $v0, 9 # +syscall +sw $v0, 40($sp) #Guardando en la variable local new_Edge@0 puntero de la instancia de la clase Edge +#Assignacion de la insformacion de tipo a la instancia +la $t0, Edge # +move $s4, $t0 # +lw $t0, 40($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 40($sp) #Lee el valor de la var new_Edge@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Edge@0 +jal new_ctr_Edge # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Evalua la Expresion para el DinamicDispatch number +#Get Local Var v +#Fin de la exprecion previa al DinamicDispatch number +lw $t0, 80($sp) #Lee el valor de la var v +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con v +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion number +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var succ +lw $t0, 60($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 1 al CastingDispatch init +#Evalua el parametro 2 para el CastingDispatch init +#Get Local Var weight +lw $t0, 52($sp) # +sw $t0, 20($sp) # +#Fin del paramentro 2 al CastingDispatch init +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@1 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@1 +lw $t0, 32($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 32($sp) #Lee el valor de la var param_2_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_2_to_init@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch add_out +lw $t0, 44($sp) #Lee el valor de la var instance_dynamic_to_add_out@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_add_out@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_add_out@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_add_out@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion add_out +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 4($sp) #Guarda el valor de la propiedad rest en la variable local instance_dynamic_to_length@0 +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_length@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_length@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 88($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var v +lw $t0, 80($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +Graph_add_vertice: # +#Parametro self en stackpoiner + 28 +#Parametro v@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_outgoing@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_append@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_append@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_add_vertice +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable edges +#Evalua la Expresion para el DinamicDispatch append +#Evalua la Expresion para el DinamicDispatch outgoing +#Get Local Var v +#Fin de la exprecion previa al DinamicDispatch outgoing +lw $t0, 24($sp) #Lee el valor de la var v@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con v@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion outgoing +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch append +#Evalua el parametro 0 para el CastingDispatch append +#Get Self Property edges +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +sw $t1, 12($sp) #Guarda el valor de la propiedad edges en la variable local param_0_to_append@0 +#Fin del paramentro 0 al CastingDispatch append +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_append@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_append@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion append +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 28($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded edges +sw $t1, 8($t0) #Setea la propiedad edges con el valor de _ +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +move $s4, $t1 #Guarda el valor de la propiedad edges en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable vertices +#Evalua la Expresion para el DinamicDispatch cons +#Get Self Property vertices +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +sw $t1, 8($sp) #Guarda el valor de la propiedad vertices en la variable local instance_dynamic_to_cons@0 +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var v +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 28($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded vertices +sw $t1, 4($t0) #Setea la propiedad vertices con el valor de _ +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +move $s4, $t1 #Guarda el valor de la propiedad vertices en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +BoolOp_and: # +#Parametro self en stackpoiner + 12 +#Parametro b1@0 en stackpoiner + 8 +#Parametro b2@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion BoolOp_and +#Evalua la condicion de un If +#Get Local Var b1 +lw $t0, 8($sp) # +move $s4, $t0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_BoolOp_and_0 # +#Else case +li $s4, 0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_BoolOp_and_0 # +then_BoolOp_and_0: +#Then case +#Get Local Var b2 +lw $t0, 4($sp) # +move $s4, $t0 # +fin_BoolOp_and_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Vertice_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property num +lw $t0, 12($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +sw $t1, 8($sp) #Guarda el valor de la propiedad num en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property out +lw $t0, 12($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +sw $t1, 4($sp) #Guarda el valor de la propiedad out en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Edge_print: # +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Edge_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property from +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 4($t0) #Lee la propiedad from +sw $t1, 20($sp) #Guarda el valor de la propiedad from en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property to +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 8($t0) #Lee la propiedad to +sw $t1, 12($sp) #Guarda el valor de la propiedad to en la variable local param_0_to_out_int@1 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_int@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 5 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property weight +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 12($t0) #Lee la propiedad weight +sw $t1, 4($sp) #Guarda el valor de la propiedad weight en la variable local param_0_to_out_int@2 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_int@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +EList_print: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_print +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +ECons_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property car +lw $t0, 12($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +sw $t1, 8($sp) #Guarda el valor de la propiedad car en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cdr +lw $t0, 12($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +sw $t1, 4($sp) #Guarda el valor de la propiedad cdr en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +VList_print: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_print +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +VCons_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property car +lw $t0, 12($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +sw $t1, 8($sp) #Guarda el valor de la propiedad car en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cdr +lw $t0, 12($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +sw $t1, 4($sp) #Guarda el valor de la propiedad cdr en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_VList: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_VList +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase VList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_EList: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_EList +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase EList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Vertice: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var new_EList@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Vertice +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded num +sw $t1, 4($t0) #Setea la propiedad num con el valor de _ +#Assignando el resultado de la expression al atributo out de la clase Vertice +#Creando instancia de tipo EList +#Allocate a una class EList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_EList@0 puntero de la instancia de la clase EList +#Assignacion de la insformacion de tipo a la instancia +la $t0, EList # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_EList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_EList@0 +jal new_ctr_EList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 8($t0) #Setea la propiedad out con el valor de _ +#Fin De la Asignacion +lw $v0, 8($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Parse_a2i: # +#Parametro self en stackpoiner + 120 +#Parametro s@0 en stackpoiner + 116 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_a2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 112($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 108($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 108($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 92($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 88($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 84($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 92($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 100($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_17 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 96($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 100($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 96($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 72($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_18 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_2 # +#Else case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 64($sp) #Lee el valor de la var param_0_to_a2i_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Parse_a2i_2 # +then_Parse_a2i_2: +#Then case +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 56($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 36($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 56($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 44($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Parse_a2i_2: +#Fin de un If +j fin_Parse_a2i_1 # +then_Parse_a2i_1: +#Then case +#Evaluando la expression de una operacion unaria +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 16($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_a2i_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@1 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#FIN expression de una operacion unaria +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +fin_Parse_a2i_1: +#Fin de un If +j fin_Parse_a2i_0 # +then_Parse_a2i_0: +#Then case +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_a2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 124 # +jr $ra # + +Parse_a2i_aux: # +#Parametro self en stackpoiner + 192 +#Parametro s@0 en stackpoiner + 188 +addi $sp, $sp, -4 #Push local var int stackpointer 184 +addi $sp, $sp, -4 #Push local var j stackpointer 180 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 176 +addi $sp, $sp, -4 #Push local var i stackpointer 172 +addi $sp, $sp, -4 #Push local var c stackpointer 168 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 164 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 160 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 156 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 152 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 148 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 144 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 140 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 136 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 132 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 128 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 124 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 120 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 116 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 112 +addi $sp, $sp, -4 #Push local var param_0_to_c2i@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 104 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 100 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 88 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 84 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 80 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 76 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_a@3 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_b@3 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 36 +addi $sp, $sp, -4 #Push local var rest@_a@2 stackpointer 32 +addi $sp, $sp, -4 #Push local var rest@_b@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_a2i_aux +#Eval Expression to Let int +li $s4, 0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 184($sp) # +#Fin de la asignacion Let int +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let j +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 180($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let j +#Eval Expression to Let i +li $s4, 0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 172($sp) # +#Fin de la asignacion Let i +#Inicio de un While +j while_cond_2 # +while_back_2: +#Eval Expression to Let c +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 164($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 160($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 156($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 164($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 164($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 164($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 176($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 168($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let c +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var c +lw $t0, 168($sp) # +sw $t0, 152($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_19 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 148($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 152($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 148($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var c +lw $t0, 168($sp) # +sw $t0, 144($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_20 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 140($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 144($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 140($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_1 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable int +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var int +lw $t0, 184($sp) # +sw $t0, 128($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 124($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 192($sp) #Guarda self +lw $a0, 128($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 124($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 136($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch c2i +#Evalua el parametro 0 para el CastingDispatch c2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 120($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 116($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 112($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 120($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 120($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 120($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 132($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 108($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch c2i +lw $t0, 192($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 112($sp) #Lee el valor de la var param_0_to_c2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_c2i@0 +lw $t0, 200($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion c2i +jal $t3 # +sw $v0, 132($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 136($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 132($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 184($sp) # +lw $t0, 184($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 104($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 100($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 104($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 100($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 96($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var j +lw $t0, 180($sp) # +sw $t0, 92($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 96($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 92($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_2 # +#Else case +la $t0, string_21 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_Parse_a2i_aux_2 # +then_Parse_a2i_aux_2: +#Then case +#Asignando un nuevo valor a la variable rest +la $t0, string_22 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +fin_Parse_a2i_aux_2: +#Fin de un If +j fin_Parse_a2i_aux_1 # +then_Parse_a2i_aux_1: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rest +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 88($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 84($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 80($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 84($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 80($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 76($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 60($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 60($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 72($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 68($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 52($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 88($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 80($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 60($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 100($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Get Local Var j +lw $t0, 180($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +fin_Parse_a2i_aux_1: +#Fin de un If +j fin_Parse_a2i_aux_0 # +then_Parse_a2i_aux_0: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rest +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 48($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> sum@_a@3 +lw $a1, 40($sp) #Guarda el parametro 1 -> sum@_b@3 +jal __int__sum__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@3 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@3 +jal __int__sub__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> rest@_a@2 +lw $a1, 28($sp) #Guarda el parametro 1 -> rest@_b@2 +jal __int__sub__ # +sw $v0, 12($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 48($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 20($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Get Local Var j +lw $t0, 180($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +fin_Parse_a2i_aux_0: +#Fin de un If +#Fin del cuerpo e inicio de la condicion de un While +while_cond_2: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var j +lw $t0, 180($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 192($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_2 # +#Fin de la condicion de un While +lw $t0, 192($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var int +lw $t0, 184($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 196 # +jr $ra # + +Vertice_init: # +#Parametro self en stackpoiner + 8 +#Parametro n@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable num +#Get Local Var n +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded num +sw $t1, 4($t0) #Setea la propiedad num con el valor de _ +lw $t0, 8($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +move $s4, $t1 #Guarda el valor de la propiedad num en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 8($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Edge_init: # +#Parametro self en stackpoiner + 16 +#Parametro f@0 en stackpoiner + 12 +#Parametro t@0 en stackpoiner + 8 +#Parametro w@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Edge_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable from +#Get Local Var f +lw $t0, 12($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded from +sw $t1, 4($t0) #Setea la propiedad from con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 4($t0) #Lee la propiedad from +move $s4, $t1 #Guarda el valor de la propiedad from en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable to +#Get Local Var t +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded to +sw $t1, 8($t0) #Setea la propiedad to con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 8($t0) #Lee la propiedad to +move $s4, $t1 #Guarda el valor de la propiedad to en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable weight +#Get Local Var w +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded weight +sw $t1, 12($t0) #Setea la propiedad weight con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 12($t0) #Lee la propiedad weight +move $s4, $t1 #Guarda el valor de la propiedad weight en la variable local _ +#Inicio del paso 3 de una sequencia Block +#Get Local Var self +lw $t0, 16($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +ECons_init: # +#Parametro self en stackpoiner + 12 +#Parametro e@0 en stackpoiner + 8 +#Parametro rest@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable car +#Get Local Var e +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase EList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $t0, 12($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable cdr +#Get Local Var rest +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase ECons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +VCons_init: # +#Parametro self en stackpoiner + 12 +#Parametro v@0 en stackpoiner + 8 +#Parametro rest@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable car +#Get Local Var v +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase VList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $t0, 12($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable cdr +#Get Local Var rest +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase VCons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Edge: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Edge +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded from +sw $t1, 4($t0) #Setea la propiedad from con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded to +sw $t1, 8($t0) #Setea la propiedad to con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded weight +sw $t1, 12($t0) #Setea la propiedad weight con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Vertice_number: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_number +#Get Self Property num +lw $t0, 4($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +move $s4, $t1 #Guarda el valor de la propiedad num en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Vertice_add_out: # +#Parametro self en stackpoiner + 16 +#Parametro s@0 en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_add_out +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable out +#Evalua la Expresion para el DinamicDispatch cons +#Get Self Property out +lw $t0, 16($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +sw $t1, 8($sp) #Guarda el valor de la propiedad out en la variable local instance_dynamic_to_cons@0 +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var s +lw $t0, 12($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 16($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 8($t0) #Setea la propiedad out con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 16($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Vertice_outgoing: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_outgoing +#Get Self Property out +lw $t0, 4($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_append: # +#Parametro self en stackpoiner + 28 +#Parametro l@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_isNil@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_append@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_append@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_append +#Evalua la condicion de un If +#Evalua la Expresion para el DinamicDispatch isNil +#Get Local Var self +#Fin de la exprecion previa al DinamicDispatch isNil +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion isNil +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_EList_append_0 # +#Else case +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch append +#StaticDispatch tail +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion tail +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch append +#Evalua el parametro 0 para el CastingDispatch append +#Get Local Var l +lw $t0, 24($sp) # +sw $t0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch append +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_append@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_append@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion append +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#StaticDispatch head +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion head +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_EList_append_0 # +then_EList_append_0: +#Then case +#Get Local Var l +lw $t0, 24($sp) # +move $s4, $t0 # +fin_EList_append_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +EList_cons: # +#Parametro self en stackpoiner + 24 +#Parametro e@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_ECons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_cons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo ECons +#Allocate a una class ECons +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +#atributo cdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_ECons@0 puntero de la instancia de la clase ECons +#Assignacion de la insformacion de tipo a la instancia +la $t0, ECons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_ECons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_ECons@0 +jal new_ctr_ECons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var e +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de ECons +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +VList_cons: # +#Parametro self en stackpoiner + 24 +#Parametro v@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_VCons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_cons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo VCons +#Allocate a una class VCons +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +#atributo cdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_VCons@0 puntero de la instancia de la clase VCons +#Assignacion de la insformacion de tipo a la instancia +la $t0, VCons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_VCons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_VCons@0 +jal new_ctr_VCons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var v +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VCons +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +Parse_c2i: # +#Parametro self en stackpoiner + 88 +#Parametro char@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var str_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_c2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_13 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_14 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_15 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> str_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> str_eq@_b@8 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_16 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@9 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_Parse_c2i_9 # +then_Parse_c2i_9: +#Then case +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_9: +#Fin de un If +j fin_Parse_c2i_8 # +then_Parse_c2i_8: +#Then case +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_8: +#Fin de un If +j fin_Parse_c2i_7 # +then_Parse_c2i_7: +#Then case +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_7: +#Fin de un If +j fin_Parse_c2i_6 # +then_Parse_c2i_6: +#Then case +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_6: +#Fin de un If +j fin_Parse_c2i_5 # +then_Parse_c2i_5: +#Then case +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_5: +#Fin de un If +j fin_Parse_c2i_4 # +then_Parse_c2i_4: +#Then case +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_4: +#Fin de un If +j fin_Parse_c2i_3 # +then_Parse_c2i_3: +#Then case +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_3: +#Fin de un If +j fin_Parse_c2i_2 # +then_Parse_c2i_2: +#Then case +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_2: +#Fin de un If +j fin_Parse_c2i_1 # +then_Parse_c2i_1: +#Then case +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_1: +#Fin de un If +j fin_Parse_c2i_0 # +then_Parse_c2i_0: +#Then case +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +EList_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_isNil +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_isNil +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_isNil +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_isNil +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_tail +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_tail +#Get Self Property cdr +lw $t0, 4($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_tail +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_tail +#Get Self Property cdr +lw $t0, 4($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_head +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_head +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_head +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_head +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_ECons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_ECons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_EList # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase ECons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_VCons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_VCons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_VList # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase VCons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +BoolOp_or: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/src/test.py b/src/test.py new file mode 100644 index 000000000..7b82ff984 --- /dev/null +++ b/src/test.py @@ -0,0 +1 @@ +from cool_compiler import __main__ \ No newline at end of file diff --git a/src/test.s b/src/test.s new file mode 100644 index 000000000..70b92d2cc --- /dev/null +++ b/src/test.s @@ -0,0 +1,16 @@ +.data +bool: .word 1 + + +.text +main: +li $v0 , 1 +li $t0 ,-1 +lw $t2 , bool +addi $t1 , $t2 ,-1 +mul $a0 , $t1 ,-1 # $t0 * $t1 = Hi and Lo registers + +syscall + +li $v0 ,10 +syscall diff --git a/tests/codegen/arith.mips b/tests/codegen/arith.mips new file mode 100644 index 000000000..f8cbef71b --- /dev/null +++ b/tests/codegen/arith.mips @@ -0,0 +1,7076 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +A_parents: .word 1, 7, 0, +A_Name: .asciiz "A" +A: .word A_Name, 2, A_parents, Object_abort, Object_copy, Object_type_name, A_value, A_set_var, A_method1, A_method2, A_method3, A_method4, A_method5, +B_parents: .word 1, 7, 8, 0, +B_Name: .asciiz "B" +B: .word B_Name, 2, B_parents, Object_abort, Object_copy, Object_type_name, A_value, A_set_var, A_method1, A_method2, A_method3, A_method4, B_method5, +C_parents: .word 1, 7, 8, 9, 0, +C_Name: .asciiz "C" +C: .word C_Name, 2, C_parents, Object_abort, Object_copy, Object_type_name, A_value, A_set_var, A_method1, A_method2, A_method3, A_method4, C_method5, C_method6, +D_parents: .word 1, 7, 8, 10, 0, +D_Name: .asciiz "D" +D: .word D_Name, 2, D_parents, Object_abort, Object_copy, Object_type_name, A_value, A_set_var, A_method1, A_method2, A_method3, A_method4, B_method5, D_method7, +E_parents: .word 1, 7, 8, 10, 11, 0, +E_Name: .asciiz "E" +E: .word E_Name, 2, E_parents, Object_abort, Object_copy, Object_type_name, A_value, A_set_var, A_method1, A_method2, A_method3, A_method4, B_method5, D_method7, E_method6, +A2I_parents: .word 1, 12, 0, +A2I_Name: .asciiz "A2I" +A2I: .word A2I_Name, 1, A2I_parents, Object_abort, Object_copy, Object_type_name, A2I_c2i, A2I_i2c, A2I_a2i, A2I_a2i_aux, A2I_i2a, A2I_i2a_aux, +Main_parents: .word 1, 6, 13, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 5, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_menu, Main_prompt, Main_get_int, Main_is_even, Main_class_type, Main_print, Main_main, +string_0: .asciiz "0" +string_1: .asciiz "1" +string_2: .asciiz "2" +string_3: .asciiz "3" +string_4: .asciiz "4" +string_5: .asciiz "5" +string_6: .asciiz "6" +string_7: .asciiz "7" +string_8: .asciiz "8" +string_9: .asciiz "9" +string_10: .asciiz "" +string_11: .asciiz "9" +string_12: .asciiz "8" +string_13: .asciiz "7" +string_14: .asciiz "6" +string_15: .asciiz "5" +string_16: .asciiz "4" +string_17: .asciiz "3" +string_18: .asciiz "2" +string_19: .asciiz "1" +string_20: .asciiz "0" +string_21: .asciiz "-" +string_22: .asciiz "+" +string_23: .asciiz "-" +string_24: .asciiz "0" +string_25: .asciiz "" +string_26: .asciiz "\n To add a number to " +string_27: .asciiz "...enter a:\n" +string_28: .asciiz " To negate " +string_29: .asciiz "...enter b:\n" +string_30: .asciiz " To find the difference between " +string_31: .asciiz "and another number...enter c:\n" +string_32: .asciiz " To find the factorial of " +string_33: .asciiz "...enter d:\n" +string_34: .asciiz " To square " +string_35: .asciiz "...enter e:\n" +string_36: .asciiz " To cube " +string_37: .asciiz "...enter f:\n" +string_38: .asciiz " To find out if " +string_39: .asciiz "is a multiple of 3...enter g:\n" +string_40: .asciiz " To divide " +string_41: .asciiz "by 8...enter h:\n" +string_42: .asciiz " To get a new number...enter j:\n" +string_43: .asciiz " To quit...enter q:\n\n" +string_44: .asciiz "\n" +string_45: .asciiz "Please enter a number... " +string_46: .asciiz "Class type is now E\n" +string_47: .asciiz "Class type is now D\n" +string_48: .asciiz "Class type is now C\n" +string_49: .asciiz "Class type is now B\n" +string_50: .asciiz "Class type is now A\n" +string_51: .asciiz "Oooops\n" +string_52: .asciiz " " +string_53: .asciiz "number " +string_54: .asciiz "is odd!\n" +string_55: .asciiz "is even!\n" +string_56: .asciiz "a" +string_57: .asciiz "b" +string_58: .asciiz "c" +string_59: .asciiz "d" +string_60: .asciiz "e" +string_61: .asciiz "f" +string_62: .asciiz "g" +string_63: .asciiz "h" +string_64: .asciiz "j" +string_65: .asciiz "q" +string_66: .asciiz "number " +string_67: .asciiz "is equal to " +string_68: .asciiz "times 8 with a remainder of " +string_69: .asciiz "\n" +string_70: .asciiz "number " +string_71: .asciiz "is not divisible by 3.\n" +string_72: .asciiz "number " +string_73: .asciiz "is divisible by 3.\n" +string_74: .asciiz "Oooops\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo char en puntero + 4 +#atributo avar en puntero + 8 +#atributo a_var en puntero + 12 +#atributo flag en puntero + 16 +li $a0, 20 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded char +sw $t1, 4($t0) #Setea la propiedad char con el valor de _ +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded a_var +sw $t1, 12($t0) #Setea la propiedad a_var con el valor de _ +#Assignando el resultado de la expression al atributo flag de la clase Main +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded flag +sw $t1, 16($t0) #Setea la propiedad flag con el valor de _ +#Fin De la Asignacion +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 436 +addi $sp, $sp, -4 #Push local var new_A@0 stackpointer 432 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 428 +addi $sp, $sp, -4 #Push local var param_0_to_print@0 stackpointer 424 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@0 stackpointer 420 +addi $sp, $sp, -4 #Push local var param_0_to_is_even@0 stackpointer 416 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 412 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 408 +addi $sp, $sp, -4 #Push local var param_0_to_class_type@0 stackpointer 404 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 400 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 396 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 392 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 388 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 384 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 380 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 376 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 372 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 368 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 364 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 360 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 356 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 352 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 348 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 344 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 340 +addi $sp, $sp, -4 #Push local var str_eq@_a@8 stackpointer 336 +addi $sp, $sp, -4 #Push local var str_eq@_b@8 stackpointer 332 +addi $sp, $sp, -4 #Push local var str_eq@_a@9 stackpointer 328 +addi $sp, $sp, -4 #Push local var str_eq@_b@9 stackpointer 324 +addi $sp, $sp, -4 #Push local var new_A@1 stackpointer 320 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method1@0 stackpointer 316 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@1 stackpointer 312 +addi $sp, $sp, -4 #Push local var param_0_to_method1@0 stackpointer 308 +addi $sp, $sp, -4 #Push local var new_A@2 stackpointer 304 +addi $sp, $sp, -4 #Push local var x stackpointer 300 +addi $sp, $sp, -4 #Push local var new_E@0 stackpointer 296 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method6@0 stackpointer 292 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@2 stackpointer 288 +addi $sp, $sp, -4 #Push local var param_0_to_method6@0 stackpointer 284 +addi $sp, $sp, -4 #Push local var r stackpointer 280 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 276 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 272 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@3 stackpointer 268 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 264 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 260 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@4 stackpointer 256 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 252 +addi $sp, $sp, -4 #Push local var param_0_to_print@1 stackpointer 248 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@4 stackpointer 244 +addi $sp, $sp, -4 #Push local var param_0_to_print@2 stackpointer 240 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@5 stackpointer 236 +addi $sp, $sp, -4 #Push local var a stackpointer 232 +addi $sp, $sp, -4 #Push local var new_A2I@0 stackpointer 228 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_i2a@0 stackpointer 224 +addi $sp, $sp, -4 #Push local var param_0_to_i2a@0 stackpointer 220 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@6 stackpointer 216 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@7 stackpointer 212 +addi $sp, $sp, -4 #Push local var new_D@0 stackpointer 208 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method7@0 stackpointer 204 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@5 stackpointer 200 +addi $sp, $sp, -4 #Push local var param_0_to_method7@0 stackpointer 196 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@8 stackpointer 192 +addi $sp, $sp, -4 #Push local var param_0_to_print@3 stackpointer 188 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@9 stackpointer 184 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@10 stackpointer 180 +addi $sp, $sp, -4 #Push local var param_0_to_print@4 stackpointer 176 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@11 stackpointer 172 +addi $sp, $sp, -4 #Push local var new_C@0 stackpointer 168 +addi $sp, $sp, -4 #Push local var instance_C_to_method5@0 stackpointer 164 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@6 stackpointer 160 +addi $sp, $sp, -4 #Push local var param_0_to_method5@0 stackpointer 156 +addi $sp, $sp, -4 #Push local var new_C@1 stackpointer 152 +addi $sp, $sp, -4 #Push local var instance_B_to_method5@0 stackpointer 148 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@7 stackpointer 144 +addi $sp, $sp, -4 #Push local var param_0_to_method5@1 stackpointer 140 +addi $sp, $sp, -4 #Push local var new_C@2 stackpointer 136 +addi $sp, $sp, -4 #Push local var instance_A_to_method5@0 stackpointer 132 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@8 stackpointer 128 +addi $sp, $sp, -4 #Push local var param_0_to_method5@2 stackpointer 124 +addi $sp, $sp, -4 #Push local var new_A@3 stackpointer 120 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 116 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var new_D@1 stackpointer 108 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method4@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@9 stackpointer 100 +addi $sp, $sp, -4 #Push local var param_0_to_method4@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@10 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_1_to_method4@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var c stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method6@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@11 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_0_to_method6@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var a stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method3@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@12 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_method3@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var o stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@12 stackpointer 40 +addi $sp, $sp, -4 #Push local var new_A@4 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var new_B@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_method2@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@13 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_method2@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@14 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_method2@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable avar +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 432($sp) #Guardando en la variable local new_A@0 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 432($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 432($sp) #Lee el valor de la var new_A@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@0 +jal new_ctr_A # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Inicio de un While +j while_cond_2 # +while_back_2: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_53 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 428($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 432($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 424($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@0 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 428($sp) #Lee el valor de la var param_0_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@0 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Evalua la condicion de un If +#StaticDispatch is_even +#Evalua el parametro 0 para el CastingDispatch is_even +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 420($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@0 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 420($sp) #Lee el valor de la var instance_dynamic_to_value@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@0 +lw $t0, 424($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 416($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch is_even +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 420($sp) #Lee el valor de la var param_0_to_is_even@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_is_even@0 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion is_even +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_0 # +#Else case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_54 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 412($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 416($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_0 # +then_Main_main_0: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_55 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 408($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 412($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_0: +#Fin de un If +#Inicio del paso 3 de una sequencia Block +#StaticDispatch class_type +#Evalua el parametro 0 para el CastingDispatch class_type +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 404($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_class_type@0 +#Fin del paramentro 0 al CastingDispatch class_type +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 408($sp) #Lee el valor de la var param_0_to_class_type@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_class_type@0 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion class_type +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#Asignando un nuevo valor a la variable char +#StaticDispatch menu +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 440($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion menu +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded char +sw $t1, 4($t0) #Setea la propiedad char con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +move $s4, $t1 #Guarda el valor de la propiedad char en la variable local _ +#Inicio del paso 5 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 400($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@0 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_56 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 396($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 400($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 396($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 392($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@1 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_57 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 388($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 392($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 388($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 384($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@2 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_58 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 380($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 384($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 380($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 376($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@3 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_59 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 372($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 376($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 372($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 368($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@4 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_60 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 364($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 368($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 364($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 360($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@5 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_61 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 356($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 360($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 356($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 352($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@6 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_62 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 348($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 352($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 348($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 344($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@7 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_63 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 340($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 344($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 340($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 336($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@8 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_64 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 332($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 336($sp) #Guarda el parametro 0 -> str_eq@_a@8 +lw $a1, 332($sp) #Guarda el parametro 1 -> str_eq@_b@8 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_9 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Self Property char +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad char +sw $t1, 328($sp) #Guarda el valor de la propiedad char en la variable local str_eq@_a@9 +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_65 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 324($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 436($sp) #Guarda self +lw $a0, 328($sp) #Guarda el parametro 0 -> str_eq@_a@9 +lw $a1, 324($sp) #Guarda el parametro 1 -> str_eq@_b@9 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_10 # +#Else case +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el DinamicDispatch method1 +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 320($sp) #Guardando en la variable local new_A@1 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 320($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 320($sp) #Lee el valor de la var new_A@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@1 +jal new_ctr_A # +sw $v0, 316($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch method1 +#Evalua el parametro 0 para el CastingDispatch method1 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 312($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@1 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 312($sp) #Lee el valor de la var instance_dynamic_to_value@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@1 +lw $t0, 316($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 308($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method1 +lw $t0, 316($sp) #Lee el valor de la var instance_dynamic_to_method1@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method1@0 +lw $t0, 312($sp) #Lee el valor de la var param_0_to_method1@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method1@0 +lw $t0, 324($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion method1 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +j fin_Main_main_10 # +then_Main_main_10: +#Then case +#Asignando un nuevo valor a la variable flag +li $s4, 0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded flag +sw $t1, 16($t0) #Setea la propiedad flag con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 16($t0) #Lee la propiedad flag +move $s4, $t1 #Guarda el valor de la propiedad flag en la variable local _ +fin_Main_main_10: +#Fin de un If +j fin_Main_main_9 # +then_Main_main_9: +#Then case +#Asignando un nuevo valor a la variable avar +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 304($sp) #Guardando en la variable local new_A@2 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 304($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 304($sp) #Lee el valor de la var new_A@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@2 +jal new_ctr_A # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_9: +#Fin de un If +j fin_Main_main_8 # +then_Main_main_8: +#Then case +la $t0, _______null_______ # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 300($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evalua la Expresion para el DinamicDispatch method6 +#Creando instancia de tipo E +#Allocate a una class E +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 296($sp) #Guardando en la variable local new_E@0 puntero de la instancia de la clase E +#Assignacion de la insformacion de tipo a la instancia +la $t0, E # +move $s4, $t0 # +lw $t0, 296($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 296($sp) #Lee el valor de la var new_E@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_E@0 +jal new_ctr_E # +sw $v0, 292($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch method6 +#Evalua el parametro 0 para el CastingDispatch method6 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 288($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@2 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 288($sp) #Lee el valor de la var instance_dynamic_to_value@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@2 +lw $t0, 292($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 284($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method6 +lw $t0, 292($sp) #Lee el valor de la var instance_dynamic_to_method6@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method6@0 +lw $t0, 288($sp) #Lee el valor de la var param_0_to_method6@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method6@0 +lw $t0, 300($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de E +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion method6 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 300($sp) # +lw $t0, 300($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Eval Expression to Let r +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 268($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@3 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 268($sp) #Lee el valor de la var instance_dynamic_to_value@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@3 +lw $t0, 272($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 276($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Evaluando el operado izquierdo de una operacion factor +#Evalua la Expresion para el DinamicDispatch value +#Get Local Var x +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 300($sp) #Lee el valor de la var x +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con x +lw $t0, 304($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 264($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 8 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 260($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 436($sp) #Guarda self +lw $a0, 264($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 260($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 272($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 436($sp) #Guarda self +lw $a0, 276($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 272($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 280($sp) # +#Fin de la asignacion Let r +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_66 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 252($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 256($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 248($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@1 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 252($sp) #Lee el valor de la var param_0_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@1 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_67 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 244($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 248($sp) #Lee el valor de la var param_0_to_out_string@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@4 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Local Var x +lw $t0, 300($sp) # +sw $t0, 240($sp) # +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 244($sp) #Lee el valor de la var param_0_to_print@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@2 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_68 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 236($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 240($sp) #Lee el valor de la var param_0_to_out_string@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@5 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 5 de una sequencia Block +#Eval Expression to Let a +#Creando instancia de tipo A2I +#Allocate a una class A2I +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 228($sp) #Guardando en la variable local new_A2I@0 puntero de la instancia de la clase A2I +#Assignacion de la insformacion de tipo a la instancia +la $t0, A2I # +move $s4, $t0 # +lw $t0, 228($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 228($sp) #Lee el valor de la var new_A2I@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A2I@0 +jal new_ctr_A2I # +sw $v0, 232($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let a +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch i2a +#Get Local Var a +lw $t0, 232($sp) # +sw $t0, 224($sp) # +#Fin de la exprecion previa al DinamicDispatch i2a +#Evalua el parametro 0 para el CastingDispatch i2a +#Get Local Var r +lw $t0, 280($sp) # +sw $t0, 220($sp) # +#Fin del paramentro 0 al CastingDispatch i2a +lw $t0, 224($sp) #Lee el valor de la var instance_dynamic_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_i2a@0 +lw $t0, 224($sp) #Lee el valor de la var param_0_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a@0 +lw $t0, 232($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion i2a +jal $t3 # +sw $v0, 216($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 220($sp) #Lee el valor de la var param_0_to_out_string@6 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@6 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_69 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 212($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 216($sp) #Lee el valor de la var param_0_to_out_string@7 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@7 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable avar +#Get Local Var x +lw $t0, 300($sp) # +move $s4, $t0 # +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_8: +#Fin de un If +j fin_Main_main_7 # +then_Main_main_7: +#Then case +#Evalua la condicion de un If +#Evalua la Expresion para el DinamicDispatch method7 +#Creando instancia de tipo D +#Allocate a una class D +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 208($sp) #Guardando en la variable local new_D@0 puntero de la instancia de la clase D +#Assignacion de la insformacion de tipo a la instancia +la $t0, D # +move $s4, $t0 # +lw $t0, 208($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 208($sp) #Lee el valor de la var new_D@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_D@0 +jal new_ctr_D # +sw $v0, 204($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch method7 +#Evalua el parametro 0 para el CastingDispatch method7 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 200($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@5 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 200($sp) #Lee el valor de la var instance_dynamic_to_value@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@5 +lw $t0, 204($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 196($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method7 +lw $t0, 204($sp) #Lee el valor de la var instance_dynamic_to_method7@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method7@0 +lw $t0, 200($sp) #Lee el valor de la var param_0_to_method7@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method7@0 +lw $t0, 212($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion method7 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_11 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_70 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 192($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 196($sp) #Lee el valor de la var param_0_to_out_string@8 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@8 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 188($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@3 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 192($sp) #Lee el valor de la var param_0_to_print@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@3 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_71 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 184($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 188($sp) #Lee el valor de la var param_0_to_out_string@9 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@9 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_11 # +then_Main_main_11: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_72 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 180($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 184($sp) #Lee el valor de la var param_0_to_out_string@10 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@10 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 176($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@4 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 180($sp) #Lee el valor de la var param_0_to_print@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@4 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_73 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 172($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 176($sp) #Lee el valor de la var param_0_to_out_string@11 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@11 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_11: +#Fin de un If +fin_Main_main_7: +#Fin de un If +j fin_Main_main_6 # +then_Main_main_6: +#Then case +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el CastingDispatch method5 +#Creando instancia de tipo C +#Allocate a una class C +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 168($sp) #Guardando en la variable local new_C@0 puntero de la instancia de la clase C +#Assignacion de la insformacion de tipo a la instancia +la $t0, C # +move $s4, $t0 # +lw $t0, 168($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 168($sp) #Lee el valor de la var new_C@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_C@0 +jal new_ctr_C # +sw $v0, 164($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al CastingDispatch method5 +#Evalua el parametro 0 para el CastingDispatch method5 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 160($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@6 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 160($sp) #Lee el valor de la var instance_dynamic_to_value@6 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@6 +lw $t0, 164($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 156($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method5 +lw $t0, 164($sp) #Lee el valor de la var instance_C_to_method5@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_C_to_method5@0 +lw $t0, 160($sp) #Lee el valor de la var param_0_to_method5@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method5@0 +jal C_method5 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_6: +#Fin de un If +j fin_Main_main_5 # +then_Main_main_5: +#Then case +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el CastingDispatch method5 +#Creando instancia de tipo C +#Allocate a una class C +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 152($sp) #Guardando en la variable local new_C@1 puntero de la instancia de la clase C +#Assignacion de la insformacion de tipo a la instancia +la $t0, C # +move $s4, $t0 # +lw $t0, 152($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 152($sp) #Lee el valor de la var new_C@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_C@1 +jal new_ctr_C # +sw $v0, 148($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al CastingDispatch method5 +#Evalua el parametro 0 para el CastingDispatch method5 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 144($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@7 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 144($sp) #Lee el valor de la var instance_dynamic_to_value@7 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@7 +lw $t0, 148($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 140($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method5 +lw $t0, 148($sp) #Lee el valor de la var instance_B_to_method5@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_B_to_method5@0 +lw $t0, 144($sp) #Lee el valor de la var param_0_to_method5@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method5@1 +jal B_method5 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_5: +#Fin de un If +j fin_Main_main_4 # +then_Main_main_4: +#Then case +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el CastingDispatch method5 +#Creando instancia de tipo C +#Allocate a una class C +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 136($sp) #Guardando en la variable local new_C@2 puntero de la instancia de la clase C +#Assignacion de la insformacion de tipo a la instancia +la $t0, C # +move $s4, $t0 # +lw $t0, 136($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 136($sp) #Lee el valor de la var new_C@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_C@2 +jal new_ctr_C # +sw $v0, 132($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al CastingDispatch method5 +#Evalua el parametro 0 para el CastingDispatch method5 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 128($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@8 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 128($sp) #Lee el valor de la var instance_dynamic_to_value@8 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@8 +lw $t0, 132($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 124($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method5 +lw $t0, 132($sp) #Lee el valor de la var instance_A_to_method5@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_A_to_method5@0 +lw $t0, 128($sp) #Lee el valor de la var param_0_to_method5@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method5@2 +jal A_method5 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_4: +#Fin de un If +j fin_Main_main_3 # +then_Main_main_3: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable a_var +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 120($sp) #Guardando en la variable local new_A@3 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 120($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 120($sp) #Lee el valor de la var new_A@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@3 +jal new_ctr_A # +sw $v0, 116($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#StaticDispatch get_int +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 440($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion get_int +jal $t3 # +sw $v0, 112($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 116($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 116($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 124($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded a_var +sw $t1, 12($t0) #Setea la propiedad a_var con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad a_var +move $s4, $t1 #Guarda el valor de la propiedad a_var en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el DinamicDispatch method4 +#Creando instancia de tipo D +#Allocate a una class D +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 108($sp) #Guardando en la variable local new_D@1 puntero de la instancia de la clase D +#Assignacion de la insformacion de tipo a la instancia +la $t0, D # +move $s4, $t0 # +lw $t0, 108($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 108($sp) #Lee el valor de la var new_D@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_D@1 +jal new_ctr_D # +sw $v0, 104($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch method4 +#Evalua el parametro 0 para el CastingDispatch method4 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 100($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@9 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 100($sp) #Lee el valor de la var instance_dynamic_to_value@9 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@9 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 96($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method4 +#Evalua el parametro 1 para el CastingDispatch method4 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property a_var +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad a_var +sw $t1, 92($sp) #Guarda el valor de la propiedad a_var en la variable local instance_dynamic_to_value@10 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 92($sp) #Lee el valor de la var instance_dynamic_to_value@10 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@10 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 88($sp) #Asigna el resultado de la funcion +#Fin del paramentro 1 al CastingDispatch method4 +lw $t0, 104($sp) #Lee el valor de la var instance_dynamic_to_method4@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method4@0 +lw $t0, 100($sp) #Lee el valor de la var param_0_to_method4@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method4@0 +lw $t0, 96($sp) #Lee el valor de la var param_1_to_method4@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_method4@0 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion method4 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_3: +#Fin de un If +j fin_Main_main_2 # +then_Main_main_2: +#Then case +#Eval Expression To Case +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 84($sp) #Guarda el valor de la propiedad avar en la variable local cond@expr@value@0 +lw $t0, 84($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 80($sp) # +#Final Expression To Case +#Check Type To Case When Option Is C +li $s4, 9 # +lw $s6, 436($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, C_step_case_1 # +#Check Type To Case When Option Is A +li $s4, 7 # +lw $s6, 436($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, A_step_case_1 # +#Check Type To Case When Option Is Object +li $s4, 1 # +lw $s6, 436($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 436($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Object_step_case_1 # +C_step_case_1: +#Assigan el valor de la expresion a la var c del case +lw $t0, 84($sp) # +sw $t0, 76($sp) # +#Eval Expression Of C Option +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el DinamicDispatch method6 +#Get Local Var c +lw $t0, 76($sp) # +sw $t0, 72($sp) # +#Fin de la exprecion previa al DinamicDispatch method6 +#Evalua el parametro 0 para el CastingDispatch method6 +#Evalua la Expresion para el DinamicDispatch value +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 76($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de C +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method6 +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_method6@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method6@1 +lw $t0, 68($sp) #Lee el valor de la var param_0_to_method6@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method6@1 +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de C +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion method6 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +j case_end_1 # +A_step_case_1: +#Assigan el valor de la expresion a la var a del case +lw $t0, 84($sp) # +sw $t0, 232($sp) # +#Eval Expression Of A Option +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el DinamicDispatch method3 +#Get Local Var a +lw $t0, 232($sp) # +sw $t0, 56($sp) # +#Fin de la exprecion previa al DinamicDispatch method3 +#Evalua el parametro 0 para el CastingDispatch method3 +#Evalua la Expresion para el DinamicDispatch value +#Get Local Var a +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 232($sp) #Lee el valor de la var a +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con a +lw $t0, 236($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method3 +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_method3@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method3@0 +lw $t0, 52($sp) #Lee el valor de la var param_0_to_method3@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method3@0 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion method3 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +j case_end_1 # +Object_step_case_1: +#Assigan el valor de la expresion a la var o del case +lw $t0, 84($sp) # +sw $t0, 44($sp) # +#Eval Expression Of Object Option +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_74 # +move $s4, $t0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 40($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) #Lee el valor de la var param_0_to_out_string@12 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@12 +lw $t0, 444($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch abort +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 440($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +li $s4, 0 # +lw $s6, 436($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j case_end_1 # +case_end_1: +fin_Main_main_2: +#Fin de un If +j fin_Main_main_1 # +then_Main_main_1: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable a_var +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 36($sp) #Guardando en la variable local new_A@4 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 36($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 36($sp) #Lee el valor de la var new_A@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@4 +jal new_ctr_A # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#StaticDispatch get_int +lw $t0, 436($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 440($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion get_int +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_set_var@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@1 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_set_var@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@1 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded a_var +sw $t1, 12($t0) #Setea la propiedad a_var con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad a_var +move $s4, $t1 #Guarda el valor de la propiedad a_var en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable avar +#Evalua la Expresion para el DinamicDispatch method2 +#Creando instancia de tipo B +#Allocate a una class B +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 24($sp) #Guardando en la variable local new_B@0 puntero de la instancia de la clase B +#Assignacion de la insformacion de tipo a la instancia +la $t0, B # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 24($sp) #Lee el valor de la var new_B@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_B@0 +jal new_ctr_B # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch method2 +#Evalua el parametro 0 para el CastingDispatch method2 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property avar +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 16($sp) #Guarda el valor de la propiedad avar en la variable local instance_dynamic_to_value@13 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_value@13 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@13 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch method2 +#Evalua el parametro 1 para el CastingDispatch method2 +#Evalua la Expresion para el DinamicDispatch value +#Get Self Property a_var +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad a_var +sw $t1, 8($sp) #Guarda el valor de la propiedad a_var en la variable local instance_dynamic_to_value@14 +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_value@14 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_value@14 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 1 al CastingDispatch method2 +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_method2@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_method2@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_method2@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method2@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_method2@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_method2@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de B +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion method2 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 436($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded avar +sw $t1, 8($t0) #Setea la propiedad avar con el valor de _ +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +move $s4, $t1 #Guarda el valor de la propiedad avar en la variable local _ +fin_Main_main_1: +#Fin de un If +#Fin del cuerpo e inicio de la condicion de un While +while_cond_2: +#Get Self Property flag +lw $t0, 436($sp) #Instancia de la clase Main +lw $t1, 16($t0) #Lee la propiedad flag +move $s4, $t1 #Guarda el valor de la propiedad flag en la variable local _ +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_2 # +#Fin de la condicion de un While +lw $t0, 436($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 440 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_A: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_A +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +#Assignando el resultado de la expression al atributo var de la clase A +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase A +move $t1, $s4 #Guarda el valor que se le asignara a la propieded var +sw $t1, 4($t0) #Setea la propiedad var con el valor de _ +#Fin De la Asignacion +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +Main_print: # +#Parametro self en stackpoiner + 36 +#Parametro var@0 en stackpoiner + 32 +addi $sp, $sp, -4 #Push local var z stackpointer 28 +addi $sp, $sp, -4 #Push local var new_A2I@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_i2a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_value@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_i2a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_print +#Eval Expression to Let z +#Creando instancia de tipo A2I +#Allocate a una class A2I +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 24($sp) #Guardando en la variable local new_A2I@0 puntero de la instancia de la clase A2I +#Assignacion de la insformacion de tipo a la instancia +la $t0, A2I # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 24($sp) #Lee el valor de la var new_A2I@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A2I@0 +jal new_ctr_A2I # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let z +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch i2a +#Get Local Var z +lw $t0, 28($sp) # +sw $t0, 20($sp) # +#Fin de la exprecion previa al DinamicDispatch i2a +#Evalua el parametro 0 para el CastingDispatch i2a +#Evalua la Expresion para el DinamicDispatch value +#Get Local Var var +#Fin de la exprecion previa al DinamicDispatch value +lw $t0, 32($sp) #Lee el valor de la var var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con var@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion value +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch i2a +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_i2a@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion i2a +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_52 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +A_value: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_value +#Get Self Property var +lw $t0, 4($sp) #Instancia de la clase A +lw $t1, 4($t0) #Lee la propiedad var +move $s4, $t1 #Guarda el valor de la propiedad var en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_is_even: # +#Parametro self en stackpoiner + 52 +#Parametro num@0 en stackpoiner + 48 +addi $sp, $sp, -4 #Push local var x stackpointer 44 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_is_even@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_is_even@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_is_even +#Eval Expression to Let x +#Get Local Var num +lw $t0, 48($sp) # +sw $t0, 44($sp) # +#Fin de la asignacion Let x +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +li $s4, 0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 52($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_is_even_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +li $s4, 0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 52($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_is_even_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 52($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_is_even_2 # +#Else case +#StaticDispatch is_even +#Evalua el parametro 0 para el CastingDispatch is_even +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 2 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 52($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch is_even +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_is_even@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_is_even@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion is_even +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_is_even_2 # +then_Main_is_even_2: +#Then case +li $s4, 0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_Main_is_even_2: +#Fin de un If +j fin_Main_is_even_1 # +then_Main_is_even_1: +#Then case +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_Main_is_even_1: +#Fin de un If +j fin_Main_is_even_0 # +then_Main_is_even_0: +#Then case +#StaticDispatch is_even +#Evalua el parametro 0 para el CastingDispatch is_even +#Evaluando la expression de una operacion unaria +#Get Local Var x +lw $t0, 44($sp) # +move $s4, $t0 # +#FIN expression de una operacion unaria +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch is_even +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_is_even@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_is_even@1 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion is_even +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_is_even_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 # +jr $ra # + +Main_class_type: # +#Parametro self en stackpoiner + 64 +#Parametro var@0 en stackpoiner + 60 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var e stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var d stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var c stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var b stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var a stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@4 stackpointer 12 +addi $sp, $sp, -4 #Push local var o stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@5 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_class_type +#Eval Expression To Case +#Get Local Var var +lw $t0, 60($sp) # +sw $t0, 56($sp) # +lw $t0, 56($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 52($sp) # +#Final Expression To Case +#Check Type To Case When Option Is E +li $s4, 11 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, E_step_case_0 # +#Check Type To Case When Option Is D +li $s4, 10 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, D_step_case_0 # +#Check Type To Case When Option Is C +li $s4, 9 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, C_step_case_0 # +#Check Type To Case When Option Is B +li $s4, 8 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, B_step_case_0 # +#Check Type To Case When Option Is A +li $s4, 7 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, A_step_case_0 # +#Check Type To Case When Option Is Object +li $s4, 1 # +lw $s6, 64($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Object_step_case_0 # +E_step_case_0: +#Assigan el valor de la expresion a la var e del case +lw $t0, 56($sp) # +sw $t0, 48($sp) # +#Eval Expression Of E Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_46 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +D_step_case_0: +#Assigan el valor de la expresion a la var d del case +lw $t0, 56($sp) # +sw $t0, 40($sp) # +#Eval Expression Of D Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_47 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 40($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +C_step_case_0: +#Assigan el valor de la expresion a la var c del case +lw $t0, 56($sp) # +sw $t0, 32($sp) # +#Eval Expression Of C Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_48 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +B_step_case_0: +#Assigan el valor de la expresion a la var b del case +lw $t0, 56($sp) # +sw $t0, 24($sp) # +#Eval Expression Of B Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_49 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +A_step_case_0: +#Assigan el valor de la expresion a la var a del case +lw $t0, 56($sp) # +sw $t0, 16($sp) # +#Eval Expression Of A Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_50 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@4 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +Object_step_case_0: +#Assigan el valor de la expresion a la var o del case +lw $t0, 56($sp) # +sw $t0, 8($sp) # +#Eval Expression Of Object Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_51 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@5 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +case_end_0: +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 68 # +jr $ra # + +Main_menu: # +#Parametro self en stackpoiner + 108 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var param_0_to_print@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 96 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_print@1 stackpointer 88 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 84 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@4 stackpointer 80 +addi $sp, $sp, -4 #Push local var param_0_to_print@2 stackpointer 76 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@5 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@6 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_0_to_print@3 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@7 stackpointer 60 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@8 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_print@4 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@9 stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@10 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_print@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@11 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@12 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_print@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@13 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@14 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_print@7 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@15 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@16 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@17 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_menu +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_26 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 104($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 108($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 100($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@0 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 104($sp) #Lee el valor de la var param_0_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@0 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_27 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 96($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 100($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_28 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 92($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 96($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 88($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@1 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) #Lee el valor de la var param_0_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@1 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 5 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_29 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 84($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 88($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 6 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_30 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 80($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 84($sp) #Lee el valor de la var param_0_to_out_string@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@4 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 7 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 76($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@2 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 80($sp) #Lee el valor de la var param_0_to_print@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@2 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 8 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_31 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 72($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 76($sp) #Lee el valor de la var param_0_to_out_string@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@5 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 9 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_32 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 72($sp) #Lee el valor de la var param_0_to_out_string@6 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@6 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 10 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 64($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@3 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 68($sp) #Lee el valor de la var param_0_to_print@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@3 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 11 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_33 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 64($sp) #Lee el valor de la var param_0_to_out_string@7 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@7 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 12 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_34 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 56($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) #Lee el valor de la var param_0_to_out_string@8 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@8 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 13 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 52($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@4 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 56($sp) #Lee el valor de la var param_0_to_print@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@4 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 14 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_35 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 48($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 52($sp) #Lee el valor de la var param_0_to_out_string@9 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@9 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 15 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_36 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) #Lee el valor de la var param_0_to_out_string@10 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@10 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 16 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 40($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@5 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) #Lee el valor de la var param_0_to_print@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@5 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 17 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_37 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 40($sp) #Lee el valor de la var param_0_to_out_string@11 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@11 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 18 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_38 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_out_string@12 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@12 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 19 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 28($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@6 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_print@6 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@6 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 20 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_39 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_out_string@13 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@13 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 21 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_40 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@14 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@14 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 22 de una sequencia Block +#StaticDispatch print +#Evalua el parametro 0 para el CastingDispatch print +#Get Self Property avar +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad avar +sw $t1, 16($sp) #Guarda el valor de la propiedad avar en la variable local param_0_to_print@7 +#Fin del paramentro 0 al CastingDispatch print +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_print@7 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print@7 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 23 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_41 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@15 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@15 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 24 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_42 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@16 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@16 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 25 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_43 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@17 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@17 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 26 de una sequencia Block +#StaticDispatch in_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 112($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 112 # +jr $ra # + +A_method1: # +#Parametro self en stackpoiner + 8 +#Parametro num@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_method1 +#Get Local Var self +lw $t0, 8($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_E: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_E +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_D # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +C_method6: # +#Parametro self en stackpoiner + 24 +#Parametro num@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var x stackpointer 16 +addi $sp, $sp, -4 #Push local var new_A@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion C_method6 +li $s4, 0 # +lw $s6, 24($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 16($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando la expression de una operacion unaria +#Get Local Var num +lw $t0, 20($sp) # +move $s4, $t0 # +#FIN expression de una operacion unaria +lw $s6, 24($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 16($sp) # +lw $t0, 16($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_A@0 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_A@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@0 +jal new_ctr_A # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 16($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +E_method6: # +#Parametro self en stackpoiner + 32 +#Parametro num@0 en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var x stackpointer 24 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_A@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion E_method6 +li $s4, 0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion div +#Get Local Var num +lw $t0, 28($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +li $s4, 8 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion div +lw $s6, 32($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +lw $t0, 24($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_A@0 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_A@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@0 +jal new_ctr_A # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 36 # +jr $ra # + +new_ctr_A2I: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_A2I +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +A2I_i2a: # +#Parametro self en stackpoiner + 48 +#Parametro i@0 en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2a +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 48($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 28($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 48($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_1 # +#Else case +#Evalua la Expresion para el DinamicDispatch concat +la $t0, string_23 # +move $s4, $t0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Evaluando la expression de una operacion unaria +li $s4, 1 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 48($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 48($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_i2a_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@0 +lw $t0, 56($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_i2a_1 # +then_A2I_i2a_1: +#Then case +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 48($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_i2a_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@1 +lw $t0, 56($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_A2I_i2a_1: +#Fin de un If +j fin_A2I_i2a_0 # +then_A2I_i2a_0: +#Then case +la $t0, string_24 # +move $s4, $t0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2a_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 52 # +jr $ra # + +A2I_i2a_aux: # +#Parametro self en stackpoiner + 60 +#Parametro i@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var next stackpointer 44 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_i2c@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2a_aux +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 52($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_aux_0 # +#Else case +#Eval Expression to Let next +#Evaluando el operado izquierdo de una operacion div +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +li $s4, 10 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion div +lw $s6, 60($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 44($sp) # +#Fin de la asignacion Let next +#Evalua la Expresion para el DinamicDispatch concat +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Get Local Var next +lw $t0, 44($sp) # +sw $t0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_i2a_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch i2c +#Evalua el parametro 0 para el CastingDispatch i2c +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var next +lw $t0, 44($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 60($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch i2c +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_i2c@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2c@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion i2c +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_i2a_aux_0 # +then_A2I_i2a_aux_0: +#Then case +la $t0, string_25 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2a_aux_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +new_ctr_D: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_D +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_B # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +D_method7: # +#Parametro self en stackpoiner + 60 +#Parametro num@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var x stackpointer 52 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_method7@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_method7@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion D_method7 +#Eval Expression to Let x +#Get Local Var num +lw $t0, 56($sp) # +sw $t0, 52($sp) # +#Fin de la asignacion Let x +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Local Var x +lw $t0, 52($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 60($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_D_method7_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var x +lw $t0, 52($sp) # +sw $t0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_D_method7_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var x +lw $t0, 52($sp) # +sw $t0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_D_method7_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +li $s4, 2 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var x +lw $t0, 52($sp) # +sw $t0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@2 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@2 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_D_method7_3 # +#Else case +#StaticDispatch method7 +#Evalua el parametro 0 para el CastingDispatch method7 +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var x +lw $t0, 52($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 3 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch method7 +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_method7@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method7@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion method7 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_D_method7_3 # +then_D_method7_3: +#Then case +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_D_method7_3: +#Fin de un If +j fin_D_method7_2 # +then_D_method7_2: +#Then case +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_D_method7_2: +#Fin de un If +j fin_D_method7_1 # +then_D_method7_1: +#Then case +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_D_method7_1: +#Fin de un If +j fin_D_method7_0 # +then_D_method7_0: +#Then case +#StaticDispatch method7 +#Evalua el parametro 0 para el CastingDispatch method7 +#Evaluando la expression de una operacion unaria +#Get Local Var x +lw $t0, 52($sp) # +move $s4, $t0 # +#FIN expression de una operacion unaria +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch method7 +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_method7@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_method7@1 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion method7 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_D_method7_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +new_ctr_C: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_C +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_B # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +C_method5: # +#Parametro self en stackpoiner + 40 +#Parametro num@0 en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var x stackpointer 32 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var factor@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_E@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion C_method5 +li $s4, 0 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 32($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var num +lw $t0, 36($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Local Var num +lw $t0, 36($sp) # +sw $t0, 16($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 40($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> factor@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> factor@_b@1 +jal __int__mul__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Local Var num +lw $t0, 36($sp) # +sw $t0, 24($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 40($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 32($sp) # +lw $t0, 32($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo E +#Allocate a una class E +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_E@0 puntero de la instancia de la clase E +#Assignacion de la insformacion de tipo a la instancia +la $t0, E # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_E@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_E@0 +jal new_ctr_E # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 32($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de E +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 # +jr $ra # + +B_method5: # +#Parametro self en stackpoiner + 32 +#Parametro num@0 en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var x stackpointer 24 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_E@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion B_method5 +li $s4, 0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var num +lw $t0, 28($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Local Var num +lw $t0, 28($sp) # +sw $t0, 16($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 32($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +lw $t0, 24($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo E +#Allocate a una class E +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_E@0 puntero de la instancia de la clase E +#Assignacion de la insformacion de tipo a la instancia +la $t0, E # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_E@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_E@0 +jal new_ctr_E # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de E +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 36 # +jr $ra # + +A_method5: # +#Parametro self en stackpoiner + 52 +#Parametro num@0 en stackpoiner + 48 +addi $sp, $sp, -4 #Push local var x stackpointer 44 +addi $sp, $sp, -4 #Push local var y stackpointer 40 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var leq@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var leq@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_E@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_method5 +#Eval Expression to Let x +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Fin de la asignacion Let x +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let y +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Fin de la asignacion Let y +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 36($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Local Var y +lw $t0, 40($sp) # +sw $t0, 32($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 52($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 44($sp) # +lw $t0, 44($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable y +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var y +lw $t0, 40($sp) # +sw $t0, 28($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 52($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando el operado izquierdo de una operacion leq +#Get Local Var y +lw $t0, 40($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion leq +#Evaluando el operado derecho de una operacion leq +#Get Local Var num +lw $t0, 48($sp) # +sw $t0, 16($sp) # +#Resolucion del operado derecha de una operacion leq +lw $s6, 52($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> leq@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> leq@_b@0 +jal __int__leq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 52($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo E +#Allocate a una class E +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_E@0 puntero de la instancia de la clase E +#Assignacion de la insformacion de tipo a la instancia +la $t0, E # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_E@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_E@0 +jal new_ctr_E # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 44($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de E +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 # +jr $ra # + +Main_get_int: # +#Parametro self en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var z stackpointer 20 +addi $sp, $sp, -4 #Push local var new_A2I@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var s stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_a2i@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_get_int +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let z +#Creando instancia de tipo A2I +#Allocate a una class A2I +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_A2I@0 puntero de la instancia de la clase A2I +#Assignacion de la insformacion de tipo a la instancia +la $t0, A2I # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_A2I@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A2I@0 +jal new_ctr_A2I # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let z +#Eval Expression to Let s +#StaticDispatch prompt +lw $t0, 24($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion prompt +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let s +#Evalua la Expresion para el DinamicDispatch a2i +#Get Local Var z +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin de la exprecion previa al DinamicDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Local Var s +lw $t0, 12($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_a2i@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +A_set_var: # +#Parametro self en stackpoiner + 8 +#Parametro num@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_set_var +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable var +#Get Local Var num +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase A +move $t1, $s4 #Guarda el valor que se le asignara a la propieded var +sw $t1, 4($t0) #Setea la propiedad var con el valor de _ +lw $t0, 8($sp) #Instancia de la clase A +lw $t1, 4($t0) #Lee la propiedad var +move $s4, $t1 #Guarda el valor de la propiedad var en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 8($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +A_method4: # +#Parametro self en stackpoiner + 68 +#Parametro num1@0 en stackpoiner + 64 +#Parametro num2@0 en stackpoiner + 60 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var x stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var new_D@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var x stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_D@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_method4 +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Local Var num2 +lw $t0, 60($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var num1 +lw $t0, 64($sp) # +sw $t0, 52($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 68($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 52($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A_method4_0 # +#Else case +li $s4, 0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 48($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var num2 +lw $t0, 60($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var num1 +lw $t0, 64($sp) # +sw $t0, 40($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 68($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 48($sp) # +lw $t0, 48($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo D +#Allocate a una class D +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 36($sp) #Guardando en la variable local new_D@0 puntero de la instancia de la clase D +#Assignacion de la insformacion de tipo a la instancia +la $t0, D # +move $s4, $t0 # +lw $t0, 36($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 36($sp) #Lee el valor de la var new_D@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_D@0 +jal new_ctr_D # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 48($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A_method4_0 # +then_A_method4_0: +#Then case +li $s4, 0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 48($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var num1 +lw $t0, 64($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var num2 +lw $t0, 60($sp) # +sw $t0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 68($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 48($sp) # +lw $t0, 48($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo D +#Allocate a una class D +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_D@1 puntero de la instancia de la clase D +#Assignacion de la insformacion de tipo a la instancia +la $t0, D # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_D@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_D@1 +jal new_ctr_D # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 48($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@1 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@1 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_A_method4_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 72 # +jr $ra # + +A_method3: # +#Parametro self en stackpoiner + 24 +#Parametro num@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var x stackpointer 16 +addi $sp, $sp, -4 #Push local var new_C@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_method3 +li $s4, 0 # +lw $s6, 24($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 16($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando la expression de una operacion unaria +#Get Local Var num +lw $t0, 20($sp) # +move $s4, $t0 # +#FIN expression de una operacion unaria +lw $s6, 24($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 16($sp) # +lw $t0, 16($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo C +#Allocate a una class C +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_C@0 puntero de la instancia de la clase C +#Assignacion de la insformacion de tipo a la instancia +la $t0, C # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_C@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_C@0 +jal new_ctr_C # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 16($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de C +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_B: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_B +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_A # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +A_method2: # +#Parametro self en stackpoiner + 36 +#Parametro num1@0 en stackpoiner + 32 +#Parametro num2@0 en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var x stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_B@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_set_var@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_set_var@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_method2 +li $s4, 0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable x +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var num1 +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Local Var num2 +lw $t0, 28($sp) # +sw $t0, 16($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 36($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +lw $t0, 24($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch set_var +#Creando instancia de tipo B +#Allocate a una class B +#atributo type_name en puntero + 0 +#atributo var en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_B@0 puntero de la instancia de la clase B +#Assignacion de la insformacion de tipo a la instancia +la $t0, B # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_B@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_B@0 +jal new_ctr_B # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch set_var +#Evalua el parametro 0 para el CastingDispatch set_var +#Get Local Var x +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch set_var +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_set_var@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_set_var@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_set_var@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de B +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion set_var +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_in_string: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_string +lw $s6, 4($sp) #Guarda self +jal __str__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +String_concat: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_concat +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__concat__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +A2I_i2c: # +#Parametro self en stackpoiner + 88 +#Parametro i@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var int_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2c +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> int_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> int_eq@_b@2 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> int_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> int_eq@_b@3 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> int_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> int_eq@_b@4 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@5 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@6 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@7 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@8 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@9 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_A2I_i2c_9 # +then_A2I_i2c_9: +#Then case +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_9: +#Fin de un If +j fin_A2I_i2c_8 # +then_A2I_i2c_8: +#Then case +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_8: +#Fin de un If +j fin_A2I_i2c_7 # +then_A2I_i2c_7: +#Then case +la $t0, string_13 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_7: +#Fin de un If +j fin_A2I_i2c_6 # +then_A2I_i2c_6: +#Then case +la $t0, string_14 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_6: +#Fin de un If +j fin_A2I_i2c_5 # +then_A2I_i2c_5: +#Then case +la $t0, string_15 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_5: +#Fin de un If +j fin_A2I_i2c_4 # +then_A2I_i2c_4: +#Then case +la $t0, string_16 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_4: +#Fin de un If +j fin_A2I_i2c_3 # +then_A2I_i2c_3: +#Then case +la $t0, string_17 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_3: +#Fin de un If +j fin_A2I_i2c_2 # +then_A2I_i2c_2: +#Then case +la $t0, string_18 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_2: +#Fin de un If +j fin_A2I_i2c_1 # +then_A2I_i2c_1: +#Then case +la $t0, string_19 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_1: +#Fin de un If +j fin_A2I_i2c_0 # +then_A2I_i2c_0: +#Then case +la $t0, string_20 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +Main_prompt: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_prompt +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_44 # +move $s4, $t0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_45 # +move $s4, $t0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch in_string +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +A2I_a2i: # +#Parametro self en stackpoiner + 120 +#Parametro s@0 en stackpoiner + 116 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_a2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 112($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 108($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 108($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 92($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 88($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 84($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 92($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 100($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_21 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 96($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 100($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 96($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 72($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_22 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_2 # +#Else case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 64($sp) #Lee el valor de la var param_0_to_a2i_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_a2i_2 # +then_A2I_a2i_2: +#Then case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 56($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 36($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 56($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 44($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_a2i_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@1 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_A2I_a2i_2: +#Fin de un If +j fin_A2I_a2i_1 # +then_A2I_a2i_1: +#Then case +#Evaluando la expression de una operacion unaria +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 16($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_a2i_aux@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@2 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#FIN expression de una operacion unaria +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +fin_A2I_a2i_1: +#Fin de un If +j fin_A2I_a2i_0 # +then_A2I_a2i_0: +#Then case +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_a2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 124 # +jr $ra # + +A2I_a2i_aux: # +#Parametro self en stackpoiner + 72 +#Parametro s@0 en stackpoiner + 68 +addi $sp, $sp, -4 #Push local var int stackpointer 64 +addi $sp, $sp, -4 #Push local var j stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var i stackpointer 52 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_c2i@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_a2i_aux +#Eval Expression to Let int +li $s4, 0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin de la asignacion Let int +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let j +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 68($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let j +#Eval Expression to Let i +li $s4, 0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin de la asignacion Let i +#Inicio de un While +j while_cond_1 # +while_back_1: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable int +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var int +lw $t0, 64($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 72($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 48($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch c2i +#Evalua el parametro 0 para el CastingDispatch c2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 68($sp) # +sw $t0, 32($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 32($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch c2i +lw $t0, 72($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_c2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_c2i@0 +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion c2i +jal $t3 # +sw $v0, 44($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 72($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 64($sp) # +lw $t0, 64($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 72($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 52($sp) # +lw $t0, 52($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var j +lw $t0, 60($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 72($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 72($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 72($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var int +lw $t0, 64($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 76 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +A2I_c2i: # +#Parametro self en stackpoiner + 88 +#Parametro char@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var str_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_c2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> str_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> str_eq@_b@8 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@9 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_A2I_c2i_9 # +then_A2I_c2i_9: +#Then case +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_9: +#Fin de un If +j fin_A2I_c2i_8 # +then_A2I_c2i_8: +#Then case +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_8: +#Fin de un If +j fin_A2I_c2i_7 # +then_A2I_c2i_7: +#Then case +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_7: +#Fin de un If +j fin_A2I_c2i_6 # +then_A2I_c2i_6: +#Then case +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_6: +#Fin de un If +j fin_A2I_c2i_5 # +then_A2I_c2i_5: +#Then case +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_5: +#Fin de un If +j fin_A2I_c2i_4 # +then_A2I_c2i_4: +#Then case +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_4: +#Fin de un If +j fin_A2I_c2i_3 # +then_A2I_c2i_3: +#Then case +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_3: +#Fin de un If +j fin_A2I_c2i_2 # +then_A2I_c2i_2: +#Then case +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_2: +#Fin de un If +j fin_A2I_c2i_1 # +then_A2I_c2i_1: +#Then case +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_1: +#Fin de un If +j fin_A2I_c2i_0 # +then_A2I_c2i_0: +#Then case +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/arith_input.txt b/tests/codegen/arith_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/arith_output.txt b/tests/codegen/arith_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/atoi.cl b/tests/codegen/atoi.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/atoi.mips b/tests/codegen/atoi.mips new file mode 100644 index 000000000..34945d848 --- /dev/null +++ b/tests/codegen/atoi.mips @@ -0,0 +1,2751 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +A2I_parents: .word 1, 7, 0, +A2I_Name: .asciiz "A2I" +A2I: .word A2I_Name, 1, A2I_parents, Object_abort, Object_copy, Object_type_name, A2I_c2i, A2I_i2c, A2I_a2i, A2I_a2i_aux, A2I_i2a, A2I_i2a_aux, +Main_parents: .word 1, 6, 8, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "0" +string_1: .asciiz "1" +string_2: .asciiz "2" +string_3: .asciiz "3" +string_4: .asciiz "4" +string_5: .asciiz "5" +string_6: .asciiz "6" +string_7: .asciiz "7" +string_8: .asciiz "8" +string_9: .asciiz "9" +string_10: .asciiz "" +string_11: .asciiz "9" +string_12: .asciiz "8" +string_13: .asciiz "7" +string_14: .asciiz "6" +string_15: .asciiz "5" +string_16: .asciiz "4" +string_17: .asciiz "3" +string_18: .asciiz "2" +string_19: .asciiz "1" +string_20: .asciiz "0" +string_21: .asciiz "-" +string_22: .asciiz "+" +string_23: .asciiz "-" +string_24: .asciiz "0" +string_25: .asciiz "" +string_26: .asciiz "678987" +string_27: .asciiz " == " +string_28: .asciiz "\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 52 +addi $sp, $sp, -4 #Push local var a stackpointer 48 +addi $sp, $sp, -4 #Push local var new_A2I@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_a2i@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var b stackpointer 32 +addi $sp, $sp, -4 #Push local var new_A2I@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_i2a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_i2a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Eval Expression to Let a +#Evalua la Expresion para el DinamicDispatch a2i +#Creando instancia de tipo A2I +#Allocate a una class A2I +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 44($sp) #Guardando en la variable local new_A2I@0 puntero de la instancia de la clase A2I +#Assignacion de la insformacion de tipo a la instancia +la $t0, A2I # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 44($sp) #Lee el valor de la var new_A2I@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A2I@0 +jal new_ctr_A2I # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +la $t0, string_26 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_a2i@0 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let a +#Eval Expression to Let b +#Evalua la Expresion para el DinamicDispatch i2a +#Creando instancia de tipo A2I +#Allocate a una class A2I +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 28($sp) #Guardando en la variable local new_A2I@1 puntero de la instancia de la clase A2I +#Assignacion de la insformacion de tipo a la instancia +la $t0, A2I # +move $s4, $t0 # +lw $t0, 28($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 28($sp) #Lee el valor de la var new_A2I@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A2I@1 +jal new_ctr_A2I # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch i2a +#Evalua el parametro 0 para el CastingDispatch i2a +li $s4, 678987 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch i2a +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_i2a@0 +lw $t0, 24($sp) #Lee el valor de la var param_0_to_i2a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion i2a +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let b +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Local Var a +lw $t0, 48($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_27 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Get Local Var b +lw $t0, 32($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_28 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_A2I: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_A2I +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +A2I_a2i: # +#Parametro self en stackpoiner + 120 +#Parametro s@0 en stackpoiner + 116 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_a2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 112($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 108($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 108($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 92($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 88($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 84($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 92($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 100($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_21 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 96($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 100($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 96($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 72($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_22 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_a2i_2 # +#Else case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 64($sp) #Lee el valor de la var param_0_to_a2i_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_a2i_2 # +then_A2I_a2i_2: +#Then case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 56($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 36($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 56($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 44($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_a2i_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@1 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_A2I_a2i_2: +#Fin de un If +j fin_A2I_a2i_1 # +then_A2I_a2i_1: +#Then case +#Evaluando la expression de una operacion unaria +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 16($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_a2i_aux@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@2 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#FIN expression de una operacion unaria +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +fin_A2I_a2i_1: +#Fin de un If +j fin_A2I_a2i_0 # +then_A2I_a2i_0: +#Then case +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_a2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 124 # +jr $ra # + +A2I_a2i_aux: # +#Parametro self en stackpoiner + 72 +#Parametro s@0 en stackpoiner + 68 +addi $sp, $sp, -4 #Push local var int stackpointer 64 +addi $sp, $sp, -4 #Push local var j stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var i stackpointer 52 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_c2i@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_a2i_aux +#Eval Expression to Let int +li $s4, 0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin de la asignacion Let int +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let j +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 68($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let j +#Eval Expression to Let i +li $s4, 0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin de la asignacion Let i +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable int +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var int +lw $t0, 64($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 72($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 48($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch c2i +#Evalua el parametro 0 para el CastingDispatch c2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 68($sp) # +sw $t0, 32($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 32($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch c2i +lw $t0, 72($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_c2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_c2i@0 +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion c2i +jal $t3 # +sw $v0, 44($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 72($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 64($sp) # +lw $t0, 64($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 72($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 52($sp) # +lw $t0, 52($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var j +lw $t0, 60($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 72($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 72($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 72($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var int +lw $t0, 64($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 76 # +jr $ra # + +A2I_i2a: # +#Parametro self en stackpoiner + 48 +#Parametro i@0 en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2a +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 48($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 28($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 48($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_1 # +#Else case +#Evalua la Expresion para el DinamicDispatch concat +la $t0, string_23 # +move $s4, $t0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Evaluando la expression de una operacion unaria +li $s4, 1 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 48($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 48($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_i2a_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@0 +lw $t0, 56($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_i2a_1 # +then_A2I_i2a_1: +#Then case +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 48($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_i2a_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@1 +lw $t0, 56($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_A2I_i2a_1: +#Fin de un If +j fin_A2I_i2a_0 # +then_A2I_i2a_0: +#Then case +la $t0, string_24 # +move $s4, $t0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2a_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 52 # +jr $ra # + +A2I_i2a_aux: # +#Parametro self en stackpoiner + 60 +#Parametro i@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var next stackpointer 44 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_i2a_aux@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_i2c@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2a_aux +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 52($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2a_aux_0 # +#Else case +#Eval Expression to Let next +#Evaluando el operado izquierdo de una operacion div +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +li $s4, 10 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion div +lw $s6, 60($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 36($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 44($sp) # +#Fin de la asignacion Let next +#Evalua la Expresion para el DinamicDispatch concat +#StaticDispatch i2a_aux +#Evalua el parametro 0 para el CastingDispatch i2a_aux +#Get Local Var next +lw $t0, 44($sp) # +sw $t0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch i2a_aux +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_i2a_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2a_aux@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion i2a_aux +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch i2c +#Evalua el parametro 0 para el CastingDispatch i2c +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var i +lw $t0, 56($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var next +lw $t0, 44($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 60($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch i2c +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_i2c@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_i2c@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion i2c +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_A2I_i2a_aux_0 # +then_A2I_i2a_aux_0: +#Then case +la $t0, string_25 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2a_aux_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +A2I_c2i: # +#Parametro self en stackpoiner + 88 +#Parametro char@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var str_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_c2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> str_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> str_eq@_b@8 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@9 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_c2i_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_A2I_c2i_9 # +then_A2I_c2i_9: +#Then case +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_9: +#Fin de un If +j fin_A2I_c2i_8 # +then_A2I_c2i_8: +#Then case +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_8: +#Fin de un If +j fin_A2I_c2i_7 # +then_A2I_c2i_7: +#Then case +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_7: +#Fin de un If +j fin_A2I_c2i_6 # +then_A2I_c2i_6: +#Then case +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_6: +#Fin de un If +j fin_A2I_c2i_5 # +then_A2I_c2i_5: +#Then case +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_5: +#Fin de un If +j fin_A2I_c2i_4 # +then_A2I_c2i_4: +#Then case +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_4: +#Fin de un If +j fin_A2I_c2i_3 # +then_A2I_c2i_3: +#Then case +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_3: +#Fin de un If +j fin_A2I_c2i_2 # +then_A2I_c2i_2: +#Then case +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_2: +#Fin de un If +j fin_A2I_c2i_1 # +then_A2I_c2i_1: +#Then case +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_1: +#Fin de un If +j fin_A2I_c2i_0 # +then_A2I_c2i_0: +#Then case +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_A2I_c2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +String_concat: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_concat +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__concat__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +A2I_i2c: # +#Parametro self en stackpoiner + 88 +#Parametro i@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var int_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A2I_i2c +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> int_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> int_eq@_b@2 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> int_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> int_eq@_b@3 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> int_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> int_eq@_b@4 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@5 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@6 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@7 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@8 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@9 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_A2I_i2c_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A2I +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_A2I_i2c_9 # +then_A2I_i2c_9: +#Then case +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_9: +#Fin de un If +j fin_A2I_i2c_8 # +then_A2I_i2c_8: +#Then case +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_8: +#Fin de un If +j fin_A2I_i2c_7 # +then_A2I_i2c_7: +#Then case +la $t0, string_13 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_7: +#Fin de un If +j fin_A2I_i2c_6 # +then_A2I_i2c_6: +#Then case +la $t0, string_14 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_6: +#Fin de un If +j fin_A2I_i2c_5 # +then_A2I_i2c_5: +#Then case +la $t0, string_15 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_5: +#Fin de un If +j fin_A2I_i2c_4 # +then_A2I_i2c_4: +#Then case +la $t0, string_16 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_4: +#Fin de un If +j fin_A2I_i2c_3 # +then_A2I_i2c_3: +#Then case +la $t0, string_17 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_3: +#Fin de un If +j fin_A2I_i2c_2 # +then_A2I_i2c_2: +#Then case +la $t0, string_18 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_2: +#Fin de un If +j fin_A2I_i2c_1 # +then_A2I_i2c_1: +#Then case +la $t0, string_19 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_1: +#Fin de un If +j fin_A2I_i2c_0 # +then_A2I_i2c_0: +#Then case +la $t0, string_20 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_A2I_i2c_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/atoi_input.txt b/tests/codegen/atoi_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/atoi_output.txt b/tests/codegen/atoi_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/book_list.mips b/tests/codegen/book_list.mips new file mode 100644 index 000000000..4a271b349 --- /dev/null +++ b/tests/codegen/book_list.mips @@ -0,0 +1,1691 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Book_parents: .word 1, 6, 7, 0, +Book_Name: .asciiz "Book" +Book: .word Book_Name, 3, Book_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Book_initBook, Book_print, +Article_parents: .word 1, 6, 7, 8, 0, +Article_Name: .asciiz "Article" +Article: .word Article_Name, 4, Article_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Book_initBook, Article_print, Article_initArticle, +BookList_parents: .word 1, 6, 9, 0, +BookList_Name: .asciiz "BookList" +BookList: .word BookList_Name, 1, BookList_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, BookList_isNil, BookList_cons, BookList_car, BookList_cdr, BookList_print_list, +Cons_parents: .word 1, 6, 9, 10, 0, +Cons_Name: .asciiz "Cons" +Cons: .word Cons_Name, 3, Cons_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Cons_isNil, BookList_cons, Cons_car, Cons_cdr, Cons_print_list, Cons_init, +Nil_parents: .word 1, 6, 9, 11, 0, +Nil_Name: .asciiz "Nil" +Nil: .word Nil_Name, 1, Nil_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Nil_isNil, BookList_cons, BookList_car, BookList_cdr, Nil_print_list, +Main_parents: .word 1, 12, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 2, Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, +string_0: .asciiz "title: " +string_1: .asciiz "\n" +string_2: .asciiz "author: " +string_3: .asciiz "\n" +string_4: .asciiz "periodical: " +string_5: .asciiz "\n" +string_6: .asciiz "- dynamic type was Article -\n" +string_7: .asciiz "- dynamic type was Book -\n" +string_8: .asciiz "Compilers, Principles, Techniques, and Tools" +string_9: .asciiz "Aho, Sethi, and Ullman" +string_10: .asciiz "The Top 100 CD_ROMs" +string_11: .asciiz "Ulanoff" +string_12: .asciiz "PC Magazine" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo books en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded books +sw $t1, 4($t0) #Setea la propiedad books con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 72 +addi $sp, $sp, -4 #Push local var a_book stackpointer 68 +addi $sp, $sp, -4 #Push local var new_Book@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_initBook@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var param_0_to_initBook@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_1_to_initBook@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var an_article stackpointer 48 +addi $sp, $sp, -4 #Push local var new_Article@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_initArticle@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_initArticle@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_1_to_initArticle@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_2_to_initArticle@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var new_Nil@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_cons@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_list@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Eval Expression to Let a_book +#Evalua la Expresion para el DinamicDispatch initBook +#Creando instancia de tipo Book +#Allocate a una class Book +#atributo type_name en puntero + 0 +#atributo title en puntero + 4 +#atributo author en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 64($sp) #Guardando en la variable local new_Book@0 puntero de la instancia de la clase Book +#Assignacion de la insformacion de tipo a la instancia +la $t0, Book # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 64($sp) #Lee el valor de la var new_Book@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Book@0 +jal new_ctr_Book # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch initBook +#Evalua el parametro 0 para el CastingDispatch initBook +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 56($sp) # +#Fin del paramentro 0 al CastingDispatch initBook +#Evalua el parametro 1 para el CastingDispatch initBook +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 52($sp) # +#Fin del paramentro 1 al CastingDispatch initBook +lw $t0, 60($sp) #Lee el valor de la var instance_dynamic_to_initBook@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_initBook@0 +lw $t0, 60($sp) #Lee el valor de la var param_0_to_initBook@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_initBook@0 +lw $t0, 60($sp) #Lee el valor de la var param_1_to_initBook@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_initBook@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion initBook +jal $t3 # +sw $v0, 68($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let a_book +#Eval Expression to Let an_article +#Evalua la Expresion para el DinamicDispatch initArticle +#Creando instancia de tipo Article +#Allocate a una class Article +#atributo type_name en puntero + 0 +#atributo title en puntero + 4 +#atributo author en puntero + 8 +#atributo per_title en puntero + 12 +li $a0, 16 # +li $v0, 9 # +syscall +sw $v0, 44($sp) #Guardando en la variable local new_Article@0 puntero de la instancia de la clase Article +#Assignacion de la insformacion de tipo a la instancia +la $t0, Article # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 44($sp) #Lee el valor de la var new_Article@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Article@0 +jal new_ctr_Article # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch initArticle +#Evalua el parametro 0 para el CastingDispatch initArticle +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch initArticle +#Evalua el parametro 1 para el CastingDispatch initArticle +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 1 al CastingDispatch initArticle +#Evalua el parametro 2 para el CastingDispatch initArticle +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 72($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Fin del paramentro 2 al CastingDispatch initArticle +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_initArticle@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_initArticle@0 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_initArticle@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_initArticle@0 +lw $t0, 40($sp) #Lee el valor de la var param_1_to_initArticle@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_initArticle@0 +lw $t0, 40($sp) #Lee el valor de la var param_2_to_initArticle@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_2_to_initArticle@0 +lw $t0, 56($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Article +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion initArticle +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let an_article +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable books +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch cons +#Creando instancia de tipo Nil +#Allocate a una class Nil +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 24($sp) #Guardando en la variable local new_Nil@0 puntero de la instancia de la clase Nil +#Assignacion de la insformacion de tipo a la instancia +la $t0, Nil # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 24($sp) #Lee el valor de la var new_Nil@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Nil@0 +jal new_ctr_Nil # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var a_book +lw $t0, 68($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Nil +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var an_article +lw $t0, 48($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_cons@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@1 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_cons@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@1 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 72($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded books +sw $t1, 4($t0) #Setea la propiedad books con el valor de _ +lw $t0, 72($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad books +move $s4, $t1 #Guarda el valor de la propiedad books en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_list +#Get Self Property books +lw $t0, 72($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad books +sw $t1, 4($sp) #Guarda el valor de la propiedad books en la variable local instance_dynamic_to_print_list@0 +#Fin de la exprecion previa al DinamicDispatch print_list +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_list@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de BookList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 76 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Book: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Book +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Book +move $t1, $s4 #Guarda el valor que se le asignara a la propieded title +sw $t1, 4($t0) #Setea la propiedad title con el valor de _ +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Book +move $t1, $s4 #Guarda el valor que se le asignara a la propieded author +sw $t1, 8($t0) #Setea la propiedad author con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Book_initBook: # +#Parametro self en stackpoiner + 12 +#Parametro title_p@0 en stackpoiner + 8 +#Parametro author_p@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Book_initBook +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable title +#Get Local Var title_p +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Book +move $t1, $s4 #Guarda el valor que se le asignara a la propieded title +sw $t1, 4($t0) #Setea la propiedad title con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Book +lw $t1, 4($t0) #Lee la propiedad title +move $s4, $t1 #Guarda el valor de la propiedad title en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable author +#Get Local Var author_p +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Book +move $t1, $s4 #Guarda el valor que se le asignara a la propieded author +sw $t1, 8($t0) #Setea la propiedad author con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Book +lw $t1, 8($t0) #Lee la propiedad author +move $s4, $t1 #Guarda el valor de la propiedad author en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Article: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Article +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Book # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Article +move $t1, $s4 #Guarda el valor que se le asignara a la propieded per_title +sw $t1, 12($t0) #Setea la propiedad per_title con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Article_initArticle: # +#Parametro self en stackpoiner + 24 +#Parametro title_p@0 en stackpoiner + 20 +#Parametro author_p@0 en stackpoiner + 16 +#Parametro per_title_p@0 en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var param_0_to_initBook@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_initBook@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Article_initArticle +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch initBook +#Evalua el parametro 0 para el CastingDispatch initBook +#Get Local Var title_p +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch initBook +#Evalua el parametro 1 para el CastingDispatch initBook +#Get Local Var author_p +lw $t0, 16($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch initBook +lw $t0, 24($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_initBook@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_initBook@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_initBook@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_initBook@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Article +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion initBook +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable per_title +#Get Local Var per_title_p +lw $t0, 12($sp) # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase Article +move $t1, $s4 #Guarda el valor que se le asignara a la propieded per_title +sw $t1, 12($t0) #Setea la propiedad per_title con el valor de _ +lw $t0, 24($sp) #Instancia de la clase Article +lw $t1, 12($t0) #Lee la propiedad per_title +move $s4, $t1 #Guarda el valor de la propiedad per_title en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 24($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +new_ctr_Nil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Nil +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_BookList # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +BookList_cons: # +#Parametro self en stackpoiner + 28 +#Parametro hd@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var new_cell stackpointer 20 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion BookList_cons +#Eval Expression to Let new_cell +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let new_cell +#Evalua la Expresion para el DinamicDispatch init +#Get Local Var new_cell +lw $t0, 20($sp) # +sw $t0, 12($sp) # +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var hd +lw $t0, 24($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 28($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +BookList_print_list: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion BookList_print_list +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de BookList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_print_list: # +#Parametro self en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var dummy stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var dummy stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_list@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_print_list +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression To Case +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property xcar +lw $t0, 36($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 24($sp) #Guarda el valor de la propiedad xcar en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +lw $t0, 32($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 28($sp) # +#Final Expression To Case +#Check Type To Case When Option Is Article +li $s4, 8 # +lw $s6, 36($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Article_step_case_0 # +#Check Type To Case When Option Is Book +li $s4, 7 # +lw $s6, 36($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Book_step_case_0 # +Article_step_case_0: +#Assigan el valor de la expresion a la var dummy del case +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Eval Expression Of Article Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +Book_step_case_0: +#Assigan el valor de la expresion a la var dummy del case +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Eval Expression Of Book Option +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +case_end_0: +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_list +#Get Self Property xcdr +lw $t0, 36($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 4($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_print_list@0 +#Fin de la exprecion previa al DinamicDispatch print_list +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_list@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de BookList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +Nil_print_list: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_print_list +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_BookList: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_BookList +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Cons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Cons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_BookList # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcar +sw $t1, 4($t0) #Setea la propiedad xcar con el valor de _ +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcdr +sw $t1, 8($t0) #Setea la propiedad xcdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_init: # +#Parametro self en stackpoiner + 12 +#Parametro hd@0 en stackpoiner + 8 +#Parametro tl@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable xcar +#Get Local Var hd +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcar +sw $t1, 4($t0) #Setea la propiedad xcar con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +move $s4, $t1 #Guarda el valor de la propiedad xcar en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable xcdr +#Get Local Var tl +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcdr +sw $t1, 8($t0) #Setea la propiedad xcdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +move $s4, $t1 #Guarda el valor de la propiedad xcdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +Book_print: # +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@4 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@5 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Book_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_string +#Evalua la Expresion para el DinamicDispatch out_string +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 40($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Get Self Property title +lw $t0, 44($sp) #Instancia de la clase Book +lw $t1, 4($t0) #Lee la propiedad title +sw $t1, 32($sp) #Guarda el valor de la propiedad title en la variable local param_0_to_out_string@1 +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@0 +lw $t0, 36($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@1 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_string +#Evalua la Expresion para el DinamicDispatch out_string +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Get Self Property author +lw $t0, 44($sp) #Instancia de la clase Book +lw $t1, 8($t0) #Lee la propiedad author +sw $t1, 12($sp) #Guarda el valor de la propiedad author en la variable local param_0_to_out_string@4 +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@2 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@4 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@3 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@5 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Book +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 44($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +Article_print: # +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var instance_Book_to_print@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Article_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el CastingDispatch print +#Get Local Var self +#Fin de la exprecion previa al CastingDispatch print +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Book_print # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_string +#Evalua la Expresion para el DinamicDispatch out_string +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Article +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Get Self Property per_title +lw $t0, 28($sp) #Instancia de la clase Article +lw $t1, 12($t0) #Lee la propiedad per_title +sw $t1, 12($sp) #Guarda el valor de la propiedad per_title en la variable local param_0_to_out_string@1 +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Article +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@1 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Article +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 28($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +BookList_isNil: #Esta funcion no se invoca en la ejecucion del programa + +BookList_car: #Esta funcion no se invoca en la ejecucion del programa + +BookList_cdr: #Esta funcion no se invoca en la ejecucion del programa + +Cons_isNil: #Esta funcion no se invoca en la ejecucion del programa + +Cons_car: #Esta funcion no se invoca en la ejecucion del programa + +Cons_cdr: #Esta funcion no se invoca en la ejecucion del programa + +Nil_isNil: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/book_list_input.txt b/tests/codegen/book_list_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/book_list_output.txt b/tests/codegen/book_list_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/cells.mips b/tests/codegen/cells.mips new file mode 100644 index 000000000..fc8e04383 --- /dev/null +++ b/tests/codegen/cells.mips @@ -0,0 +1,1753 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +CellularAutomaton_parents: .word 1, 6, 7, 0, +CellularAutomaton_Name: .asciiz "CellularAutomaton" +CellularAutomaton: .word CellularAutomaton_Name, 2, CellularAutomaton_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, CellularAutomaton_init, CellularAutomaton_print, CellularAutomaton_num_cells, CellularAutomaton_cell, CellularAutomaton_cell_left_neighbor, CellularAutomaton_cell_right_neighbor, CellularAutomaton_cell_at_next_evolution, CellularAutomaton_evolve, +Main_parents: .word 1, 8, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 2, Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, +string_0: .asciiz "\n" +string_1: .asciiz "X" +string_2: .asciiz "X" +string_3: .asciiz "X" +string_4: .asciiz "." +string_5: .asciiz "X" +string_6: .asciiz " X " + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo cells en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cells +sw $t1, 4($t0) #Setea la propiedad cells con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 48 +addi $sp, $sp, -4 #Push local var new_CellularAutomaton@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var countdown stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_evolve@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable cells +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo CellularAutomaton +#Allocate a una class CellularAutomaton +#atributo type_name en puntero + 0 +#atributo population_map en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 44($sp) #Guardando en la variable local new_CellularAutomaton@0 puntero de la instancia de la clase CellularAutomaton +#Assignacion de la insformacion de tipo a la instancia +la $t0, CellularAutomaton # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 44($sp) #Lee el valor de la var new_CellularAutomaton@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_CellularAutomaton@0 +jal new_ctr_CellularAutomaton # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch init +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 48($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cells +sw $t1, 4($t0) #Setea la propiedad cells con el valor de _ +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad cells +move $s4, $t1 #Guarda el valor de la propiedad cells en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cells +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad cells +sw $t1, 32($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Eval Expression to Let countdown +li $s4, 20 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Fin de la asignacion Let countdown +#Inicio de un While +j while_cond_1 # +while_back_1: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch evolve +#Get Self Property cells +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad cells +sw $t1, 24($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_evolve@0 +#Fin de la exprecion previa al DinamicDispatch evolve +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_evolve@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_evolve@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion evolve +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cells +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad cells +sw $t1, 20($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable countdown +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var countdown +lw $t0, 28($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 48($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 28($sp) # +lw $t0, 28($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evaluando el operado izquierdo de una operacion less +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var countdown +lw $t0, 28($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 48($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 48($sp) # +move $s4, $t0 # +#Inicio del paso 3 de una sequencia Block +#Get Local Var self +lw $t0, 48($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 52 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_CellularAutomaton: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_CellularAutomaton +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 4($t0) #Setea la propiedad population_map con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +CellularAutomaton_init: # +#Parametro self en stackpoiner + 8 +#Parametro map@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable population_map +#Get Local Var map +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 4($t0) #Setea la propiedad population_map con el valor de _ +lw $t0, 8($sp) #Instancia de la clase CellularAutomaton +lw $t1, 4($t0) #Lee la propiedad population_map +move $s4, $t1 #Guarda el valor de la propiedad population_map en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 8($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +CellularAutomaton_print: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch concat +#Get Self Property population_map +lw $t0, 16($sp) #Instancia de la clase CellularAutomaton +lw $t1, 4($t0) #Lee la propiedad population_map +sw $t1, 12($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_concat@0 +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 16($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 16($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 16($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +CellularAutomaton_evolve: # +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var position stackpointer 40 +addi $sp, $sp, -4 #Push local var num stackpointer 36 +addi $sp, $sp, -4 #Push local var temp stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_cell_at_next_evolution@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_evolve +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +#Eval Expression to Let num +#StaticDispatch num_cells +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion num_cells +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let num +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 32($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable temp +#Evalua la Expresion para el DinamicDispatch concat +#Get Local Var temp +lw $t0, 32($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch cell_at_next_evolution +#Evalua el parametro 0 para el CastingDispatch cell_at_next_evolution +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch cell_at_next_evolution +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_cell_at_next_evolution@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell_at_next_evolution@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion cell_at_next_evolution +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 24($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 32($sp) # +lw $t0, 32($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable position +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 44($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var num +lw $t0, 36($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 44($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 44($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable population_map +#Get Local Var temp +lw $t0, 32($sp) # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 4($t0) #Setea la propiedad population_map con el valor de _ +lw $t0, 44($sp) #Instancia de la clase CellularAutomaton +lw $t1, 4($t0) #Lee la propiedad population_map +move $s4, $t1 #Guarda el valor de la propiedad population_map en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 44($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +String_concat: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_concat +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__concat__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +CellularAutomaton_num_cells: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_num_cells +#Evalua la Expresion para el DinamicDispatch length +#Get Self Property population_map +lw $t0, 8($sp) #Instancia de la clase CellularAutomaton +lw $t1, 4($t0) #Lee la propiedad population_map +sw $t1, 4($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_length@0 +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_length@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_length@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +CellularAutomaton_cell_at_next_evolution: # +#Parametro self en stackpoiner + 68 +#Parametro position@0 en stackpoiner + 64 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_cell_left_neighbor@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell_right_neighbor@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell_at_next_evolution +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Get Local Var position +lw $t0, 64($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 68($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_0 # +#Else case +li $s4, 0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_0 # +then_CellularAutomaton_cell_at_next_evolution_0: +#Then case +li $s4, 1 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_0: +#Fin de un If +move $t0, $s4 # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch cell_left_neighbor +#Evalua el parametro 0 para el CastingDispatch cell_left_neighbor +#Get Local Var position +lw $t0, 64($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch cell_left_neighbor +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_cell_left_neighbor@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell_left_neighbor@0 +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion cell_left_neighbor +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 68($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_1 # +#Else case +li $s4, 0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_1 # +then_CellularAutomaton_cell_at_next_evolution_1: +#Then case +li $s4, 1 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_1: +#Fin de un If +move $t0, $s4 # +sw $t0, 40($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 40($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 52($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch cell_right_neighbor +#Evalua el parametro 0 para el CastingDispatch cell_right_neighbor +#Get Local Var position +lw $t0, 64($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell_right_neighbor +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell_right_neighbor@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell_right_neighbor@0 +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell_right_neighbor +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 68($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 8($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_2 # +#Else case +li $s4, 0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_2 # +then_CellularAutomaton_cell_at_next_evolution_2: +#Then case +li $s4, 1 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_2: +#Fin de un If +move $t0, $s4 # +sw $t0, 48($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 60($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 1 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 56($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 68($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 56($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_3 # +#Else case +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_3 # +then_CellularAutomaton_cell_at_next_evolution_3: +#Then case +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 68($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_3: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 72 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +CellularAutomaton_cell: # +#Parametro self en stackpoiner + 20 +#Parametro position@0 en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell +#Evalua la Expresion para el DinamicDispatch substr +#Get Self Property population_map +lw $t0, 20($sp) #Instancia de la clase CellularAutomaton +lw $t1, 4($t0) #Lee la propiedad population_map +sw $t1, 12($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_substr@0 +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var position +lw $t0, 16($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +CellularAutomaton_cell_left_neighbor: # +#Parametro self en stackpoiner + 40 +#Parametro position@0 en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell_left_neighbor +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var position +lw $t0, 36($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_left_neighbor_0 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 36($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 40($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_cell_left_neighbor_0 # +then_CellularAutomaton_cell_left_neighbor_0: +#Then case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion rest +#StaticDispatch num_cells +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion num_cells +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 40($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@1 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_CellularAutomaton_cell_left_neighbor_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 # +jr $ra # + +CellularAutomaton_cell_right_neighbor: # +#Parametro self en stackpoiner + 40 +#Parametro position@0 en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell_right_neighbor +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var position +lw $t0, 36($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando el operado izquierdo de una operacion rest +#StaticDispatch num_cells +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion num_cells +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 40($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_right_neighbor_0 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 36($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 40($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_cell_right_neighbor_0 # +then_CellularAutomaton_cell_right_neighbor_0: +#Then case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +li $s4, 0 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@1 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_CellularAutomaton_cell_right_neighbor_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/cells_input.txt b/tests/codegen/cells_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/cells_output.txt b/tests/codegen/cells_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/complex.mips b/tests/codegen/complex.mips new file mode 100644 index 000000000..28e827df6 --- /dev/null +++ b/tests/codegen/complex.mips @@ -0,0 +1,1115 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +Complex_parents: .word 1, 6, 8, 0, +Complex_Name: .asciiz "Complex" +Complex: .word Complex_Name, 3, Complex_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Complex_init, Complex_print, Complex_reflect_0, Complex_reflect_X, Complex_reflect_Y, +string_0: .asciiz "=(\n" +string_1: .asciiz "=)\n" +string_2: .asciiz "+" +string_3: .asciiz "I" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 52 +addi $sp, $sp, -4 #Push local var c stackpointer 48 +addi $sp, $sp, -4 #Push local var new_Complex@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var ref_eq@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var ref_eq@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_X@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_Y@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_0@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Eval Expression to Let c +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Complex +#Allocate a una class Complex +#atributo type_name en puntero + 0 +#atributo x en puntero + 4 +#atributo y en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 44($sp) #Guardando en la variable local new_Complex@0 puntero de la instancia de la clase Complex +#Assignacion de la insformacion de tipo a la instancia +la $t0, Complex # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 44($sp) #Lee el valor de la var new_Complex@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Complex@0 +jal new_ctr_Complex # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 40($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let c +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion ref_eq +#Evalua la Expresion para el DinamicDispatch reflect_Y +#Evalua la Expresion para el DinamicDispatch reflect_X +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_X +lw $t0, 48($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion reflect_X +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch reflect_Y +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_reflect_Y@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_reflect_Y@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion reflect_Y +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion ref_eq +#Evaluando el operado derecho de una operacion ref_eq +#Evalua la Expresion para el DinamicDispatch reflect_0 +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_0 +lw $t0, 48($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion reflect_0 +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion ref_eq +lw $t0, 28($sp) # +lw $t1, 24($sp) # +seq $a0, $t1, $t0 # +lw $s6, 52($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_0 # +#Else case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_0 # +then_Main_main_0: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Complex: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Complex +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Complex +move $t1, $s4 #Guarda el valor que se le asignara a la propieded x +sw $t1, 4($t0) #Setea la propiedad x con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Complex +move $t1, $s4 #Guarda el valor que se le asignara a la propieded y +sw $t1, 8($t0) #Setea la propiedad y con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Complex_init: # +#Parametro self en stackpoiner + 28 +#Parametro a@0 en stackpoiner + 24 +#Parametro b@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 28($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 16($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var a +lw $t0, 24($sp) # +sw $t0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 28($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@1 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var b +lw $t0, 20($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 28($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +Complex_reflect_X: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_X +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property y +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +move $s4, $t1 #Guarda el valor de la propiedad y en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 12($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Complex_reflect_Y: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_Y +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 8($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property x +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +move $s4, $t1 #Guarda el valor de la propiedad x en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 12($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Complex_reflect_0: # +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_0 +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 16($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property x +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +move $s4, $t1 #Guarda el valor de la propiedad x en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 20($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 20($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@1 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property y +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +move $s4, $t1 #Guarda el valor de la propiedad y en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 20($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 20($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 20($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +Complex_print: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/complex_input.txt b/tests/codegen/complex_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/complex_output.txt b/tests/codegen/complex_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/fib.cl b/tests/codegen/fib.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/fib.mips b/tests/codegen/fib.mips new file mode 100644 index 000000000..9b0eb88d4 --- /dev/null +++ b/tests/codegen/fib.mips @@ -0,0 +1,948 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, Main_fib, +string_0: .asciiz "Enter n to find nth fibonacci number!\n" +string_1: .asciiz "\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_fib@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#StaticDispatch fib +#Evalua el parametro 0 para el CastingDispatch fib +#StaticDispatch in_int +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion in_int +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch fib +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_fib@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_fib@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion fib +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_in_int: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_int +lw $s6, 4($sp) #Guarda self +jal __int__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Main_fib: # +#Parametro self en stackpoiner + 44 +#Parametro i@0 en stackpoiner + 40 +addi $sp, $sp, -4 #Push local var a stackpointer 36 +addi $sp, $sp, -4 #Push local var b stackpointer 32 +addi $sp, $sp, -4 #Push local var c stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_fib +#Eval Expression to Let a +li $s4, 1 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Fin de la asignacion Let a +#Eval Expression to Let b +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Fin de la asignacion Let b +#Eval Expression to Let c +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Fin de la asignacion Let c +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable c +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var a +lw $t0, 36($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Local Var b +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 44($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 28($sp) # +lw $t0, 28($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var i +lw $t0, 40($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 44($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable b +#Get Local Var a +lw $t0, 36($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 32($sp) # +lw $t0, 32($sp) # +move $s4, $t0 # +#Inicio del paso 3 de una sequencia Block +#Asignando un nuevo valor a la variable a +#Get Local Var c +lw $t0, 28($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 36($sp) # +lw $t0, 36($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 40($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 44($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 44($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var c +lw $t0, 28($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/fib_input.txt b/tests/codegen/fib_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/fib_output.txt b/tests/codegen/fib_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/graph.mips b/tests/codegen/graph.mips new file mode 100644 index 000000000..1db004daf --- /dev/null +++ b/tests/codegen/graph.mips @@ -0,0 +1,4151 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Graph_parents: .word 1, 7, 0, +Graph_Name: .asciiz "Graph" +Graph: .word Graph_Name, 3, Graph_parents, Object_abort, Object_copy, Object_type_name, Graph_add_vertice, Graph_print_E, Graph_print_V, +Vertice_parents: .word 1, 6, 8, 0, +Vertice_Name: .asciiz "Vertice" +Vertice: .word Vertice_Name, 3, Vertice_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Vertice_outgoing, Vertice_number, Vertice_init, Vertice_add_out, Vertice_print, +Edge_parents: .word 1, 6, 9, 0, +Edge_Name: .asciiz "Edge" +Edge: .word Edge_Name, 4, Edge_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Edge_init, Edge_print, +EList_parents: .word 1, 6, 10, 0, +EList_Name: .asciiz "EList" +EList: .word EList_Name, 2, EList_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, EList_isNil, EList_head, EList_tail, EList_cons, EList_append, EList_print, +ECons_parents: .word 1, 6, 10, 11, 0, +ECons_Name: .asciiz "ECons" +ECons: .word ECons_Name, 3, ECons_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, ECons_isNil, ECons_head, ECons_tail, EList_cons, EList_append, ECons_print, ECons_init, +VList_parents: .word 1, 6, 12, 0, +VList_Name: .asciiz "VList" +VList: .word VList_Name, 2, VList_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, VList_isNil, VList_head, VList_tail, VList_cons, VList_print, +VCons_parents: .word 1, 6, 12, 13, 0, +VCons_Name: .asciiz "VCons" +VCons: .word VCons_Name, 3, VCons_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, VCons_isNil, VCons_head, VCons_tail, VList_cons, VCons_print, VCons_init, +Parse_parents: .word 1, 6, 14, 0, +Parse_Name: .asciiz "Parse" +Parse: .word Parse_Name, 3, Parse_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Parse_read_input, Parse_parse_line, Parse_c2i, Parse_a2i, Parse_a2i_aux, +Main_parents: .word 1, 6, 14, 15, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 4, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Parse_read_input, Parse_parse_line, Parse_c2i, Parse_a2i, Parse_a2i_aux, Main_main, +BoolOp_parents: .word 1, 16, 0, +BoolOp_Name: .asciiz "BoolOp" +BoolOp: .word BoolOp_Name, 1, BoolOp_parents, Object_abort, Object_copy, Object_type_name, BoolOp_and, BoolOp_or, +string_0: .asciiz " (" +string_1: .asciiz "," +string_2: .asciiz ")" +string_3: .asciiz "\n" +string_4: .asciiz "\n" +string_5: .asciiz "\n" +string_6: .asciiz "" +string_7: .asciiz "0" +string_8: .asciiz "1" +string_9: .asciiz "2" +string_10: .asciiz "3" +string_11: .asciiz "4" +string_12: .asciiz "5" +string_13: .asciiz "6" +string_14: .asciiz "7" +string_15: .asciiz "8" +string_16: .asciiz "9" +string_17: .asciiz "-" +string_18: .asciiz " " +string_19: .asciiz " " +string_20: .asciiz "," +string_21: .asciiz "" +string_22: .asciiz "" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo boolop en puntero + 4 +#atributo rest en puntero + 8 +#atributo g en puntero + 12 +li $a0, 16 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Parse # +#Assignando el resultado de la expression al atributo g de la clase Main +#StaticDispatch read_input +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion read_input +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded g +sw $t1, 12($t0) #Setea la propiedad g con el valor de _ +#Fin De la Asignacion +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_V@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_E@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_V +#Get Self Property g +lw $t0, 12($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad g +sw $t1, 8($sp) #Guarda el valor de la propiedad g en la variable local instance_dynamic_to_print_V@0 +#Fin de la exprecion previa al DinamicDispatch print_V +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_print_V@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_V@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Graph +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion print_V +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_E +#Get Self Property g +lw $t0, 12($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad g +sw $t1, 4($sp) #Guarda el valor de la propiedad g en la variable local instance_dynamic_to_print_E@0 +#Fin de la exprecion previa al DinamicDispatch print_E +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print_E@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_E@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Graph +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion print_E +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Parse: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var new_BoolOp@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Parse +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +#Assignando el resultado de la expression al atributo boolop de la clase Parse +#Creando instancia de tipo BoolOp +#Allocate a una class BoolOp +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_BoolOp@0 puntero de la instancia de la clase BoolOp +#Assignacion de la insformacion de tipo a la instancia +la $t0, BoolOp # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_BoolOp@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_BoolOp@0 +jal new_ctr_BoolOp # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 8($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded boolop +sw $t1, 4($t0) #Setea la propiedad boolop con el valor de _ +#Fin De la Asignacion +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 8($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $v0, 8($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Parse_read_input: # +#Parametro self en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var g stackpointer 52 +addi $sp, $sp, -4 #Push local var new_Graph@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var line stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_add_vertice@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_parse_line@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_add_vertice@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_and@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_and@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_and@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_read_input +#Eval Expression to Let g +#Creando instancia de tipo Graph +#Allocate a una class Graph +#atributo type_name en puntero + 0 +#atributo vertices en puntero + 4 +#atributo edges en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 48($sp) #Guardando en la variable local new_Graph@0 puntero de la instancia de la clase Graph +#Assignacion de la insformacion de tipo a la instancia +la $t0, Graph # +move $s4, $t0 # +lw $t0, 48($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 48($sp) #Lee el valor de la var new_Graph@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Graph@0 +jal new_ctr_Graph # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let g +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let line +#StaticDispatch in_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +sw $v0, 44($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let line +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch add_vertice +#Get Local Var g +lw $t0, 52($sp) # +sw $t0, 40($sp) # +#Fin de la exprecion previa al DinamicDispatch add_vertice +#Evalua el parametro 0 para el CastingDispatch add_vertice +#StaticDispatch parse_line +#Evalua el parametro 0 para el CastingDispatch parse_line +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch parse_line +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 40($sp) #Lee el valor de la var param_0_to_parse_line@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_parse_line@0 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion parse_line +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch add_vertice +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_add_vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_add_vertice@0 +lw $t0, 36($sp) #Lee el valor de la var param_0_to_add_vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_add_vertice@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Graph +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion add_vertice +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable line +#StaticDispatch in_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 44($sp) # +lw $t0, 44($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evalua la Expresion para el DinamicDispatch and +#Get Self Property boolop +lw $t0, 56($sp) #Instancia de la clase Parse +lw $t1, 4($t0) #Lee la propiedad boolop +sw $t1, 28($sp) #Guarda el valor de la propiedad boolop en la variable local instance_dynamic_to_and@0 +#Fin de la exprecion previa al DinamicDispatch and +#Evalua el parametro 0 para el CastingDispatch and +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 56($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +sw $v0, 16($sp) # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch and +#Evalua el parametro 1 para el CastingDispatch and +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var line +lw $t0, 44($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 56($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +sw $v0, 4($sp) # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch and +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_and@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_and@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_and@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_and@0 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de BoolOp +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion and +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 56($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var g +lw $t0, 52($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 60 # +jr $ra # + +Graph_print_V: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_print_V +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property vertices +lw $t0, 8($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +sw $t1, 4($sp) #Guarda el valor de la propiedad vertices en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Graph_print_E: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_print_E +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property edges +lw $t0, 8($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +sw $t1, 4($sp) #Guarda el valor de la propiedad edges en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_BoolOp: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_BoolOp +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Graph: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var new_VList@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var new_EList@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Graph +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +#Assignando el resultado de la expression al atributo vertices de la clase Graph +#Creando instancia de tipo VList +#Allocate a una class VList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 8($sp) #Guardando en la variable local new_VList@0 puntero de la instancia de la clase VList +#Assignacion de la insformacion de tipo a la instancia +la $t0, VList # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 8($sp) #Lee el valor de la var new_VList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_VList@0 +jal new_ctr_VList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 12($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded vertices +sw $t1, 4($t0) #Setea la propiedad vertices con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo edges de la clase Graph +#Creando instancia de tipo EList +#Allocate a una class EList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_EList@0 puntero de la instancia de la clase EList +#Assignacion de la insformacion de tipo a la instancia +la $t0, EList # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_EList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_EList@0 +jal new_ctr_EList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 12($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded edges +sw $t1, 8($t0) #Setea la propiedad edges con el valor de _ +#Fin De la Asignacion +lw $v0, 12($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +IO_in_string: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_string +lw $s6, 4($sp) #Guarda self +jal __str__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Parse_parse_line: # +#Parametro self en stackpoiner + 88 +#Parametro s@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var v stackpointer 80 +addi $sp, $sp, -4 #Push local var new_Vertice@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var succ stackpointer 60 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@1 stackpointer 56 +addi $sp, $sp, -4 #Push local var weight stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@2 stackpointer 48 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_add_out@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var new_Edge@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_number@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_init@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_2_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_add_out@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_parse_line +#Eval Expression to Let v +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Vertice +#Allocate a una class Vertice +#atributo type_name en puntero + 0 +#atributo num en puntero + 4 +#atributo out en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 76($sp) #Guardando en la variable local new_Vertice@0 puntero de la instancia de la clase Vertice +#Assignacion de la insformacion de tipo a la instancia +la $t0, Vertice # +move $s4, $t0 # +lw $t0, 76($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 76($sp) #Lee el valor de la var new_Vertice@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Vertice@0 +jal new_ctr_Vertice # +sw $v0, 72($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Local Var s +lw $t0, 84($sp) # +sw $t0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 72($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch init +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 68($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 80($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let v +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Inicio de un While +j while_cond_1 # +while_back_1: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let succ +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 56($sp) #Guarda el valor de la propiedad rest en la variable local param_0_to_a2i@1 +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 60($sp) #Lee el valor de la var param_0_to_a2i@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@1 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let succ +#Eval Expression to Let weight +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 48($sp) #Guarda el valor de la propiedad rest en la variable local param_0_to_a2i@2 +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 52($sp) #Lee el valor de la var param_0_to_a2i@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@2 +lw $t0, 96($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let weight +#Evalua la Expresion para el DinamicDispatch add_out +#Get Local Var v +lw $t0, 80($sp) # +sw $t0, 44($sp) # +#Fin de la exprecion previa al DinamicDispatch add_out +#Evalua el parametro 0 para el CastingDispatch add_out +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Edge +#Allocate a una class Edge +#atributo type_name en puntero + 0 +#atributo from en puntero + 4 +#atributo to en puntero + 8 +#atributo weight en puntero + 12 +li $a0, 16 # +li $v0, 9 # +syscall +sw $v0, 40($sp) #Guardando en la variable local new_Edge@0 puntero de la instancia de la clase Edge +#Assignacion de la insformacion de tipo a la instancia +la $t0, Edge # +move $s4, $t0 # +lw $t0, 40($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 40($sp) #Lee el valor de la var new_Edge@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Edge@0 +jal new_ctr_Edge # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Evalua la Expresion para el DinamicDispatch number +#Get Local Var v +#Fin de la exprecion previa al DinamicDispatch number +lw $t0, 80($sp) #Lee el valor de la var v +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con v +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion number +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var succ +lw $t0, 60($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 1 al CastingDispatch init +#Evalua el parametro 2 para el CastingDispatch init +#Get Local Var weight +lw $t0, 52($sp) # +sw $t0, 20($sp) # +#Fin del paramentro 2 al CastingDispatch init +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@1 +lw $t0, 32($sp) #Lee el valor de la var param_0_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@1 +lw $t0, 32($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 32($sp) #Lee el valor de la var param_2_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_2_to_init@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch add_out +lw $t0, 44($sp) #Lee el valor de la var instance_dynamic_to_add_out@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_add_out@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_add_out@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_add_out@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion add_out +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evaluando la expression de una operacion unaria +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Self Property rest +lw $t0, 88($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +sw $t1, 4($sp) #Guarda el valor de la propiedad rest en la variable local instance_dynamic_to_length@0 +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_length@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_length@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 88($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var v +lw $t0, 80($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +Graph_add_vertice: # +#Parametro self en stackpoiner + 28 +#Parametro v@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_outgoing@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_append@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_append@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Graph_add_vertice +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable edges +#Evalua la Expresion para el DinamicDispatch append +#Evalua la Expresion para el DinamicDispatch outgoing +#Get Local Var v +#Fin de la exprecion previa al DinamicDispatch outgoing +lw $t0, 24($sp) #Lee el valor de la var v@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con v@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion outgoing +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch append +#Evalua el parametro 0 para el CastingDispatch append +#Get Self Property edges +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +sw $t1, 12($sp) #Guarda el valor de la propiedad edges en la variable local param_0_to_append@0 +#Fin del paramentro 0 al CastingDispatch append +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_append@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_append@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion append +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 28($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded edges +sw $t1, 8($t0) #Setea la propiedad edges con el valor de _ +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 8($t0) #Lee la propiedad edges +move $s4, $t1 #Guarda el valor de la propiedad edges en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable vertices +#Evalua la Expresion para el DinamicDispatch cons +#Get Self Property vertices +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +sw $t1, 8($sp) #Guarda el valor de la propiedad vertices en la variable local instance_dynamic_to_cons@0 +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var v +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 28($sp) #Instancia de la clase Graph +move $t1, $s4 #Guarda el valor que se le asignara a la propieded vertices +sw $t1, 4($t0) #Setea la propiedad vertices con el valor de _ +lw $t0, 28($sp) #Instancia de la clase Graph +lw $t1, 4($t0) #Lee la propiedad vertices +move $s4, $t1 #Guarda el valor de la propiedad vertices en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +BoolOp_and: # +#Parametro self en stackpoiner + 12 +#Parametro b1@0 en stackpoiner + 8 +#Parametro b2@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion BoolOp_and +#Evalua la condicion de un If +#Get Local Var b1 +lw $t0, 8($sp) # +move $s4, $t0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_BoolOp_and_0 # +#Else case +li $s4, 0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_BoolOp_and_0 # +then_BoolOp_and_0: +#Then case +#Get Local Var b2 +lw $t0, 4($sp) # +move $s4, $t0 # +fin_BoolOp_and_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Vertice_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property num +lw $t0, 12($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +sw $t1, 8($sp) #Guarda el valor de la propiedad num en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property out +lw $t0, 12($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +sw $t1, 4($sp) #Guarda el valor de la propiedad out en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Edge_print: # +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Edge_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property from +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 4($t0) #Lee la propiedad from +sw $t1, 20($sp) #Guarda el valor de la propiedad from en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property to +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 8($t0) #Lee la propiedad to +sw $t1, 12($sp) #Guarda el valor de la propiedad to en la variable local param_0_to_out_int@1 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_int@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 5 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property weight +lw $t0, 28($sp) #Instancia de la clase Edge +lw $t1, 12($t0) #Lee la propiedad weight +sw $t1, 4($sp) #Guarda el valor de la propiedad weight en la variable local param_0_to_out_int@2 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_int@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +EList_print: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_print +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +ECons_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property car +lw $t0, 12($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +sw $t1, 8($sp) #Guarda el valor de la propiedad car en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Edge +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cdr +lw $t0, 12($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +sw $t1, 4($sp) #Guarda el valor de la propiedad cdr en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +VList_print: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_print +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +VCons_print: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_print +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property car +lw $t0, 12($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +sw $t1, 8($sp) #Guarda el valor de la propiedad car en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Vertice +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cdr +lw $t0, 12($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +sw $t1, 4($sp) #Guarda el valor de la propiedad cdr en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_VList: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_VList +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase VList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_EList: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_EList +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase EList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Vertice: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var new_EList@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Vertice +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded num +sw $t1, 4($t0) #Setea la propiedad num con el valor de _ +#Assignando el resultado de la expression al atributo out de la clase Vertice +#Creando instancia de tipo EList +#Allocate a una class EList +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_EList@0 puntero de la instancia de la clase EList +#Assignacion de la insformacion de tipo a la instancia +la $t0, EList # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_EList@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_EList@0 +jal new_ctr_EList # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 8($t0) #Setea la propiedad out con el valor de _ +#Fin De la Asignacion +lw $v0, 8($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Parse_a2i: # +#Parametro self en stackpoiner + 120 +#Parametro s@0 en stackpoiner + 116 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_a2i@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_a2i_aux@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_a2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 112($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 108($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 108($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 92($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 88($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 84($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 92($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 92($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 100($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_17 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 96($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 100($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 96($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 72($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 72($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 72($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 80($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_18 # +move $s4, $t0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 120($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 120($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_2 # +#Else case +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 64($sp) #Lee el valor de la var param_0_to_a2i_aux@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Parse_a2i_2 # +then_Parse_a2i_2: +#Then case +#StaticDispatch a2i +#Evalua el parametro 0 para el CastingDispatch a2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 56($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 36($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 56($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 44($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_a2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i@0 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion a2i +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Parse_a2i_2: +#Fin de un If +j fin_Parse_a2i_1 # +then_Parse_a2i_1: +#Then case +#Evaluando la expression de una operacion unaria +#StaticDispatch a2i_aux +#Evalua el parametro 0 para el CastingDispatch a2i_aux +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 116($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 116($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 120($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 120($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 16($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch a2i_aux +lw $t0, 120($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_a2i_aux@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_a2i_aux@1 +lw $t0, 128($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion a2i_aux +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#FIN expression de una operacion unaria +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +fin_Parse_a2i_1: +#Fin de un If +j fin_Parse_a2i_0 # +then_Parse_a2i_0: +#Then case +li $s4, 0 # +lw $s6, 120($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_a2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 124 # +jr $ra # + +Parse_a2i_aux: # +#Parametro self en stackpoiner + 192 +#Parametro s@0 en stackpoiner + 188 +addi $sp, $sp, -4 #Push local var int stackpointer 184 +addi $sp, $sp, -4 #Push local var j stackpointer 180 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 176 +addi $sp, $sp, -4 #Push local var i stackpointer 172 +addi $sp, $sp, -4 #Push local var c stackpointer 168 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 164 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 160 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 156 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 152 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 148 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 144 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 140 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 136 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 132 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 128 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 124 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 120 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 116 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 112 +addi $sp, $sp, -4 #Push local var param_0_to_c2i@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 104 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 100 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 88 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 84 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 80 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 76 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@3 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_a@3 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_b@3 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_substr@3 stackpointer 36 +addi $sp, $sp, -4 #Push local var rest@_a@2 stackpointer 32 +addi $sp, $sp, -4 #Push local var rest@_b@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_1_to_substr@3 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_a2i_aux +#Eval Expression to Let int +li $s4, 0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 184($sp) # +#Fin de la asignacion Let int +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Eval Expression to Let j +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 180($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let j +#Eval Expression to Let i +li $s4, 0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 172($sp) # +#Fin de la asignacion Let i +#Inicio de un While +j while_cond_2 # +while_back_2: +#Eval Expression to Let c +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 164($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 160($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 156($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 164($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 164($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 164($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 176($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 168($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let c +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var c +lw $t0, 168($sp) # +sw $t0, 152($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_19 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 148($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 152($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 148($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var c +lw $t0, 168($sp) # +sw $t0, 144($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_20 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 140($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 144($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 140($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_1 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable int +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion factor +#Get Local Var int +lw $t0, 184($sp) # +sw $t0, 128($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +li $s4, 10 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 124($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 192($sp) #Guarda self +lw $a0, 128($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 124($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 136($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch c2i +#Evalua el parametro 0 para el CastingDispatch c2i +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 120($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 116($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 112($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 120($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 120($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 120($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 132($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 108($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch c2i +lw $t0, 192($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 112($sp) #Lee el valor de la var param_0_to_c2i@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_c2i@0 +lw $t0, 200($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion c2i +jal $t3 # +sw $v0, 132($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 136($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 132($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 184($sp) # +lw $t0, 184($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 104($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 100($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 104($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 100($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 96($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var j +lw $t0, 180($sp) # +sw $t0, 92($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 192($sp) #Guarda self +lw $a0, 96($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 92($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_a2i_aux_2 # +#Else case +la $t0, string_21 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_Parse_a2i_aux_2 # +then_Parse_a2i_aux_2: +#Then case +#Asignando un nuevo valor a la variable rest +la $t0, string_22 # +move $s4, $t0 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +fin_Parse_a2i_aux_2: +#Fin de un If +j fin_Parse_a2i_aux_1 # +then_Parse_a2i_aux_1: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rest +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 88($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 84($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 80($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 84($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 80($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 76($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 60($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 60($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 72($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 68($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 52($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 88($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 80($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 60($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 100($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Get Local Var j +lw $t0, 180($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +fin_Parse_a2i_aux_1: +#Fin de un If +j fin_Parse_a2i_aux_0 # +then_Parse_a2i_aux_0: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rest +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 188($sp) # +sw $t0, 48($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 192($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> sum@_a@3 +lw $a1, 40($sp) #Guarda el parametro 1 -> sum@_b@3 +jal __int__sum__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 188($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 192($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 20($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> rest@_a@3 +lw $a1, 20($sp) #Guarda el parametro 1 -> rest@_b@3 +jal __int__sub__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 192($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 192($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> rest@_a@2 +lw $a1, 28($sp) #Guarda el parametro 1 -> rest@_b@2 +jal __int__sub__ # +sw $v0, 12($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 48($sp) #Lee el valor de la var instance_dynamic_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@3 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@3 +lw $t0, 20($sp) #Lee el valor de la var param_1_to_substr@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@3 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 192($sp) #Instancia de la clase Parse +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rest +sw $t1, 8($t0) #Setea la propiedad rest con el valor de _ +lw $t0, 192($sp) #Instancia de la clase Parse +lw $t1, 8($t0) #Lee la propiedad rest +move $s4, $t1 #Guarda el valor de la propiedad rest en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Get Local Var j +lw $t0, 180($sp) # +move $s4, $t0 # +move $t0, $s4 # +sw $t0, 172($sp) # +lw $t0, 172($sp) # +move $s4, $t0 # +fin_Parse_a2i_aux_0: +#Fin de un If +#Fin del cuerpo e inicio de la condicion de un While +while_cond_2: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 172($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var j +lw $t0, 180($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 192($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 192($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_2 # +#Fin de la condicion de un While +lw $t0, 192($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var int +lw $t0, 184($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 196 # +jr $ra # + +Vertice_init: # +#Parametro self en stackpoiner + 8 +#Parametro n@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable num +#Get Local Var n +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded num +sw $t1, 4($t0) #Setea la propiedad num con el valor de _ +lw $t0, 8($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +move $s4, $t1 #Guarda el valor de la propiedad num en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 8($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Edge_init: # +#Parametro self en stackpoiner + 16 +#Parametro f@0 en stackpoiner + 12 +#Parametro t@0 en stackpoiner + 8 +#Parametro w@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Edge_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable from +#Get Local Var f +lw $t0, 12($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded from +sw $t1, 4($t0) #Setea la propiedad from con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 4($t0) #Lee la propiedad from +move $s4, $t1 #Guarda el valor de la propiedad from en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable to +#Get Local Var t +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded to +sw $t1, 8($t0) #Setea la propiedad to con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 8($t0) #Lee la propiedad to +move $s4, $t1 #Guarda el valor de la propiedad to en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable weight +#Get Local Var w +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded weight +sw $t1, 12($t0) #Setea la propiedad weight con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Edge +lw $t1, 12($t0) #Lee la propiedad weight +move $s4, $t1 #Guarda el valor de la propiedad weight en la variable local _ +#Inicio del paso 3 de una sequencia Block +#Get Local Var self +lw $t0, 16($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +ECons_init: # +#Parametro self en stackpoiner + 12 +#Parametro e@0 en stackpoiner + 8 +#Parametro rest@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable car +#Get Local Var e +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase EList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $t0, 12($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable cdr +#Get Local Var rest +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase ECons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +VCons_init: # +#Parametro self en stackpoiner + 12 +#Parametro v@0 en stackpoiner + 8 +#Parametro rest@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable car +#Get Local Var v +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase VList +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $t0, 12($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable cdr +#Get Local Var rest +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase VCons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Edge: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Edge +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded from +sw $t1, 4($t0) #Setea la propiedad from con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded to +sw $t1, 8($t0) #Setea la propiedad to con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Edge +move $t1, $s4 #Guarda el valor que se le asignara a la propieded weight +sw $t1, 12($t0) #Setea la propiedad weight con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Vertice_number: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_number +#Get Self Property num +lw $t0, 4($sp) #Instancia de la clase Vertice +lw $t1, 4($t0) #Lee la propiedad num +move $s4, $t1 #Guarda el valor de la propiedad num en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Vertice_add_out: # +#Parametro self en stackpoiner + 16 +#Parametro s@0 en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_add_out +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable out +#Evalua la Expresion para el DinamicDispatch cons +#Get Self Property out +lw $t0, 16($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +sw $t1, 8($sp) #Guarda el valor de la propiedad out en la variable local instance_dynamic_to_cons@0 +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#Get Local Var s +lw $t0, 12($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 16($sp) #Instancia de la clase Vertice +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 8($t0) #Setea la propiedad out con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 16($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Vertice_outgoing: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Vertice_outgoing +#Get Self Property out +lw $t0, 4($sp) #Instancia de la clase Vertice +lw $t1, 8($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_append: # +#Parametro self en stackpoiner + 28 +#Parametro l@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_isNil@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_append@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_append@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_append +#Evalua la condicion de un If +#Evalua la Expresion para el DinamicDispatch isNil +#Get Local Var self +#Fin de la exprecion previa al DinamicDispatch isNil +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion isNil +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_EList_append_0 # +#Else case +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch append +#StaticDispatch tail +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion tail +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch append +#Evalua el parametro 0 para el CastingDispatch append +#Get Local Var l +lw $t0, 24($sp) # +sw $t0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch append +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_append@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_append@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_append@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion append +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +#StaticDispatch head +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion head +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_EList_append_0 # +then_EList_append_0: +#Then case +#Get Local Var l +lw $t0, 24($sp) # +move $s4, $t0 # +fin_EList_append_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +EList_cons: # +#Parametro self en stackpoiner + 24 +#Parametro e@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_ECons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_cons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo ECons +#Allocate a una class ECons +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +#atributo cdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_ECons@0 puntero de la instancia de la clase ECons +#Assignacion de la insformacion de tipo a la instancia +la $t0, ECons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_ECons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_ECons@0 +jal new_ctr_ECons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var e +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de ECons +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +VList_cons: # +#Parametro self en stackpoiner + 24 +#Parametro v@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_VCons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_cons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo VCons +#Allocate a una class VCons +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +#atributo cdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_VCons@0 puntero de la instancia de la clase VCons +#Assignacion de la insformacion de tipo a la instancia +la $t0, VCons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_VCons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_VCons@0 +jal new_ctr_VCons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var v +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VCons +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +Parse_c2i: # +#Parametro self en stackpoiner + 88 +#Parametro char@0 en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 64 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 52 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 32 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 20 +addi $sp, $sp, -4 #Push local var str_eq@_a@8 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_b@8 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@9 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@9 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Parse_c2i +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 76($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 60($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 52($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 36($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_13 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 28($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_14 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_15 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> str_eq@_a@8 +lw $a1, 12($sp) #Guarda el parametro 1 -> str_eq@_b@8 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var char +lw $t0, 84($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_16 # +move $s4, $t0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 88($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@9 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@9 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 88($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Parse_c2i_9 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 88($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Parse +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_Parse_c2i_9 # +then_Parse_c2i_9: +#Then case +li $s4, 9 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_9: +#Fin de un If +j fin_Parse_c2i_8 # +then_Parse_c2i_8: +#Then case +li $s4, 8 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_8: +#Fin de un If +j fin_Parse_c2i_7 # +then_Parse_c2i_7: +#Then case +li $s4, 7 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_7: +#Fin de un If +j fin_Parse_c2i_6 # +then_Parse_c2i_6: +#Then case +li $s4, 6 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_6: +#Fin de un If +j fin_Parse_c2i_5 # +then_Parse_c2i_5: +#Then case +li $s4, 5 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_5: +#Fin de un If +j fin_Parse_c2i_4 # +then_Parse_c2i_4: +#Then case +li $s4, 4 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_4: +#Fin de un If +j fin_Parse_c2i_3 # +then_Parse_c2i_3: +#Then case +li $s4, 3 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_3: +#Fin de un If +j fin_Parse_c2i_2 # +then_Parse_c2i_2: +#Then case +li $s4, 2 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_2: +#Fin de un If +j fin_Parse_c2i_1 # +then_Parse_c2i_1: +#Then case +li $s4, 1 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_1: +#Fin de un If +j fin_Parse_c2i_0 # +then_Parse_c2i_0: +#Then case +li $s4, 0 # +lw $s6, 88($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_Parse_c2i_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 92 # +jr $ra # + +EList_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_isNil +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_isNil +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_isNil +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_isNil +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_tail +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_tail +#Get Self Property cdr +lw $t0, 4($sp) #Instancia de la clase ECons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_tail +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_tail +#Get Self Property cdr +lw $t0, 4($sp) #Instancia de la clase VCons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +EList_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion EList_head +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de EList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +ECons_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion ECons_head +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase EList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VList_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VList_head +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de VList +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +VCons_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion VCons_head +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase VList +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_ECons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_ECons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_EList # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase ECons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_VCons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_VCons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_VList # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase VCons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +BoolOp_or: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/graph_input.txt b/tests/codegen/graph_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/graph_output.txt b/tests/codegen/graph_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/hairyscary.mips b/tests/codegen/hairyscary.mips new file mode 100644 index 000000000..e4853be7f --- /dev/null +++ b/tests/codegen/hairyscary.mips @@ -0,0 +1,1729 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Foo_parents: .word 1, 6, 7, 8, 0, +Foo_Name: .asciiz "Foo" +Foo: .word Foo_Name, 6, Foo_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Bazz_printh, Foo_doh, +Bar_parents: .word 1, 6, 7, 8, 9, 10, 0, +Bar_Name: .asciiz "Bar" +Bar: .word Bar_Name, 10, Bar_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Bazz_printh, Foo_doh, +Razz_parents: .word 1, 6, 7, 8, 9, 0, +Razz_Name: .asciiz "Razz" +Razz: .word Razz_Name, 8, Razz_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Bazz_printh, Foo_doh, +Bazz_parents: .word 1, 6, 7, 0, +Bazz_Name: .asciiz "Bazz" +Bazz: .word Bazz_Name, 4, Bazz_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Bazz_printh, Bazz_doh, +Main_parents: .word 1, 11, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 5, Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, +string_0: .asciiz "do nothing" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo a en puntero + 4 +#atributo b en puntero + 8 +#atributo c en puntero + 12 +#atributo d en puntero + 16 +li $a0, 20 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_Bazz@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_Foo@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var new_Razz@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var new_Bar@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +#Assignando el resultado de la expression al atributo a de la clase Main +#Creando instancia de tipo Bazz +#Allocate a una class Bazz +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +li $a0, 16 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_Bazz@0 puntero de la instancia de la clase Bazz +#Assignacion de la insformacion de tipo a la instancia +la $t0, Bazz # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_Bazz@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Bazz@0 +jal new_ctr_Bazz # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 20($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded a +sw $t1, 4($t0) #Setea la propiedad a con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo b de la clase Main +#Creando instancia de tipo Foo +#Allocate a una class Foo +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +li $a0, 24 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_Foo@0 puntero de la instancia de la clase Foo +#Assignacion de la insformacion de tipo a la instancia +la $t0, Foo # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_Foo@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Foo@0 +jal new_ctr_Foo # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 20($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded b +sw $t1, 8($t0) #Setea la propiedad b con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo c de la clase Main +#Creando instancia de tipo Razz +#Allocate a una class Razz +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +li $a0, 32 # +li $v0, 9 # +syscall +sw $v0, 8($sp) #Guardando en la variable local new_Razz@0 puntero de la instancia de la clase Razz +#Assignacion de la insformacion de tipo a la instancia +la $t0, Razz # +move $s4, $t0 # +lw $t0, 8($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 8($sp) #Lee el valor de la var new_Razz@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Razz@0 +jal new_ctr_Razz # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 20($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded c +sw $t1, 12($t0) #Setea la propiedad c con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo d de la clase Main +#Creando instancia de tipo Bar +#Allocate a una class Bar +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +#atributo c en puntero + 32 +#atributo d en puntero + 36 +li $a0, 40 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_Bar@0 puntero de la instancia de la clase Bar +#Assignacion de la insformacion de tipo a la instancia +la $t0, Bar # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_Bar@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Bar@0 +jal new_ctr_Bar # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 20($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded d +sw $t1, 16($t0) #Setea la propiedad d con el valor de _ +#Fin De la Asignacion +lw $v0, 20($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bazz: # +#Parametro self en stackpoiner + 40 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var n stackpointer 28 +addi $sp, $sp, -4 #Push local var n stackpointer 24 +addi $sp, $sp, -4 #Push local var new_Bar@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var n stackpointer 16 +addi $sp, $sp, -4 #Push local var new_Razz@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var n stackpointer 8 +addi $sp, $sp, -4 #Push local var new_Foo@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Bazz +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +#Assignando el resultado de la expression al atributo h de la clase Bazz +li $s4, 1 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 40($sp) #Instancia de la clase Bazz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded h +sw $t1, 4($t0) #Setea la propiedad h con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo g de la clase Bazz +#Eval Expression To Case +#Get Local Var self +lw $t0, 40($sp) # +sw $t0, 36($sp) # +lw $t0, 36($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 32($sp) # +#Final Expression To Case +#Check Type To Case When Option Is Bar +li $s4, 10 # +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Bar_step_case_2 # +#Check Type To Case When Option Is Razz +li $s4, 9 # +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Razz_step_case_2 # +#Check Type To Case When Option Is Foo +li $s4, 8 # +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Foo_step_case_1 # +#Check Type To Case When Option Is Bazz +li $s4, 7 # +lw $s6, 40($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 40($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Bazz_step_case_0 # +Bar_step_case_2: +#Assigan el valor de la expresion a la var n del case +lw $t0, 36($sp) # +sw $t0, 28($sp) # +#Eval Expression Of Bar Option +#Get Local Var n +lw $t0, 28($sp) # +move $s4, $t0 # +j case_end_2 # +Razz_step_case_2: +#Assigan el valor de la expresion a la var n del case +lw $t0, 36($sp) # +sw $t0, 28($sp) # +#Eval Expression Of Razz Option +#Creando instancia de tipo Bar +#Allocate a una class Bar +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +#atributo c en puntero + 32 +#atributo d en puntero + 36 +li $a0, 40 # +li $v0, 9 # +syscall +sw $v0, 20($sp) #Guardando en la variable local new_Bar@0 puntero de la instancia de la clase Bar +#Assignacion de la insformacion de tipo a la instancia +la $t0, Bar # +move $s4, $t0 # +lw $t0, 20($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 20($sp) #Lee el valor de la var new_Bar@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Bar@0 +jal new_ctr_Bar # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_2 # +Foo_step_case_1: +#Assigan el valor de la expresion a la var n del case +lw $t0, 36($sp) # +sw $t0, 28($sp) # +#Eval Expression Of Foo Option +#Creando instancia de tipo Razz +#Allocate a una class Razz +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +li $a0, 32 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_Razz@0 puntero de la instancia de la clase Razz +#Assignacion de la insformacion de tipo a la instancia +la $t0, Razz # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_Razz@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Razz@0 +jal new_ctr_Razz # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_2 # +Bazz_step_case_0: +#Assigan el valor de la expresion a la var n del case +lw $t0, 36($sp) # +sw $t0, 28($sp) # +#Eval Expression Of Bazz Option +#Creando instancia de tipo Foo +#Allocate a una class Foo +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +li $a0, 24 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_Foo@0 puntero de la instancia de la clase Foo +#Assignacion de la insformacion de tipo a la instancia +la $t0, Foo # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_Foo@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Foo@0 +jal new_ctr_Foo # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_2 # +case_end_2: +lw $t0, 40($sp) #Instancia de la clase Bazz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded g +sw $t1, 8($t0) #Setea la propiedad g con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo i de la clase Bazz +#StaticDispatch printh +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bazz +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion printh +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 40($sp) #Instancia de la clase Bazz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded i +sw $t1, 12($t0) #Setea la propiedad i con el valor de _ +#Fin De la Asignacion +lw $v0, 40($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 # +jr $ra # + +new_ctr_Foo: # +#Parametro self en stackpoiner + 64 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var n stackpointer 52 +addi $sp, $sp, -4 #Push local var n stackpointer 48 +addi $sp, $sp, -4 #Push local var new_Bar@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var n stackpointer 40 +addi $sp, $sp, -4 #Push local var new_Razz@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_doh@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_doh@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Foo +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Bazz # +#Assignando el resultado de la expression al atributo a de la clase Foo +#Eval Expression To Case +#Get Local Var self +lw $t0, 64($sp) # +sw $t0, 60($sp) # +lw $t0, 60($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 56($sp) # +#Final Expression To Case +#Check Type To Case When Option Is Bar +li $s4, 10 # +lw $s6, 64($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Bar_step_case_0 # +#Check Type To Case When Option Is Razz +li $s4, 9 # +lw $s6, 64($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Razz_step_case_0 # +#Check Type To Case When Option Is Foo +li $s4, 8 # +lw $s6, 64($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Foo_step_case_0 # +Bar_step_case_0: +#Assigan el valor de la expresion a la var n del case +lw $t0, 60($sp) # +sw $t0, 52($sp) # +#Eval Expression Of Bar Option +#Get Local Var n +lw $t0, 52($sp) # +move $s4, $t0 # +j case_end_0 # +Razz_step_case_0: +#Assigan el valor de la expresion a la var n del case +lw $t0, 60($sp) # +sw $t0, 52($sp) # +#Eval Expression Of Razz Option +#Creando instancia de tipo Bar +#Allocate a una class Bar +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +#atributo c en puntero + 32 +#atributo d en puntero + 36 +li $a0, 40 # +li $v0, 9 # +syscall +sw $v0, 44($sp) #Guardando en la variable local new_Bar@0 puntero de la instancia de la clase Bar +#Assignacion de la insformacion de tipo a la instancia +la $t0, Bar # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 44($sp) #Lee el valor de la var new_Bar@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Bar@0 +jal new_ctr_Bar # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +Foo_step_case_0: +#Assigan el valor de la expresion a la var n del case +lw $t0, 60($sp) # +sw $t0, 52($sp) # +#Eval Expression Of Foo Option +#Creando instancia de tipo Razz +#Allocate a una class Razz +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +li $a0, 32 # +li $v0, 9 # +syscall +sw $v0, 36($sp) #Guardando en la variable local new_Razz@0 puntero de la instancia de la clase Razz +#Assignacion de la insformacion de tipo a la instancia +la $t0, Razz # +move $s4, $t0 # +lw $t0, 36($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 36($sp) #Lee el valor de la var new_Razz@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Razz@0 +jal new_ctr_Razz # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_0 # +case_end_0: +lw $t0, 64($sp) #Instancia de la clase Foo +move $t1, $s4 #Guarda el valor que se le asignara a la propieded a +sw $t1, 16($t0) #Setea la propiedad a con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo b de la clase Foo +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evalua la Expresion para el DinamicDispatch doh +#Get Self Property a +lw $t0, 64($sp) #Instancia de la clase Foo +lw $t1, 16($t0) #Lee la propiedad a +sw $t1, 8($sp) #Guarda el valor de la propiedad a en la variable local instance_dynamic_to_doh@0 +#Fin de la exprecion previa al DinamicDispatch doh +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_doh@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_doh@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Razz +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la Expresion para el DinamicDispatch doh +#Get Self Property g +lw $t0, 64($sp) #Instancia de la clase Bazz +lw $t1, 8($t0) #Lee la propiedad g +sw $t1, 4($sp) #Guarda el valor de la propiedad g en la variable local instance_dynamic_to_doh@1 +#Fin de la exprecion previa al DinamicDispatch doh +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_doh@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_doh@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Foo +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 64($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 24($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch doh +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Foo +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 64($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 20($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 32($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch printh +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Foo +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion printh +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 64($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 28($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Foo +move $t1, $s4 #Guarda el valor que se le asignara a la propieded b +sw $t1, 20($t0) #Setea la propiedad b con el valor de _ +#Fin De la Asignacion +lw $v0, 64($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 68 # +jr $ra # + +new_ctr_Razz: # +#Parametro self en stackpoiner + 68 +addi $sp, $sp, -4 #Push local var cond@expr@value@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var cond@type@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var n stackpointer 56 +addi $sp, $sp, -4 #Push local var n stackpointer 52 +addi $sp, $sp, -4 #Push local var new_Bar@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@3 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_Bazz_to_doh@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_doh@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_doh@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Razz +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Foo # +#Assignando el resultado de la expression al atributo e de la clase Razz +#Eval Expression To Case +#Get Local Var self +lw $t0, 68($sp) # +sw $t0, 64($sp) # +lw $t0, 64($sp) # +lw $t1, ($t0) #Lee la propiedad **type** de la instancia +lw $t0, 8($t1) #Lee la propiedad **parents** de la propiedad **type** +sw $t0, 60($sp) # +#Final Expression To Case +#Check Type To Case When Option Is Bar +li $s4, 10 # +lw $s6, 68($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Bar_step_case_1 # +#Check Type To Case When Option Is Razz +li $s4, 9 # +lw $s6, 68($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> cond@type@0 +move $a1, $s4 #Guarda el parametro 1 -> _ +jal __bool__check__type__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 68($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, Razz_step_case_1 # +Bar_step_case_1: +#Assigan el valor de la expresion a la var n del case +lw $t0, 64($sp) # +sw $t0, 56($sp) # +#Eval Expression Of Bar Option +#Get Local Var n +lw $t0, 56($sp) # +move $s4, $t0 # +j case_end_1 # +Razz_step_case_1: +#Assigan el valor de la expresion a la var n del case +lw $t0, 64($sp) # +sw $t0, 56($sp) # +#Eval Expression Of Razz Option +#Creando instancia de tipo Bar +#Allocate a una class Bar +#atributo type_name en puntero + 0 +#atributo h en puntero + 4 +#atributo g en puntero + 8 +#atributo i en puntero + 12 +#atributo a en puntero + 16 +#atributo b en puntero + 20 +#atributo e en puntero + 24 +#atributo f en puntero + 28 +#atributo c en puntero + 32 +#atributo d en puntero + 36 +li $a0, 40 # +li $v0, 9 # +syscall +sw $v0, 48($sp) #Guardando en la variable local new_Bar@0 puntero de la instancia de la clase Bar +#Assignacion de la insformacion de tipo a la instancia +la $t0, Bar # +move $s4, $t0 # +lw $t0, 48($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 48($sp) #Lee el valor de la var new_Bar@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Bar@0 +jal new_ctr_Bar # +move $s4, $v0 #Asigna el resultado de la funcion +j case_end_1 # +case_end_1: +lw $t0, 68($sp) #Instancia de la clase Razz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded e +sw $t1, 24($t0) #Setea la propiedad e con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo f de la clase Razz +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evalua la Expresion para el CastingDispatch doh +#Get Self Property a +lw $t0, 68($sp) #Instancia de la clase Foo +lw $t1, 16($t0) #Lee la propiedad a +sw $t1, 12($sp) #Guarda el valor de la propiedad a en la variable local instance_Bazz_to_doh@0 +#Fin de la exprecion previa al CastingDispatch doh +lw $t0, 12($sp) #Lee el valor de la var instance_Bazz_to_doh@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_Bazz_to_doh@0 +jal Bazz_doh # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la Expresion para el DinamicDispatch doh +#Get Self Property g +lw $t0, 68($sp) #Instancia de la clase Bazz +lw $t1, 8($t0) #Lee la propiedad g +sw $t1, 8($sp) #Guarda el valor de la propiedad g en la variable local instance_dynamic_to_doh@0 +#Fin de la exprecion previa al DinamicDispatch doh +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_doh@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_doh@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Foo +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@3 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@3 +jal __int__sum__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la Expresion para el DinamicDispatch doh +#Get Self Property e +lw $t0, 68($sp) #Instancia de la clase Razz +lw $t1, 24($t0) #Lee la propiedad e +sw $t1, 4($sp) #Guarda el valor de la propiedad e en la variable local instance_dynamic_to_doh@1 +#Fin de la exprecion previa al DinamicDispatch doh +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_doh@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_doh@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bar +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 24($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch doh +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Razz +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 32($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 44($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#StaticDispatch printh +lw $t0, 68($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Razz +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion printh +jal $t3 # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion sum +lw $s6, 68($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 68($sp) #Instancia de la clase Razz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded f +sw $t1, 28($t0) #Setea la propiedad f con el valor de _ +#Fin De la Asignacion +lw $v0, 68($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 72 # +jr $ra # + +new_ctr_Bar: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Bar +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Razz # +#Assignando el resultado de la expression al atributo c de la clase Bar +#StaticDispatch doh +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bar +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion doh +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 4($sp) #Instancia de la clase Bar +move $t1, $s4 #Guarda el valor que se le asignara a la propieded c +sw $t1, 32($t0) #Setea la propiedad c con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo d de la clase Bar +#StaticDispatch printh +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bar +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion printh +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 4($sp) #Instancia de la clase Bar +move $t1, $s4 #Guarda el valor que se le asignara a la propieded d +sw $t1, 36($t0) #Setea la propiedad d con el valor de _ +#Fin De la Asignacion +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Bazz_printh: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Bazz_printh +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property h +lw $t0, 8($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +sw $t1, 4($sp) #Guarda el valor de la propiedad h en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bazz +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Foo_doh: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var i stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Foo_doh +#Eval Expression to Let i +#Get Self Property h +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +sw $t1, 12($sp) #Guarda el valor de la propiedad h en la variable local i +#Fin de la asignacion Let i +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable h +#Evaluando el operado izquierdo de una operacion sum +#Get Self Property h +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +sw $t1, 8($sp) #Guarda el valor de la propiedad h en la variable local sum@_a@0 +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 2 # +lw $s6, 16($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 16($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 16($sp) #Instancia de la clase Bazz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded h +sw $t1, 4($t0) #Setea la propiedad h con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +move $s4, $t1 #Guarda el valor de la propiedad h en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var i +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +Bazz_doh: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var i stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Bazz_doh +#Eval Expression to Let i +#Get Self Property h +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +sw $t1, 12($sp) #Guarda el valor de la propiedad h en la variable local i +#Fin de la asignacion Let i +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable h +#Evaluando el operado izquierdo de una operacion sum +#Get Self Property h +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +sw $t1, 8($sp) #Guarda el valor de la propiedad h en la variable local sum@_a@0 +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 16($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 16($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 16($sp) #Instancia de la clase Bazz +move $t1, $s4 #Guarda el valor que se le asignara a la propieded h +sw $t1, 4($t0) #Setea la propiedad h con el valor de _ +lw $t0, 16($sp) #Instancia de la clase Bazz +lw $t1, 4($t0) #Lee la propiedad h +move $s4, $t1 #Guarda el valor de la propiedad h en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Get Local Var i +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/hairyscary_input.txt b/tests/codegen/hairyscary_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/hairyscary_output.txt b/tests/codegen/hairyscary_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/hello_world.mips b/tests/codegen/hello_world.mips new file mode 100644 index 000000000..d18336e49 --- /dev/null +++ b/tests/codegen/hello_world.mips @@ -0,0 +1,712 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "Hello, World.\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/hello_world_input.txt b/tests/codegen/hello_world_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/hello_world_output.txt b/tests/codegen/hello_world_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/io.mips b/tests/codegen/io.mips new file mode 100644 index 000000000..02d9f4a7f --- /dev/null +++ b/tests/codegen/io.mips @@ -0,0 +1,1064 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +A_parents: .word 1, 7, 0, +A_Name: .asciiz "A" +A: .word A_Name, 2, A_parents, Object_abort, Object_copy, Object_type_name, A_out_a, +B_parents: .word 1, 7, 8, 0, +B_Name: .asciiz "B" +B: .word B_Name, 2, B_parents, Object_abort, Object_copy, Object_type_name, A_out_a, B_out_b, +C_parents: .word 1, 6, 9, 0, +C_Name: .asciiz "C" +C: .word C_Name, 1, C_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, C_out_c, +D_parents: .word 1, 6, 9, 10, 0, +D_Name: .asciiz "D" +D: .word D_Name, 1, D_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, C_out_c, D_out_d, +Main_parents: .word 1, 6, 11, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "A: Hello world\n" +string_1: .asciiz "B: Hello world\n" +string_2: .asciiz "C: Hello world\n" +string_3: .asciiz "D: Hello world\n" +string_4: .asciiz "Done.\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 40 +addi $sp, $sp, -4 #Push local var new_A@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var new_B@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var new_C@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_c@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var new_D@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_d@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_a +#Creando instancia de tipo A +#Allocate a una class A +#atributo type_name en puntero + 0 +#atributo io en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 36($sp) #Guardando en la variable local new_A@0 puntero de la instancia de la clase A +#Assignacion de la insformacion de tipo a la instancia +la $t0, A # +move $s4, $t0 # +lw $t0, 36($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 36($sp) #Lee el valor de la var new_A@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_A@0 +jal new_ctr_A # +sw $v0, 32($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_a +lw $t0, 32($sp) #Lee el valor de la var instance_dynamic_to_out_a@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_a@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de A +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion out_a +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_b +#Creando instancia de tipo B +#Allocate a una class B +#atributo type_name en puntero + 0 +#atributo io en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 28($sp) #Guardando en la variable local new_B@0 puntero de la instancia de la clase B +#Assignacion de la insformacion de tipo a la instancia +la $t0, B # +move $s4, $t0 # +lw $t0, 28($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 28($sp) #Lee el valor de la var new_B@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_B@0 +jal new_ctr_B # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_b +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_out_b@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_b@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de B +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion out_b +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_c +#Creando instancia de tipo C +#Allocate a una class C +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 20($sp) #Guardando en la variable local new_C@0 puntero de la instancia de la clase C +#Assignacion de la insformacion de tipo a la instancia +la $t0, C # +move $s4, $t0 # +lw $t0, 20($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 20($sp) #Lee el valor de la var new_C@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_C@0 +jal new_ctr_C # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_c +lw $t0, 16($sp) #Lee el valor de la var instance_dynamic_to_out_c@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_c@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de C +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion out_c +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_d +#Creando instancia de tipo D +#Allocate a una class D +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 12($sp) #Guardando en la variable local new_D@0 puntero de la instancia de la clase D +#Assignacion de la insformacion de tipo a la instancia +la $t0, D # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 12($sp) #Lee el valor de la var new_D@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_D@0 +jal new_ctr_D # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_d +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_out_d@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_d@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion out_d +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 40($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 40($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_A: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var new_IO@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_A +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +#Assignando el resultado de la expression al atributo io de la clase A +#Creando instancia de tipo IO +#Allocate a una class IO +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_IO@0 puntero de la instancia de la clase IO +#Assignacion de la insformacion de tipo a la instancia +la $t0, IO # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_IO@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_IO@0 +jal new_ctr_IO # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 8($sp) #Instancia de la clase A +move $t1, $s4 #Guarda el valor que se le asignara a la propieded io +sw $t1, 4($t0) #Setea la propiedad io con el valor de _ +#Fin De la Asignacion +lw $v0, 8($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +A_out_a: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion A_out_a +#Evalua la Expresion para el DinamicDispatch out_string +#Get Self Property io +lw $t0, 12($sp) #Instancia de la clase A +lw $t1, 4($t0) #Lee la propiedad io +sw $t1, 8($sp) #Guarda el valor de la propiedad io en la variable local instance_dynamic_to_out_string@0 +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de IO +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_B: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_B +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_A # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +B_out_b: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion B_out_b +#Evalua la Expresion para el DinamicDispatch out_string +#Get Self Property io +lw $t0, 12($sp) #Instancia de la clase A +lw $t1, 4($t0) #Lee la propiedad io +sw $t1, 8($sp) #Guarda el valor de la propiedad io en la variable local instance_dynamic_to_out_string@0 +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de IO +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_C: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_C +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +C_out_c: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion C_out_c +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de C +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_D: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_D +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_C # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +D_out_d: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion D_out_d +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 8($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de D +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/io_input.txt b/tests/codegen/io_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/io_output.txt b/tests/codegen/io_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/life.mips b/tests/codegen/life.mips new file mode 100644 index 000000000..006f2443b --- /dev/null +++ b/tests/codegen/life.mips @@ -0,0 +1,6054 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Board_parents: .word 1, 6, 7, 0, +Board_Name: .asciiz "Board" +Board: .word Board_Name, 4, Board_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Board_size_of_board, Board_board_init, +CellularAutomaton_parents: .word 1, 6, 7, 8, 0, +CellularAutomaton_Name: .asciiz "CellularAutomaton" +CellularAutomaton: .word CellularAutomaton_Name, 5, CellularAutomaton_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Board_size_of_board, Board_board_init, CellularAutomaton_init, CellularAutomaton_print, CellularAutomaton_num_cells, CellularAutomaton_cell, CellularAutomaton_north, CellularAutomaton_south, CellularAutomaton_east, CellularAutomaton_west, CellularAutomaton_northwest, CellularAutomaton_northeast, CellularAutomaton_southeast, CellularAutomaton_southwest, CellularAutomaton_neighbors, CellularAutomaton_cell_at_next_evolution, CellularAutomaton_evolve, CellularAutomaton_option, CellularAutomaton_prompt, CellularAutomaton_prompt2, +Main_parents: .word 1, 6, 7, 8, 9, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 6, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Board_size_of_board, Board_board_init, CellularAutomaton_init, CellularAutomaton_print, CellularAutomaton_num_cells, CellularAutomaton_cell, CellularAutomaton_north, CellularAutomaton_south, CellularAutomaton_east, CellularAutomaton_west, CellularAutomaton_northwest, CellularAutomaton_northeast, CellularAutomaton_southeast, CellularAutomaton_southwest, CellularAutomaton_neighbors, CellularAutomaton_cell_at_next_evolution, CellularAutomaton_evolve, CellularAutomaton_option, CellularAutomaton_prompt, CellularAutomaton_prompt2, Main_main, +string_0: .asciiz "\n" +string_1: .asciiz "\n" +string_2: .asciiz "\n" +string_3: .asciiz " " +string_4: .asciiz " " +string_5: .asciiz " " +string_6: .asciiz " " +string_7: .asciiz " " +string_8: .asciiz " " +string_9: .asciiz " " +string_10: .asciiz " " +string_11: .asciiz " " +string_12: .asciiz " " +string_13: .asciiz " " +string_14: .asciiz " " +string_15: .asciiz " " +string_16: .asciiz " " +string_17: .asciiz "X" +string_18: .asciiz "X" +string_19: .asciiz "X" +string_20: .asciiz "X" +string_21: .asciiz "X" +string_22: .asciiz "X" +string_23: .asciiz "X" +string_24: .asciiz "X" +string_25: .asciiz "-" +string_26: .asciiz "X" +string_27: .asciiz "-" +string_28: .asciiz "X" +string_29: .asciiz "X" +string_30: .asciiz "\nPlease chose a number:\n" +string_31: .asciiz " 1: A cross\n" +string_32: .asciiz " 2: A slash from the upper left to lower right\n" +string_33: .asciiz " 3: A slash from the upper right to lower left\n" +string_34: .asciiz " 4: An X\n" +string_35: .asciiz " 5: A greater than sign \n" +string_36: .asciiz " 6: A less than sign\n" +string_37: .asciiz " 7: Two greater than signs\n" +string_38: .asciiz " 8: Two less than signs\n" +string_39: .asciiz " 9: A 'V'\n" +string_40: .asciiz " 10: An inverse 'V'\n" +string_41: .asciiz " 11: Numbers 9 and 10 combined\n" +string_42: .asciiz " 12: A full grid\n" +string_43: .asciiz " 13: A 'T'\n" +string_44: .asciiz " 14: A plus '+'\n" +string_45: .asciiz " 15: A 'W'\n" +string_46: .asciiz " 16: An 'M'\n" +string_47: .asciiz " 17: An 'E'\n" +string_48: .asciiz " 18: A '3'\n" +string_49: .asciiz " 19: An 'O'\n" +string_50: .asciiz " 20: An '8'\n" +string_51: .asciiz " 21: An 'S'\n" +string_52: .asciiz "Your choice => " +string_53: .asciiz "\n" +string_54: .asciiz " " +string_55: .asciiz " XXXX X XX X XXXX " +string_56: .asciiz " XX X XX X XX X XX X XX " +string_57: .asciiz " XX X XX X XX " +string_58: .asciiz "XXX X X X X XXXX " +string_59: .asciiz "XXXXX X XXXXX X XXXX" +string_60: .asciiz " X X X X X X X" +string_61: .asciiz "X X X X X X X " +string_62: .asciiz " X X XXXXX X X " +string_63: .asciiz "XXXXX X X X X " +string_64: .asciiz "XXXXXXXXXXXXXXXXXXXXXXXXX" +string_65: .asciiz "X X X X X X X X" +string_66: .asciiz " X X X X X" +string_67: .asciiz "X X X X X " +string_68: .asciiz " X XX X X X " +string_69: .asciiz "X X X XX X " +string_70: .asciiz " X X X X X" +string_71: .asciiz "X X X X X " +string_72: .asciiz "X X X X X X X X X" +string_73: .asciiz "X X X X X" +string_74: .asciiz " X X X X X " +string_75: .asciiz " XX XXXX XXXX XX " +string_76: .asciiz "Would you like to continue with the next generation? \n" +string_77: .asciiz "Please use lowercase y or n for your answer [y]: " +string_78: .asciiz "\n" +string_79: .asciiz "n" +string_80: .asciiz "\n\n" +string_81: .asciiz "Would you like to choose a background pattern? \n" +string_82: .asciiz "Please use lowercase y or n for your answer [n]: " +string_83: .asciiz "y" +string_84: .asciiz "Welcome to the Game of Life.\n" +string_85: .asciiz "There are many initial states to choose from. \n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo rows en puntero + 4 +#atributo columns en puntero + 8 +#atributo board_size en puntero + 12 +#atributo population_map en puntero + 16 +#atributo cells en puntero + 20 +li $a0, 24 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_CellularAutomaton # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cells +sw $t1, 20($t0) #Setea la propiedad cells con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var continue stackpointer 40 +addi $sp, $sp, -4 #Push local var choice stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var new_CellularAutomaton@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_evolve@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 36($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_84 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_85 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Inicio de un While +j while_cond_2 # +while_back_2: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable continue +li $s4, 1 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable choice +#StaticDispatch option +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 108($t1) #Buscando el metodo dinamico para la funcion option +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 36($sp) # +lw $t0, 36($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable cells +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo CellularAutomaton +#Allocate a una class CellularAutomaton +#atributo type_name en puntero + 0 +#atributo rows en puntero + 4 +#atributo columns en puntero + 8 +#atributo board_size en puntero + 12 +#atributo population_map en puntero + 16 +li $a0, 20 # +li $v0, 9 # +syscall +sw $v0, 24($sp) #Guardando en la variable local new_CellularAutomaton@0 puntero de la instancia de la clase CellularAutomaton +#Assignacion de la insformacion de tipo a la instancia +la $t0, CellularAutomaton # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 24($sp) #Lee el valor de la var new_CellularAutomaton@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_CellularAutomaton@0 +jal new_ctr_CellularAutomaton # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var choice +lw $t0, 36($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch init +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 44($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cells +sw $t1, 20($t0) #Setea la propiedad cells con el valor de _ +lw $t0, 44($sp) #Instancia de la clase Main +lw $t1, 20($t0) #Lee la propiedad cells +move $s4, $t1 #Guarda el valor de la propiedad cells en la variable local _ +#Inicio del paso 3 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cells +lw $t0, 44($sp) #Instancia de la clase Main +lw $t1, 20($t0) #Lee la propiedad cells +sw $t1, 12($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_print@0 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_print@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#Inicio de un While +j while_cond_3 # +while_back_3: +#Evalua la condicion de un If +#StaticDispatch prompt +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 112($t1) #Buscando el metodo dinamico para la funcion prompt +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_0 # +#Else case +#Asignando un nuevo valor a la variable continue +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +j fin_Main_main_0 # +then_Main_main_0: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch evolve +#Get Self Property cells +lw $t0, 44($sp) #Instancia de la clase Main +lw $t1, 20($t0) #Lee la propiedad cells +sw $t1, 8($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_evolve@0 +#Fin de la exprecion previa al DinamicDispatch evolve +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_evolve@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_evolve@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 104($t1) #Buscando el metodo dinamico para la funcion evolve +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print +#Get Self Property cells +lw $t0, 44($sp) #Instancia de la clase Main +lw $t1, 20($t0) #Lee la propiedad cells +sw $t1, 4($sp) #Guarda el valor de la propiedad cells en la variable local instance_dynamic_to_print@1 +#Fin de la exprecion previa al DinamicDispatch print +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print@1 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_0: +#Fin de un If +#Fin del cuerpo e inicio de la condicion de un While +while_cond_3: +#Get Local Var continue +lw $t0, 40($sp) # +move $s4, $t0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_3 # +#Fin de la condicion de un While +lw $t0, 44($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_2: +#StaticDispatch prompt2 +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 116($t1) #Buscando el metodo dinamico para la funcion prompt2 +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_2 # +#Fin de la condicion de un While +lw $t0, 44($sp) # +move $s4, $t0 # +#Inicio del paso 3 de una sequencia Block +#Get Local Var self +lw $t0, 44($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +new_ctr_CellularAutomaton: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_CellularAutomaton +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Board # +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 16($t0) #Setea la propiedad population_map con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +CellularAutomaton_option: # +#Parametro self en stackpoiner + 272 +addi $sp, $sp, -4 #Push local var num stackpointer 268 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 264 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 260 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 256 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 252 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@4 stackpointer 248 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@5 stackpointer 244 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@6 stackpointer 240 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@7 stackpointer 236 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@8 stackpointer 232 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@9 stackpointer 228 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@10 stackpointer 224 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@11 stackpointer 220 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@12 stackpointer 216 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@13 stackpointer 212 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@14 stackpointer 208 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@15 stackpointer 204 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@16 stackpointer 200 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@17 stackpointer 196 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@18 stackpointer 192 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@19 stackpointer 188 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@20 stackpointer 184 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@21 stackpointer 180 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@22 stackpointer 176 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@23 stackpointer 172 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 168 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 164 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 160 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 156 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 152 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 148 +addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 144 +addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 140 +addi $sp, $sp, -4 #Push local var int_eq@_a@4 stackpointer 136 +addi $sp, $sp, -4 #Push local var int_eq@_b@4 stackpointer 132 +addi $sp, $sp, -4 #Push local var int_eq@_a@5 stackpointer 128 +addi $sp, $sp, -4 #Push local var int_eq@_b@5 stackpointer 124 +addi $sp, $sp, -4 #Push local var int_eq@_a@6 stackpointer 120 +addi $sp, $sp, -4 #Push local var int_eq@_b@6 stackpointer 116 +addi $sp, $sp, -4 #Push local var int_eq@_a@7 stackpointer 112 +addi $sp, $sp, -4 #Push local var int_eq@_b@7 stackpointer 108 +addi $sp, $sp, -4 #Push local var int_eq@_a@8 stackpointer 104 +addi $sp, $sp, -4 #Push local var int_eq@_b@8 stackpointer 100 +addi $sp, $sp, -4 #Push local var int_eq@_a@9 stackpointer 96 +addi $sp, $sp, -4 #Push local var int_eq@_b@9 stackpointer 92 +addi $sp, $sp, -4 #Push local var int_eq@_a@10 stackpointer 88 +addi $sp, $sp, -4 #Push local var int_eq@_b@10 stackpointer 84 +addi $sp, $sp, -4 #Push local var int_eq@_a@11 stackpointer 80 +addi $sp, $sp, -4 #Push local var int_eq@_b@11 stackpointer 76 +addi $sp, $sp, -4 #Push local var int_eq@_a@12 stackpointer 72 +addi $sp, $sp, -4 #Push local var int_eq@_b@12 stackpointer 68 +addi $sp, $sp, -4 #Push local var int_eq@_a@13 stackpointer 64 +addi $sp, $sp, -4 #Push local var int_eq@_b@13 stackpointer 60 +addi $sp, $sp, -4 #Push local var int_eq@_a@14 stackpointer 56 +addi $sp, $sp, -4 #Push local var int_eq@_b@14 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_a@15 stackpointer 48 +addi $sp, $sp, -4 #Push local var int_eq@_b@15 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@16 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@16 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@17 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@17 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@18 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@18 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@19 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@19 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@20 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@20 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_option +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +li $s4, 0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 268($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_30 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 264($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 268($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_31 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 260($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 264($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_32 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 256($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 260($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_33 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 252($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 256($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_34 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 248($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 252($sp) #Lee el valor de la var param_0_to_out_string@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@4 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 5 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_35 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 244($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 248($sp) #Lee el valor de la var param_0_to_out_string@5 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@5 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 6 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_36 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 240($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 244($sp) #Lee el valor de la var param_0_to_out_string@6 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@6 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 7 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_37 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 236($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 240($sp) #Lee el valor de la var param_0_to_out_string@7 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@7 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 8 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_38 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 232($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 236($sp) #Lee el valor de la var param_0_to_out_string@8 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@8 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 9 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_39 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 228($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 232($sp) #Lee el valor de la var param_0_to_out_string@9 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@9 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 10 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_40 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 224($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 228($sp) #Lee el valor de la var param_0_to_out_string@10 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@10 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 11 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_41 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 220($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 224($sp) #Lee el valor de la var param_0_to_out_string@11 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@11 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 12 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_42 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 216($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 220($sp) #Lee el valor de la var param_0_to_out_string@12 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@12 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 13 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_43 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 212($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 216($sp) #Lee el valor de la var param_0_to_out_string@13 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@13 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 14 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_44 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 208($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 212($sp) #Lee el valor de la var param_0_to_out_string@14 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@14 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 15 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_45 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 204($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 208($sp) #Lee el valor de la var param_0_to_out_string@15 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@15 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 16 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_46 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 200($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 204($sp) #Lee el valor de la var param_0_to_out_string@16 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@16 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 17 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_47 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 196($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 200($sp) #Lee el valor de la var param_0_to_out_string@17 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@17 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 18 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_48 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 192($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 196($sp) #Lee el valor de la var param_0_to_out_string@18 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@18 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 19 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_49 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 188($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 192($sp) #Lee el valor de la var param_0_to_out_string@19 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@19 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 20 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_50 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 184($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 188($sp) #Lee el valor de la var param_0_to_out_string@20 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@20 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 21 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_51 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 180($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 184($sp) #Lee el valor de la var param_0_to_out_string@21 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@21 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 22 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_52 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 176($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 180($sp) #Lee el valor de la var param_0_to_out_string@22 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@22 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 23 de una sequencia Block +#Asignando un nuevo valor a la variable num +#StaticDispatch in_int +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 276($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion in_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 268($sp) # +lw $t0, 268($sp) # +move $s4, $t0 # +#Inicio del paso 24 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_53 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 172($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 272($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 176($sp) #Lee el valor de la var param_0_to_out_string@23 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@23 +lw $t0, 280($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 25 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 168($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 1 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 164($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 168($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 164($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 160($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 2 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 156($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 160($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 156($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 152($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 3 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 148($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 152($sp) #Guarda el parametro 0 -> int_eq@_a@2 +lw $a1, 148($sp) #Guarda el parametro 1 -> int_eq@_b@2 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 144($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 4 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 140($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 144($sp) #Guarda el parametro 0 -> int_eq@_a@3 +lw $a1, 140($sp) #Guarda el parametro 1 -> int_eq@_b@3 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 136($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 5 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 132($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 136($sp) #Guarda el parametro 0 -> int_eq@_a@4 +lw $a1, 132($sp) #Guarda el parametro 1 -> int_eq@_b@4 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 128($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 6 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 124($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 128($sp) #Guarda el parametro 0 -> int_eq@_a@5 +lw $a1, 124($sp) #Guarda el parametro 1 -> int_eq@_b@5 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_5 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 120($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 7 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 116($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 120($sp) #Guarda el parametro 0 -> int_eq@_a@6 +lw $a1, 116($sp) #Guarda el parametro 1 -> int_eq@_b@6 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_6 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 112($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 8 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 108($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> int_eq@_a@7 +lw $a1, 108($sp) #Guarda el parametro 1 -> int_eq@_b@7 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_7 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 104($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 9 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 100($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 104($sp) #Guarda el parametro 0 -> int_eq@_a@8 +lw $a1, 100($sp) #Guarda el parametro 1 -> int_eq@_b@8 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_8 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 96($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 10 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 92($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 96($sp) #Guarda el parametro 0 -> int_eq@_a@9 +lw $a1, 92($sp) #Guarda el parametro 1 -> int_eq@_b@9 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_9 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 88($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 11 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 84($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 88($sp) #Guarda el parametro 0 -> int_eq@_a@10 +lw $a1, 84($sp) #Guarda el parametro 1 -> int_eq@_b@10 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_10 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 80($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 12 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 76($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 80($sp) #Guarda el parametro 0 -> int_eq@_a@11 +lw $a1, 76($sp) #Guarda el parametro 1 -> int_eq@_b@11 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_11 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 72($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 13 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> int_eq@_a@12 +lw $a1, 68($sp) #Guarda el parametro 1 -> int_eq@_b@12 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_12 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 64($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 14 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 60($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 64($sp) #Guarda el parametro 0 -> int_eq@_a@13 +lw $a1, 60($sp) #Guarda el parametro 1 -> int_eq@_b@13 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_13 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 56($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 15 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 56($sp) #Guarda el parametro 0 -> int_eq@_a@14 +lw $a1, 52($sp) #Guarda el parametro 1 -> int_eq@_b@14 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_14 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 16 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> int_eq@_a@15 +lw $a1, 44($sp) #Guarda el parametro 1 -> int_eq@_b@15 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_15 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 17 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@16 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@16 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_16 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 18 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@17 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@17 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_17 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 19 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@18 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@18 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_18 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 20 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@19 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@19 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_19 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var num +lw $t0, 268($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 21 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 272($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@20 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@20 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 272($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_option_20 # +#Else case +la $t0, string_54 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_option_20 # +then_CellularAutomaton_option_20: +#Then case +la $t0, string_55 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_20: +#Fin de un If +j fin_CellularAutomaton_option_19 # +then_CellularAutomaton_option_19: +#Then case +la $t0, string_56 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_19: +#Fin de un If +j fin_CellularAutomaton_option_18 # +then_CellularAutomaton_option_18: +#Then case +la $t0, string_57 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_18: +#Fin de un If +j fin_CellularAutomaton_option_17 # +then_CellularAutomaton_option_17: +#Then case +la $t0, string_58 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_17: +#Fin de un If +j fin_CellularAutomaton_option_16 # +then_CellularAutomaton_option_16: +#Then case +la $t0, string_59 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_16: +#Fin de un If +j fin_CellularAutomaton_option_15 # +then_CellularAutomaton_option_15: +#Then case +la $t0, string_60 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_15: +#Fin de un If +j fin_CellularAutomaton_option_14 # +then_CellularAutomaton_option_14: +#Then case +la $t0, string_61 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_14: +#Fin de un If +j fin_CellularAutomaton_option_13 # +then_CellularAutomaton_option_13: +#Then case +la $t0, string_62 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_13: +#Fin de un If +j fin_CellularAutomaton_option_12 # +then_CellularAutomaton_option_12: +#Then case +la $t0, string_63 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_12: +#Fin de un If +j fin_CellularAutomaton_option_11 # +then_CellularAutomaton_option_11: +#Then case +la $t0, string_64 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_11: +#Fin de un If +j fin_CellularAutomaton_option_10 # +then_CellularAutomaton_option_10: +#Then case +la $t0, string_65 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_10: +#Fin de un If +j fin_CellularAutomaton_option_9 # +then_CellularAutomaton_option_9: +#Then case +la $t0, string_66 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_9: +#Fin de un If +j fin_CellularAutomaton_option_8 # +then_CellularAutomaton_option_8: +#Then case +la $t0, string_67 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_8: +#Fin de un If +j fin_CellularAutomaton_option_7 # +then_CellularAutomaton_option_7: +#Then case +la $t0, string_68 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_7: +#Fin de un If +j fin_CellularAutomaton_option_6 # +then_CellularAutomaton_option_6: +#Then case +la $t0, string_69 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_6: +#Fin de un If +j fin_CellularAutomaton_option_5 # +then_CellularAutomaton_option_5: +#Then case +la $t0, string_70 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_5: +#Fin de un If +j fin_CellularAutomaton_option_4 # +then_CellularAutomaton_option_4: +#Then case +la $t0, string_71 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_4: +#Fin de un If +j fin_CellularAutomaton_option_3 # +then_CellularAutomaton_option_3: +#Then case +la $t0, string_72 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_3: +#Fin de un If +j fin_CellularAutomaton_option_2 # +then_CellularAutomaton_option_2: +#Then case +la $t0, string_73 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_2: +#Fin de un If +j fin_CellularAutomaton_option_1 # +then_CellularAutomaton_option_1: +#Then case +la $t0, string_74 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_1: +#Fin de un If +j fin_CellularAutomaton_option_0 # +then_CellularAutomaton_option_0: +#Then case +la $t0, string_75 # +move $s4, $t0 # +lw $s6, 272($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_option_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 276 # +jr $ra # + +Board_board_init: # +#Parametro self en stackpoiner + 64 +#Parametro start@0 en stackpoiner + 60 +addi $sp, $sp, -4 #Push local var size stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_size_of_board@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@4 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@4 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@5 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@5 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Board_board_init +#Eval Expression to Let size +#StaticDispatch size_of_board +#Evalua el parametro 0 para el CastingDispatch size_of_board +#Get Local Var start +lw $t0, 60($sp) # +sw $t0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch size_of_board +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 56($sp) #Lee el valor de la var param_0_to_size_of_board@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_size_of_board@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Board +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion size_of_board +jal $t3 # +sw $v0, 56($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let size +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 15 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 40($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 16 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 40($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 36($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 32($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 20 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 28($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 32($sp) #Guarda el parametro 0 -> int_eq@_a@2 +lw $a1, 28($sp) #Guarda el parametro 1 -> int_eq@_b@2 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_2 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 24($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 21 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@3 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@3 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_3 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 25 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@4 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@4 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_4 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var size +lw $t0, 56($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 28 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 64($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@5 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@5 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Board_board_init_5 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +j fin_Board_board_init_5 # +then_Board_board_init_5: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 7 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 4 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_5: +#Fin de un If +j fin_Board_board_init_4 # +then_Board_board_init_4: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_4: +#Fin de un If +j fin_Board_board_init_3 # +then_Board_board_init_3: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 3 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 7 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_3: +#Fin de un If +j fin_Board_board_init_2 # +then_Board_board_init_2: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 4 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_2: +#Fin de un If +j fin_Board_board_init_1 # +then_Board_board_init_1: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 4 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 4 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_1: +#Fin de un If +j fin_Board_board_init_0 # +then_Board_board_init_0: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable rows +li $s4, 3 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 4($t0) #Lee la propiedad rows +move $s4, $t1 #Guarda el valor de la propiedad rows en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable columns +li $s4, 5 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +move $s4, $t1 #Guarda el valor de la propiedad columns en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable board_size +#Get Local Var size +lw $t0, 56($sp) # +move $s4, $t0 # +lw $t0, 64($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $t0, 64($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +move $s4, $t1 #Guarda el valor de la propiedad board_size en la variable local _ +fin_Board_board_init_0: +#Fin de un If +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 64($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 68 # +jr $ra # + +CellularAutomaton_init: # +#Parametro self en stackpoiner + 12 +#Parametro map@0 en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_board_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable population_map +#Get Local Var map +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 16($t0) #Setea la propiedad population_map con el valor de _ +lw $t0, 12($sp) #Instancia de la clase CellularAutomaton +lw $t1, 16($t0) #Lee la propiedad population_map +move $s4, $t1 #Guarda el valor de la propiedad population_map en la variable local _ +#Inicio del paso 1 de una sequencia Block +#StaticDispatch board_init +#Evalua el parametro 0 para el CastingDispatch board_init +#Get Local Var map +lw $t0, 8($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch board_init +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_board_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_board_init@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion board_init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +CellularAutomaton_print: # +#Parametro self en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var i stackpointer 52 +addi $sp, $sp, -4 #Push local var num stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_print +#Eval Expression to Let i +li $s4, 0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 52($sp) # +#Fin de la asignacion Let i +#Eval Expression to Let num +#Get Self Property board_size +lw $t0, 56($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +sw $t1, 48($sp) #Guarda el valor de la propiedad board_size en la variable local num +#Fin de la asignacion Let num +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch substr +#Get Self Property population_map +lw $t0, 56($sp) #Instancia de la clase CellularAutomaton +lw $t1, 16($t0) #Lee la propiedad population_map +sw $t1, 40($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_substr@0 +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Get Self Property columns +lw $t0, 56($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 32($sp) #Guarda el valor de la propiedad columns en la variable local param_1_to_substr@0 +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 40($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 40($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Self Property columns +lw $t0, 56($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local sum@_b@0 +#Resolucion del operado derecha de una operacion sum +lw $s6, 56($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 52($sp) # +lw $t0, 52($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var num +lw $t0, 48($sp) # +sw $t0, 8($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 56($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 56($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 56($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 56($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#Get Local Var self +lw $t0, 56($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 60 # +jr $ra # + +CellularAutomaton_prompt: # +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var ans stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_prompt +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_76 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_77 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Asignando un nuevo valor a la variable ans +#StaticDispatch in_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 24($sp) # +lw $t0, 24($sp) # +move $s4, $t0 # +#Inicio del paso 3 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_78 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 4 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var ans +lw $t0, 24($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_79 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_prompt_0 # +#Else case +li $s4, 1 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_prompt_0 # +then_CellularAutomaton_prompt_0: +#Then case +li $s4, 0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_CellularAutomaton_prompt_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +CellularAutomaton_prompt2: # +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var ans stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_prompt2 +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 24($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_80 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_81 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_82 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 3 de una sequencia Block +#Asignando un nuevo valor a la variable ans +#StaticDispatch in_string +lw $t0, 28($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 24($sp) # +lw $t0, 24($sp) # +move $s4, $t0 # +#Inicio del paso 4 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Get Local Var ans +lw $t0, 24($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_83 # +move $s4, $t0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_prompt2_0 # +#Else case +li $s4, 0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_prompt2_0 # +then_CellularAutomaton_prompt2_0: +#Then case +li $s4, 1 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 28($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_CellularAutomaton_prompt2_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +CellularAutomaton_evolve: # +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var position stackpointer 40 +addi $sp, $sp, -4 #Push local var num stackpointer 36 +addi $sp, $sp, -4 #Push local var temp stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_concat@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_cell_at_next_evolution@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_evolve +#Eval Expression to Let position +li $s4, 0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Fin de la asignacion Let position +#Eval Expression to Let num +#StaticDispatch num_cells +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion num_cells +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let num +la $t0, _______void_str_______ # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 32($sp) # +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Inicio de un While +j while_cond_1 # +while_back_1: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable temp +#Evalua la Expresion para el DinamicDispatch concat +#Get Local Var temp +lw $t0, 32($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch concat +#Evalua el parametro 0 para el CastingDispatch concat +#StaticDispatch cell_at_next_evolution +#Evalua el parametro 0 para el CastingDispatch cell_at_next_evolution +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch cell_at_next_evolution +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) #Lee el valor de la var param_0_to_cell_at_next_evolution@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell_at_next_evolution@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 100($t1) #Buscando el metodo dinamico para la funcion cell_at_next_evolution +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch concat +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_concat@0 +lw $t0, 24($sp) #Lee el valor de la var param_0_to_concat@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_concat@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $t0, $s4 # +sw $t0, 32($sp) # +lw $t0, 32($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable position +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 44($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 40($sp) # +lw $t0, 40($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var num +lw $t0, 36($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 44($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 44($sp) # +move $s4, $t0 # +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable population_map +#Get Local Var temp +lw $t0, 32($sp) # +move $s4, $t0 # +lw $t0, 44($sp) #Instancia de la clase CellularAutomaton +move $t1, $s4 #Guarda el valor que se le asignara a la propieded population_map +sw $t1, 16($t0) #Setea la propiedad population_map con el valor de _ +lw $t0, 44($sp) #Instancia de la clase CellularAutomaton +lw $t1, 16($t0) #Lee la propiedad population_map +move $s4, $t1 #Guarda el valor de la propiedad population_map en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 44($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +new_ctr_Board: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Board +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded rows +sw $t1, 4($t0) #Setea la propiedad rows con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded columns +sw $t1, 8($t0) #Setea la propiedad columns con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Board +move $t1, $s4 #Guarda el valor que se le asignara a la propieded board_size +sw $t1, 12($t0) #Setea la propiedad board_size con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_in_int: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_int +lw $s6, 4($sp) #Guarda self +jal __int__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Board_size_of_board: # +#Parametro self en stackpoiner + 12 +#Parametro initial@0 en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Board_size_of_board +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var initial +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 8($sp) #Lee el valor de la var initial@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con initial@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +IO_in_string: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_string +lw $s6, 4($sp) #Guarda self +jal __str__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +CellularAutomaton_num_cells: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_num_cells +#Evalua la Expresion para el DinamicDispatch length +#Get Self Property population_map +lw $t0, 8($sp) #Instancia de la clase CellularAutomaton +lw $t1, 16($t0) #Lee la propiedad population_map +sw $t1, 4($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_length@0 +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_length@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_length@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +CellularAutomaton_cell_at_next_evolution: # +#Parametro self en stackpoiner + 44 +#Parametro position@0 en stackpoiner + 40 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_neighbors@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_neighbors@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell_at_next_evolution +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#StaticDispatch neighbors +#Evalua el parametro 0 para el CastingDispatch neighbors +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch neighbors +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_neighbors@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_neighbors@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 96($t1) #Buscando el metodo dinamico para la funcion neighbors +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 3 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 44($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#StaticDispatch neighbors +#Evalua el parametro 0 para el CastingDispatch neighbors +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch neighbors +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_neighbors@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_neighbors@1 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 96($t1) #Buscando el metodo dinamico para la funcion neighbors +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 2 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 44($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_1 # +#Else case +la $t0, string_25 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_1 # +then_CellularAutomaton_cell_at_next_evolution_1: +#Then case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Get Local Var position +lw $t0, 40($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 44($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_26 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 44($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 44($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_at_next_evolution_2 # +#Else case +la $t0, string_27 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_cell_at_next_evolution_2 # +then_CellularAutomaton_cell_at_next_evolution_2: +#Then case +la $t0, string_28 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_2: +#Fin de un If +fin_CellularAutomaton_cell_at_next_evolution_1: +#Fin de un If +j fin_CellularAutomaton_cell_at_next_evolution_0 # +then_CellularAutomaton_cell_at_next_evolution_0: +#Then case +la $t0, string_29 # +move $s4, $t0 # +lw $s6, 44($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_at_next_evolution_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 48 # +jr $ra # + +String_concat: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_concat +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__concat__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +CellularAutomaton_neighbors: # +#Parametro self en stackpoiner + 160 +#Parametro position@0 en stackpoiner + 156 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 152 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 148 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 144 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 140 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 136 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 132 +addi $sp, $sp, -4 #Push local var sum@_a@3 stackpointer 128 +addi $sp, $sp, -4 #Push local var sum@_b@3 stackpointer 124 +addi $sp, $sp, -4 #Push local var sum@_a@4 stackpointer 120 +addi $sp, $sp, -4 #Push local var sum@_b@4 stackpointer 116 +addi $sp, $sp, -4 #Push local var sum@_a@5 stackpointer 112 +addi $sp, $sp, -4 #Push local var sum@_b@5 stackpointer 108 +addi $sp, $sp, -4 #Push local var sum@_a@6 stackpointer 104 +addi $sp, $sp, -4 #Push local var sum@_b@6 stackpointer 100 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var param_0_to_north@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var str_eq@_a@1 stackpointer 84 +addi $sp, $sp, -4 #Push local var str_eq@_b@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var param_0_to_south@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@2 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@2 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_0_to_east@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var str_eq@_a@3 stackpointer 60 +addi $sp, $sp, -4 #Push local var str_eq@_b@3 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_west@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var str_eq@_a@4 stackpointer 48 +addi $sp, $sp, -4 #Push local var str_eq@_b@4 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_northeast@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var str_eq@_a@5 stackpointer 36 +addi $sp, $sp, -4 #Push local var str_eq@_b@5 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_northwest@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var str_eq@_a@6 stackpointer 24 +addi $sp, $sp, -4 #Push local var str_eq@_b@6 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_southeast@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var str_eq@_a@7 stackpointer 12 +addi $sp, $sp, -4 #Push local var str_eq@_b@7 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_southwest@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_neighbors +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evaluando el operado izquierdo de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch north +#Evalua el parametro 0 para el CastingDispatch north +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 88($sp) # +#Fin del paramentro 0 al CastingDispatch north +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 92($sp) #Lee el valor de la var param_0_to_north@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_north@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion north +jal $t3 # +sw $v0, 96($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_17 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 92($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 96($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 92($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_0 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_0 # +then_CellularAutomaton_neighbors_0: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_0: +#Fin de un If +move $t0, $s4 # +sw $t0, 104($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch south +#Evalua el parametro 0 para el CastingDispatch south +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 76($sp) # +#Fin del paramentro 0 al CastingDispatch south +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 80($sp) #Lee el valor de la var param_0_to_south@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_south@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion south +jal $t3 # +sw $v0, 84($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_18 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 80($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 84($sp) #Guarda el parametro 0 -> str_eq@_a@1 +lw $a1, 80($sp) #Guarda el parametro 1 -> str_eq@_b@1 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_1 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_1 # +then_CellularAutomaton_neighbors_1: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_1: +#Fin de un If +move $t0, $s4 # +sw $t0, 100($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 104($sp) #Guarda el parametro 0 -> sum@_a@6 +lw $a1, 100($sp) #Guarda el parametro 1 -> sum@_b@6 +jal __int__sum__ # +sw $v0, 112($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch east +#Evalua el parametro 0 para el CastingDispatch east +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 64($sp) # +#Fin del paramentro 0 al CastingDispatch east +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 68($sp) #Lee el valor de la var param_0_to_east@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_east@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 72($t1) #Buscando el metodo dinamico para la funcion east +jal $t3 # +sw $v0, 72($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_19 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 68($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@2 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@2 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_2 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_2 # +then_CellularAutomaton_neighbors_2: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_2: +#Fin de un If +move $t0, $s4 # +sw $t0, 108($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 112($sp) #Guarda el parametro 0 -> sum@_a@5 +lw $a1, 108($sp) #Guarda el parametro 1 -> sum@_b@5 +jal __int__sum__ # +sw $v0, 120($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch west +#Evalua el parametro 0 para el CastingDispatch west +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 52($sp) # +#Fin del paramentro 0 al CastingDispatch west +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 56($sp) #Lee el valor de la var param_0_to_west@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_west@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion west +jal $t3 # +sw $v0, 60($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_20 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 56($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> str_eq@_a@3 +lw $a1, 56($sp) #Guarda el parametro 1 -> str_eq@_b@3 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_3 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_3 # +then_CellularAutomaton_neighbors_3: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_3: +#Fin de un If +move $t0, $s4 # +sw $t0, 116($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 120($sp) #Guarda el parametro 0 -> sum@_a@4 +lw $a1, 116($sp) #Guarda el parametro 1 -> sum@_b@4 +jal __int__sum__ # +sw $v0, 128($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch northeast +#Evalua el parametro 0 para el CastingDispatch northeast +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 40($sp) # +#Fin del paramentro 0 al CastingDispatch northeast +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) #Lee el valor de la var param_0_to_northeast@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_northeast@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 84($t1) #Buscando el metodo dinamico para la funcion northeast +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_21 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> str_eq@_a@4 +lw $a1, 44($sp) #Guarda el parametro 1 -> str_eq@_b@4 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_4 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_4 # +then_CellularAutomaton_neighbors_4: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_4: +#Fin de un If +move $t0, $s4 # +sw $t0, 124($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 128($sp) #Guarda el parametro 0 -> sum@_a@3 +lw $a1, 124($sp) #Guarda el parametro 1 -> sum@_b@3 +jal __int__sum__ # +sw $v0, 136($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch northwest +#Evalua el parametro 0 para el CastingDispatch northwest +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 28($sp) # +#Fin del paramentro 0 al CastingDispatch northwest +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 32($sp) #Lee el valor de la var param_0_to_northwest@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_northwest@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 80($t1) #Buscando el metodo dinamico para la funcion northwest +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_22 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> str_eq@_a@5 +lw $a1, 32($sp) #Guarda el parametro 1 -> str_eq@_b@5 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_5 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_5 # +then_CellularAutomaton_neighbors_5: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_5: +#Fin de un If +move $t0, $s4 # +sw $t0, 132($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 136($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 132($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 144($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch southeast +#Evalua el parametro 0 para el CastingDispatch southeast +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch southeast +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_southeast@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_southeast@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 88($t1) #Buscando el metodo dinamico para la funcion southeast +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_23 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> str_eq@_a@6 +lw $a1, 20($sp) #Guarda el parametro 1 -> str_eq@_b@6 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_6 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_6 # +then_CellularAutomaton_neighbors_6: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_6: +#Fin de un If +move $t0, $s4 # +sw $t0, 140($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 144($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 140($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 152($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#StaticDispatch southwest +#Evalua el parametro 0 para el CastingDispatch southwest +#Get Local Var position +lw $t0, 156($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch southwest +lw $t0, 160($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_southwest@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_southwest@0 +lw $t0, 168($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 92($t1) #Buscando el metodo dinamico para la funcion southwest +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +la $t0, string_24 # +move $s4, $t0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 160($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> str_eq@_a@7 +lw $a1, 8($sp) #Guarda el parametro 1 -> str_eq@_b@7 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 160($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_neighbors_7 # +#Else case +li $s4, 0 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_CellularAutomaton_neighbors_7 # +then_CellularAutomaton_neighbors_7: +#Then case +li $s4, 1 # +lw $s6, 160($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +fin_CellularAutomaton_neighbors_7: +#Fin de un If +move $t0, $s4 # +sw $t0, 148($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 160($sp) #Guarda self +lw $a0, 152($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 148($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 164 # +jr $ra # + +CellularAutomaton_cell: # +#Parametro self en stackpoiner + 36 +#Parametro position@0 en stackpoiner + 32 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_cell +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Evaluando el operado izquierdo de una operacion rest +#Get Self Property board_size +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +sw $t1, 20($sp) #Guarda el valor de la propiedad board_size en la variable local rest@_a@0 +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 36($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 24($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 36($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_cell_0 # +#Else case +#Evalua la Expresion para el DinamicDispatch substr +#Get Self Property population_map +lw $t0, 36($sp) #Instancia de la clase CellularAutomaton +lw $t1, 16($t0) #Lee la propiedad population_map +sw $t1, 12($sp) #Guarda el valor de la propiedad population_map en la variable local instance_dynamic_to_substr@0 +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_cell_0 # +then_CellularAutomaton_cell_0: +#Then case +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_cell_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +CellularAutomaton_north: # +#Parametro self en stackpoiner + 36 +#Parametro position@0 en stackpoiner + 32 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_north +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Self Property columns +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local rest@_b@0 +#Resolucion del operado derecha de una operacion rest +lw $s6, 36($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +li $s4, 0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 36($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_north_0 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Self Property columns +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 8($sp) #Guarda el valor de la propiedad columns en la variable local rest@_b@1 +#Resolucion del operado derecha de una operacion rest +lw $s6, 36($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_north_0 # +then_CellularAutomaton_north_0: +#Then case +la $t0, string_4 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_north_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +CellularAutomaton_northwest: # +#Parametro self en stackpoiner + 60 +#Parametro position@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_north@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_northwest +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 40($sp) #Guarda el valor de la propiedad columns en la variable local rest@_b@0 +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 52($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +li $s4, 0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 60($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_northwest_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 60($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 24($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 60($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 32($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_northwest_1 # +#Else case +#StaticDispatch north +#Evalua el parametro 0 para el CastingDispatch north +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch north +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_north@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_north@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion north +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_northwest_1 # +then_CellularAutomaton_northwest_1: +#Then case +la $t0, string_9 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_northwest_1: +#Fin de un If +j fin_CellularAutomaton_northwest_0 # +then_CellularAutomaton_northwest_0: +#Then case +la $t0, string_10 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_northwest_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +CellularAutomaton_northeast: # +#Parametro self en stackpoiner + 76 +#Parametro position@0 en stackpoiner + 72 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_north@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_northeast +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 60($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 56($sp) #Guarda el valor de la propiedad columns en la variable local rest@_b@0 +#Resolucion del operado derecha de una operacion rest +lw $s6, 76($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 56($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 68($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +li $s4, 0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 76($sp) #Guarda self +lw $a0, 68($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 64($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 76($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_northeast_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 28($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 32($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 76($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 44($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 40($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 76($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 52($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 76($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 76($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_northeast_1 # +#Else case +#StaticDispatch north +#Evalua el parametro 0 para el CastingDispatch north +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 8($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch north +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_north@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_north@0 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion north +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_northeast_1 # +then_CellularAutomaton_northeast_1: +#Then case +la $t0, string_11 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_northeast_1: +#Fin de un If +j fin_CellularAutomaton_northeast_0 # +then_CellularAutomaton_northeast_0: +#Then case +la $t0, string_12 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_northeast_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 80 # +jr $ra # + +CellularAutomaton_south: # +#Parametro self en stackpoiner + 36 +#Parametro position@0 en stackpoiner + 32 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_south +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Self Property board_size +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +sw $t1, 28($sp) #Guarda el valor de la propiedad board_size en la variable local less@_a@0 +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Self Property columns +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local sum@_b@0 +#Resolucion del operado derecha de una operacion sum +lw $s6, 36($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 36($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 36($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_south_0 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 32($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Self Property columns +lw $t0, 36($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 8($sp) #Guarda el valor de la propiedad columns en la variable local sum@_b@1 +#Resolucion del operado derecha de una operacion sum +lw $s6, 36($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_south_0 # +then_CellularAutomaton_south_0: +#Then case +la $t0, string_5 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_south_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +CellularAutomaton_southeast: # +#Parametro self en stackpoiner + 76 +#Parametro position@0 en stackpoiner + 72 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_a@3 stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_b@3 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_south@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_southeast +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Self Property board_size +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +sw $t1, 68($sp) #Guarda el valor de la propiedad board_size en la variable local less@_a@0 +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 60($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 56($sp) #Guarda el valor de la propiedad columns en la variable local sum@_b@0 +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 56($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 64($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 76($sp) #Guarda self +lw $a0, 68($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 64($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 76($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_southeast_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 28($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 24($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 32($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 76($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 44($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 76($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 40($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 76($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 52($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 76($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 76($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_southeast_1 # +#Else case +#StaticDispatch south +#Evalua el parametro 0 para el CastingDispatch south +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 72($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 76($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> sum@_a@3 +lw $a1, 8($sp) #Guarda el parametro 1 -> sum@_b@3 +jal __int__sum__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch south +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_south@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_south@0 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion south +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_southeast_1 # +then_CellularAutomaton_southeast_1: +#Then case +la $t0, string_13 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_southeast_1: +#Fin de un If +j fin_CellularAutomaton_southeast_0 # +then_CellularAutomaton_southeast_0: +#Then case +la $t0, string_14 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_southeast_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 80 # +jr $ra # + +CellularAutomaton_southwest: # +#Parametro self en stackpoiner + 60 +#Parametro position@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_south@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_southwest +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Self Property board_size +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 12($t0) #Lee la propiedad board_size +sw $t1, 52($sp) #Guarda el valor de la propiedad board_size en la variable local less@_a@0 +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 40($sp) #Guarda el valor de la propiedad columns en la variable local sum@_b@0 +#Resolucion del operado derecha de una operacion sum +lw $s6, 60($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 60($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_southwest_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 60($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 24($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 60($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 32($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_southwest_1 # +#Else case +#StaticDispatch south +#Evalua el parametro 0 para el CastingDispatch south +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 60($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch south +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_south@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_south@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion south +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_southwest_1 # +then_CellularAutomaton_southwest_1: +#Then case +la $t0, string_15 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_southwest_1: +#Fin de un If +j fin_CellularAutomaton_southwest_0 # +then_CellularAutomaton_southwest_0: +#Then case +la $t0, string_16 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_southwest_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +CellularAutomaton_east: # +#Parametro self en stackpoiner + 60 +#Parametro position@0 en stackpoiner + 56 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_a@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var sum@_b@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_east +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 28($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 60($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 32($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 60($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 32($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 44($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 60($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 40($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 60($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 52($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 60($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 60($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 48($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_east_0 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var position +lw $t0, 56($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 60($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> sum@_a@2 +lw $a1, 8($sp) #Guarda el parametro 1 -> sum@_b@2 +jal __int__sum__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_east_0 # +then_CellularAutomaton_east_0: +#Then case +la $t0, string_6 # +move $s4, $t0 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_east_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +CellularAutomaton_west: # +#Parametro self en stackpoiner + 52 +#Parametro position@0 en stackpoiner + 48 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion CellularAutomaton_west +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Local Var position +lw $t0, 48($sp) # +sw $t0, 44($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 52($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_west_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Get Local Var position +lw $t0, 48($sp) # +sw $t0, 20($sp) # +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property columns +lw $t0, 52($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 16($sp) #Guarda el valor de la propiedad columns en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 52($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 16($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 28($sp) # +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property columns +lw $t0, 52($sp) #Instancia de la clase Board +lw $t1, 8($t0) #Lee la propiedad columns +sw $t1, 24($sp) #Guarda el valor de la propiedad columns en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 52($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 24($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 36($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var position +lw $t0, 48($sp) # +sw $t0, 32($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 52($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 32($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 52($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_CellularAutomaton_west_1 # +#Else case +#StaticDispatch cell +#Evalua el parametro 0 para el CastingDispatch cell +#Evaluando el operado izquierdo de una operacion rest +#Get Local Var position +lw $t0, 48($sp) # +sw $t0, 12($sp) # +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 8($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 52($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch cell +lw $t0, 52($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_cell@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cell@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion cell +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_CellularAutomaton_west_1 # +then_CellularAutomaton_west_1: +#Then case +la $t0, string_7 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_west_1: +#Fin de un If +j fin_CellularAutomaton_west_0 # +then_CellularAutomaton_west_0: +#Then case +la $t0, string_8 # +move $s4, $t0 # +lw $s6, 52($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +fin_CellularAutomaton_west_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/life_input.txt b/tests/codegen/life_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/life_output.txt b/tests/codegen/life_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/list.cl b/tests/codegen/list.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/list.mips b/tests/codegen/list.mips new file mode 100644 index 000000000..544516e33 --- /dev/null +++ b/tests/codegen/list.mips @@ -0,0 +1,1338 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +List_parents: .word 1, 7, 0, +List_Name: .asciiz "List" +List: .word List_Name, 1, List_parents, Object_abort, Object_copy, Object_type_name, List_isNil, List_head, List_tail, List_cons, +Cons_parents: .word 1, 7, 8, 0, +Cons_Name: .asciiz "Cons" +Cons: .word Cons_Name, 3, Cons_parents, Object_abort, Object_copy, Object_type_name, Cons_isNil, Cons_head, Cons_tail, List_cons, Cons_init, +Main_parents: .word 1, 6, 9, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 2, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_print_list, Main_main, +string_0: .asciiz " " +string_1: .asciiz "\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo mylist en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded mylist +sw $t1, 4($t0) #Setea la propiedad mylist con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 60 +addi $sp, $sp, -4 #Push local var new_List@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@1 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_cons@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_cons@2 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_cons@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_cons@4 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_cons@4 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_print_list@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_tail@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_isNil@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable mylist +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch cons +#Evalua la Expresion para el DinamicDispatch cons +#Creando instancia de tipo List +#Allocate a una class List +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 56($sp) #Guardando en la variable local new_List@0 puntero de la instancia de la clase List +#Assignacion de la insformacion de tipo a la instancia +la $t0, List # +move $s4, $t0 # +lw $t0, 56($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 56($sp) #Lee el valor de la var new_List@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_List@0 +jal new_ctr_List # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +li $s4, 1 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 48($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 52($sp) #Lee el valor de la var instance_dynamic_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@0 +lw $t0, 52($sp) #Lee el valor de la var param_0_to_cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +sw $v0, 44($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +li $s4, 2 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 40($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 44($sp) #Lee el valor de la var instance_dynamic_to_cons@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@1 +lw $t0, 44($sp) #Lee el valor de la var param_0_to_cons@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@1 +lw $t0, 52($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +li $s4, 3 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_cons@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@2 +lw $t0, 36($sp) #Lee el valor de la var param_0_to_cons@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@2 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +li $s4, 4 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_cons@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@3 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_cons@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@3 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch cons +#Evalua el parametro 0 para el CastingDispatch cons +li $s4, 5 # +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch cons +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_cons@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_cons@4 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_cons@4 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_cons@4 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 60($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded mylist +sw $t1, 4($t0) #Setea la propiedad mylist con el valor de _ +lw $t0, 60($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad mylist +move $s4, $t1 #Guarda el valor de la propiedad mylist en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch print_list +#Evalua el parametro 0 para el CastingDispatch print_list +#Get Self Property mylist +lw $t0, 60($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad mylist +sw $t1, 12($sp) #Guarda el valor de la propiedad mylist en la variable local param_0_to_print_list@0 +#Fin del paramentro 0 al CastingDispatch print_list +lw $t0, 60($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print_list@0 +lw $t0, 68($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable mylist +#Evalua la Expresion para el DinamicDispatch tail +#Get Self Property mylist +lw $t0, 60($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad mylist +sw $t1, 8($sp) #Guarda el valor de la propiedad mylist en la variable local instance_dynamic_to_tail@0 +#Fin de la exprecion previa al DinamicDispatch tail +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_tail@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_tail@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion tail +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 60($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded mylist +sw $t1, 4($t0) #Setea la propiedad mylist con el valor de _ +lw $t0, 60($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad mylist +move $s4, $t1 #Guarda el valor de la propiedad mylist en la variable local _ +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando la expression de una operacion unaria +#Evalua la Expresion para el DinamicDispatch isNil +#Get Self Property mylist +lw $t0, 60($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad mylist +sw $t1, 4($sp) #Guarda el valor de la propiedad mylist en la variable local instance_dynamic_to_isNil@0 +#Fin de la exprecion previa al DinamicDispatch isNil +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_isNil@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_isNil@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion isNil +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#FIN expression de una operacion unaria +lw $s6, 60($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__neg__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 60($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 60($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_List: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_List +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +List_cons: # +#Parametro self en stackpoiner + 24 +#Parametro i@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_cons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo car en puntero + 4 +#atributo cdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var i +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +Main_print_list: # +#Parametro self en stackpoiner + 36 +#Parametro l@0 en stackpoiner + 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_isNil@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_head@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_tail@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_print_list@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_print_list +#Evalua la condicion de un If +#Evalua la Expresion para el DinamicDispatch isNil +#Get Local Var l +#Fin de la exprecion previa al DinamicDispatch isNil +lw $t0, 32($sp) #Lee el valor de la var l@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con l@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion isNil +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_print_list_0 # +#Else case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Evalua la Expresion para el DinamicDispatch head +#Get Local Var l +#Fin de la exprecion previa al DinamicDispatch head +lw $t0, 32($sp) #Lee el valor de la var l@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con l@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion head +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch print_list +#Evalua el parametro 0 para el CastingDispatch print_list +#Evalua la Expresion para el DinamicDispatch tail +#Get Local Var l +#Fin de la exprecion previa al DinamicDispatch tail +lw $t0, 32($sp) #Lee el valor de la var l@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con l@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion tail +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch print_list +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_print_list@0 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_print_list_0 # +then_Main_print_list_0: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 36($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_print_list_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 40 # +jr $ra # + +List_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_tail +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_tail: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_tail +#Get Self Property cdr +lw $t0, 4($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +List_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_isNil +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_isNil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_isNil +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Cons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Cons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_List # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_init: # +#Parametro self en stackpoiner + 12 +#Parametro i@0 en stackpoiner + 8 +#Parametro rest@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable car +#Get Local Var i +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded car +sw $t1, 4($t0) #Setea la propiedad car con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable cdr +#Get Local Var rest +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded cdr +sw $t1, 8($t0) #Setea la propiedad cdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad cdr +move $s4, $t1 #Guarda el valor de la propiedad cdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +List_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_head +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_head: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_head +#Get Self Property car +lw $t0, 4($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad car +move $s4, $t1 #Guarda el valor de la propiedad car en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/list_input.txt b/tests/codegen/list_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/list_output.txt b/tests/codegen/list_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/new_complex.mips b/tests/codegen/new_complex.mips new file mode 100644 index 000000000..f58369328 --- /dev/null +++ b/tests/codegen/new_complex.mips @@ -0,0 +1,1367 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +Complex_parents: .word 1, 6, 8, 0, +Complex_Name: .asciiz "Complex" +Complex: .word Complex_Name, 3, Complex_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Complex_init, Complex_print, Complex_reflect_0, Complex_reflect_X, Complex_reflect_Y, Complex_equal, Complex_x_value, Complex_y_value, +string_0: .asciiz "=(\n" +string_1: .asciiz "=)\n" +string_2: .asciiz "=(\n" +string_3: .asciiz "=)\n" +string_4: .asciiz "+" +string_5: .asciiz "I" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 76 +addi $sp, $sp, -4 #Push local var c stackpointer 72 +addi $sp, $sp, -4 #Push local var new_Complex@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var ref_eq@_a@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var ref_eq@_b@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_X@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_0@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_X@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_Y@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_equal@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_reflect_0@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_equal@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@3 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Eval Expression to Let c +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Complex +#Allocate a una class Complex +#atributo type_name en puntero + 0 +#atributo x en puntero + 4 +#atributo y en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 68($sp) #Guardando en la variable local new_Complex@0 puntero de la instancia de la clase Complex +#Assignacion de la insformacion de tipo a la instancia +la $t0, Complex # +move $s4, $t0 # +lw $t0, 68($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 68($sp) #Lee el valor de la var new_Complex@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Complex@0 +jal new_ctr_Complex # +sw $v0, 64($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +li $s4, 1 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 56($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 64($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 64($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 64($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +sw $v0, 72($sp) #Asigna el resultado de la funcion +#Fin de la asignacion Let c +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion ref_eq +#Evalua la Expresion para el DinamicDispatch reflect_X +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_X +lw $t0, 72($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion reflect_X +jal $t3 # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion ref_eq +#Evaluando el operado derecho de una operacion ref_eq +#Evalua la Expresion para el DinamicDispatch reflect_0 +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_0 +lw $t0, 72($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion reflect_0 +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion ref_eq +lw $t0, 52($sp) # +lw $t1, 48($sp) # +seq $a0, $t1, $t0 # +lw $s6, 76($sp) #Guarda self +jal __int__new__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 76($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_0 # +#Else case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 40($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_0 # +then_Main_main_0: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 36($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_0: +#Fin de un If +#Inicio del paso 1 de una sequencia Block +#Evalua la condicion de un If +#Evalua la Expresion para el DinamicDispatch equal +#Evalua la Expresion para el DinamicDispatch reflect_Y +#Evalua la Expresion para el DinamicDispatch reflect_X +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_X +lw $t0, 72($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion reflect_X +jal $t3 # +sw $v0, 24($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch reflect_Y +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_reflect_Y@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_reflect_Y@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion reflect_Y +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch equal +#Evalua el parametro 0 para el CastingDispatch equal +#Evalua la Expresion para el DinamicDispatch reflect_0 +#Get Local Var c +#Fin de la exprecion previa al DinamicDispatch reflect_0 +lw $t0, 72($sp) #Lee el valor de la var c +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con c +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion reflect_0 +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch equal +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_equal@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_equal@0 +lw $t0, 16($sp) #Lee el valor de la var param_0_to_equal@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_equal@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion equal +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_1 # +#Else case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_1 # +then_Main_main_1: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 76($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 76($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@3 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@3 +lw $t0, 84($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_1: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 80 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Complex: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Complex +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Complex +move $t1, $s4 #Guarda el valor que se le asignara a la propieded x +sw $t1, 4($t0) #Setea la propiedad x con el valor de _ +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Complex +move $t1, $s4 #Guarda el valor que se le asignara a la propieded y +sw $t1, 8($t0) #Setea la propiedad y con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Complex_init: # +#Parametro self en stackpoiner + 28 +#Parametro a@0 en stackpoiner + 24 +#Parametro b@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 28($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 16($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var a +lw $t0, 24($sp) # +sw $t0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 28($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@1 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Get Local Var b +lw $t0, 20($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 28($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 28($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 28($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 32 # +jr $ra # + +Complex_reflect_X: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_X +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property y +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +move $s4, $t1 #Guarda el valor de la propiedad y en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 12($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Complex_reflect_0: # +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_0 +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 16($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property x +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +move $s4, $t1 #Guarda el valor de la propiedad x en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 20($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 20($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 8($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@1 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property y +lw $t0, 20($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +move $s4, $t1 #Guarda el valor de la propiedad y en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 20($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 20($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 20($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +Complex_reflect_Y: # +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_reflect_Y +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 8($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evaluando la expression de una operacion unaria +#Get Self Property x +lw $t0, 12($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +move $s4, $t1 #Guarda el valor de la propiedad x en la variable local _ +#FIN expression de una operacion unaria +lw $s6, 12($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +sw $v0, 4($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 12($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Inicio del paso 1 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Complex_equal: # +#Parametro self en stackpoiner + 32 +#Parametro d@0 en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_x_value@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_y_value@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_equal +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property x +lw $t0, 32($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +sw $t1, 24($sp) #Guarda el valor de la propiedad x en la variable local int_eq@_a@0 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch x_value +#Get Local Var d +#Fin de la exprecion previa al DinamicDispatch x_value +lw $t0, 28($sp) #Lee el valor de la var d@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con d@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion x_value +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 32($sp) #Guarda self +lw $a0, 24($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 20($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 32($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Complex_equal_0 # +#Else case +li $s4, 0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_Complex_equal_0 # +then_Complex_equal_0: +#Then case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Get Self Property y +lw $t0, 32($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +sw $t1, 12($sp) #Guarda el valor de la propiedad y en la variable local int_eq@_a@1 +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch y_value +#Get Local Var d +#Fin de la exprecion previa al DinamicDispatch y_value +lw $t0, 28($sp) #Lee el valor de la var d@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con d@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Complex +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion y_value +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 32($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 8($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 32($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Complex_equal_1 # +#Else case +li $s4, 0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_Complex_equal_1 # +then_Complex_equal_1: +#Then case +li $s4, 1 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 32($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_Complex_equal_1: +#Fin de un If +fin_Complex_equal_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 36 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Complex_x_value: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_x_value +#Get Self Property x +lw $t0, 4($sp) #Instancia de la clase Complex +lw $t1, 4($t0) #Lee la propiedad x +move $s4, $t1 #Guarda el valor de la propiedad x en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Complex_y_value: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Complex_y_value +#Get Self Property y +lw $t0, 4($sp) #Instancia de la clase Complex +lw $t1, 8($t0) #Lee la propiedad y +move $s4, $t1 #Guarda el valor de la propiedad y en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +Complex_print: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/new_complex_input.txt b/tests/codegen/new_complex_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/new_complex_output.txt b/tests/codegen/new_complex_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/palindrome.mips b/tests/codegen/palindrome.mips new file mode 100644 index 000000000..f953bc069 --- /dev/null +++ b/tests/codegen/palindrome.mips @@ -0,0 +1,1176 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 2, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_pal, Main_main, +string_0: .asciiz "enter a string\n" +string_1: .asciiz "that was not a palindrome\n" +string_2: .asciiz "that was a palindrome\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo i en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded i +sw $t1, 4($t0) #Setea la propiedad i con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable i +#Evaluando la expression de una operacion unaria +li $s4, 1 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +#FIN expression de una operacion unaria +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__complement__ # +move $s4, $v0 # +lw $t0, 20($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded i +sw $t1, 4($t0) #Setea la propiedad i con el valor de _ +lw $t0, 20($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad i +move $s4, $t1 #Guarda el valor de la propiedad i en la variable local _ +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Evalua la condicion de un If +#StaticDispatch pal +#Evalua el parametro 0 para el CastingDispatch pal +#StaticDispatch in_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion in_string +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch pal +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_pal@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_pal@0 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion pal +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_main_0 # +#Else case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Main_main_0 # +then_Main_main_0: +#Then case +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 20($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 20($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_main_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_in_string: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_string +lw $s6, 4($sp) #Guarda self +jal __str__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Main_pal: # +#Parametro self en stackpoiner + 104 +#Parametro s@0 en stackpoiner + 100 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 84 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var str_eq@_a@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var str_eq@_b@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@2 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_length@3 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_pal +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 100($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 96($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 92($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 104($sp) #Guarda self +lw $a0, 96($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 92($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 104($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_pal_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 100($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 84($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 80($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 104($sp) #Guarda self +lw $a0, 84($sp) #Guarda el parametro 0 -> int_eq@_a@1 +lw $a1, 80($sp) #Guarda el parametro 1 -> int_eq@_b@1 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 104($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_pal_1 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 100($sp) # +sw $t0, 64($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 60($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 56($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 64($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 64($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 64($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 76($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 72($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion str_eq +#Evaluando el operado derecho de una operacion str_eq +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 100($sp) # +sw $t0, 52($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 100($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 48($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 104($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 36($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 32($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 52($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 40($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 40($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 68($sp) #Asigna el resultado de la funcion +#Resolucion del operado derecha de una operacion str_eq +lw $s6, 104($sp) #Guarda self +lw $a0, 72($sp) #Guarda el parametro 0 -> str_eq@_a@0 +lw $a1, 68($sp) #Guarda el parametro 1 -> str_eq@_b@0 +jal __str__cmp__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 104($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Main_pal_2 # +#Else case +li $s4, 0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_Main_pal_2 # +then_Main_pal_2: +#Then case +#StaticDispatch pal +#Evalua el parametro 0 para el CastingDispatch pal +#Evalua la Expresion para el DinamicDispatch substr +#Get Local Var s +lw $t0, 100($sp) # +sw $t0, 28($sp) # +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +#Evaluando el operado izquierdo de una operacion rest +#Evalua la Expresion para el DinamicDispatch length +#Get Local Var s +#Fin de la exprecion previa al DinamicDispatch length +lw $t0, 100($sp) #Lee el valor de la var s@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con s@0 +lw $t0, 104($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +li $s4, 2 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 104($sp) #Guarda self +lw $a0, 20($sp) #Guarda el parametro 0 -> rest@_a@1 +lw $a1, 16($sp) #Guarda el parametro 1 -> rest@_b@1 +jal __int__sub__ # +sw $v0, 8($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@2 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@2 +lw $t0, 16($sp) #Lee el valor de la var param_1_to_substr@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@2 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch pal +lw $t0, 104($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_pal@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_pal@0 +lw $t0, 112($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion pal +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Main_pal_2: +#Fin de un If +j fin_Main_pal_1 # +then_Main_pal_1: +#Then case +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_Main_pal_1: +#Fin de un If +j fin_Main_pal_0 # +then_Main_pal_0: +#Then case +li $s4, 1 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 104($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_Main_pal_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 108 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +String_length: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_length +lw $s6, 4($sp) #Guarda self +jal __str__length__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/palindrome_input.txt b/tests/codegen/palindrome_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/palindrome_output.txt b/tests/codegen/palindrome_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/primes.cl b/tests/codegen/primes.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/primes.mips b/tests/codegen/primes.mips new file mode 100644 index 000000000..8c81e1e7e --- /dev/null +++ b/tests/codegen/primes.mips @@ -0,0 +1,1236 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 6, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "2 is trivially prime.\n" +string_1: .asciiz " is prime.\n" +string_2: .asciiz "continue" +string_3: .asciiz "halt" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo out en puntero + 4 +#atributo testee en puntero + 8 +#atributo divisor en puntero + 12 +#atributo stop en puntero + 16 +#atributo m en puntero + 20 +li $a0, 24 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 108 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 92 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 88 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var factor@_a@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var factor@_b@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var factor@_a@1 stackpointer 52 +addi $sp, $sp, -4 #Push local var factor@_b@1 stackpointer 48 +addi $sp, $sp, -4 #Push local var div@_a@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var div@_b@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var less@_a@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var less@_b@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var factor@_a@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var factor@_b@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var leq@_a@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var leq@_b@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_abort@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +#Assignando el resultado de la expression al atributo out de la clase Main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 104($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 108($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +li $s4, 2 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 4($t0) #Setea la propiedad out con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo testee de la clase Main +#Get Self Property out +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded testee +sw $t1, 8($t0) #Setea la propiedad testee con el valor de _ +#Fin De la Asignacion +li $s4, 0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded divisor +sw $t1, 12($t0) #Setea la propiedad divisor con el valor de _ +#Assignando el resultado de la expression al atributo stop de la clase Main +li $s4, 500 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded stop +sw $t1, 16($t0) #Setea la propiedad stop con el valor de _ +#Fin De la Asignacion +#Assignando el resultado de la expression al atributo m de la clase Main +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable testee +#Evaluando el operado izquierdo de una operacion sum +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 100($sp) #Guarda el valor de la propiedad testee en la variable local sum@_a@0 +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 96($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 108($sp) #Guarda self +lw $a0, 100($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 96($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded testee +sw $t1, 8($t0) #Setea la propiedad testee con el valor de _ +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +move $s4, $t1 #Guarda el valor de la propiedad testee en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable divisor +li $s4, 2 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded divisor +sw $t1, 12($t0) #Setea la propiedad divisor con el valor de _ +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +move $s4, $t1 #Guarda el valor de la propiedad divisor en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Inicio de un While +j while_cond_1 # +while_back_1: +#Asignando un nuevo valor a la variable divisor +#Evaluando el operado izquierdo de una operacion sum +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 92($sp) #Guarda el valor de la propiedad divisor en la variable local sum@_a@1 +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 88($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 108($sp) #Guarda self +lw $a0, 92($sp) #Guarda el parametro 0 -> sum@_a@1 +lw $a1, 88($sp) #Guarda el parametro 1 -> sum@_b@1 +jal __int__sum__ # +move $s4, $v0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded divisor +sw $t1, 12($t0) #Setea la propiedad divisor con el valor de _ +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +move $s4, $t1 #Guarda el valor de la propiedad divisor en la variable local _ +#Fin del cuerpo e inicio de la condicion de un While +while_cond_1: +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 84($sp) #Guarda el valor de la propiedad testee en la variable local less@_a@0 +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Evaluando el operado izquierdo de una operacion factor +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 76($sp) #Guarda el valor de la propiedad divisor en la variable local factor@_a@0 +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 72($sp) #Guarda el valor de la propiedad divisor en la variable local factor@_b@0 +#Resolucion del operado derecha de una operacion factor +lw $s6, 108($sp) #Guarda self +lw $a0, 76($sp) #Guarda el parametro 0 -> factor@_a@0 +lw $a1, 72($sp) #Guarda el parametro 1 -> factor@_b@0 +jal __int__mul__ # +sw $v0, 80($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 108($sp) #Guarda self +lw $a0, 84($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 80($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 108($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_new_ctr_Main_0 # +#Else case +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion int_eq +#Evaluando el operado izquierdo de una operacion rest +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 60($sp) #Guarda el valor de la propiedad testee en la variable local rest@_a@0 +#Resolucion del operado izquierdo de una operacion rest +#Evaluando el operado derecho de una operacion rest +#Evaluando el operado izquierdo de una operacion factor +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 52($sp) #Guarda el valor de la propiedad divisor en la variable local factor@_a@1 +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Evaluando el operado izquierdo de una operacion div +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 44($sp) #Guarda el valor de la propiedad testee en la variable local div@_a@0 +#Resolucion del operado izquierdo de una operacion div +#Evaluando el operado derecho de una operacion div +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 40($sp) #Guarda el valor de la propiedad divisor en la variable local div@_b@0 +#Resolucion del operado derecha de una operacion div +lw $s6, 108($sp) #Guarda self +lw $a0, 44($sp) #Guarda el parametro 0 -> div@_a@0 +lw $a1, 40($sp) #Guarda el parametro 1 -> div@_b@0 +jal __int__div__ # +sw $v0, 48($sp) # +#Resolucion del operado derecha de una operacion factor +lw $s6, 108($sp) #Guarda self +lw $a0, 52($sp) #Guarda el parametro 0 -> factor@_a@1 +lw $a1, 48($sp) #Guarda el parametro 1 -> factor@_b@1 +jal __int__mul__ # +sw $v0, 56($sp) # +#Resolucion del operado derecha de una operacion rest +lw $s6, 108($sp) #Guarda self +lw $a0, 60($sp) #Guarda el parametro 0 -> rest@_a@0 +lw $a1, 56($sp) #Guarda el parametro 1 -> rest@_b@0 +jal __int__sub__ # +sw $v0, 68($sp) # +#Resolucion del operado izquierdo de una operacion int_eq +#Evaluando el operado derecho de una operacion int_eq +li $s4, 0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 64($sp) # +#Resolucion del operado derecha de una operacion int_eq +lw $s6, 108($sp) #Guarda self +lw $a0, 68($sp) #Guarda el parametro 0 -> int_eq@_a@0 +lw $a1, 64($sp) #Guarda el parametro 1 -> int_eq@_b@0 +jal __int__eq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 108($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_new_ctr_Main_1 # +#Else case +li $s4, 1 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +j fin_new_ctr_Main_1 # +then_new_ctr_Main_1: +#Then case +li $s4, 0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_new_ctr_Main_1: +#Fin de un If +j fin_new_ctr_Main_0 # +then_new_ctr_Main_0: +#Then case +li $s4, 0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +fin_new_ctr_Main_0: +#Fin de un If +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_1 # +#Fin de la condicion de un While +lw $t0, 108($sp) # +move $s4, $t0 # +#Inicio del paso 3 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 36($sp) #Guarda el valor de la propiedad testee en la variable local less@_a@1 +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Evaluando el operado izquierdo de una operacion factor +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 28($sp) #Guarda el valor de la propiedad divisor en la variable local factor@_a@2 +#Resolucion del operado izquierdo de una operacion factor +#Evaluando el operado derecho de una operacion factor +#Get Self Property divisor +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 12($t0) #Lee la propiedad divisor +sw $t1, 24($sp) #Guarda el valor de la propiedad divisor en la variable local factor@_b@2 +#Resolucion del operado derecha de una operacion factor +lw $s6, 108($sp) #Guarda self +lw $a0, 28($sp) #Guarda el parametro 0 -> factor@_a@2 +lw $a1, 24($sp) #Guarda el parametro 1 -> factor@_b@2 +jal __int__mul__ # +sw $v0, 32($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 108($sp) #Guarda self +lw $a0, 36($sp) #Guarda el parametro 0 -> less@_a@1 +lw $a1, 32($sp) #Guarda el parametro 1 -> less@_b@1 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 108($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_new_ctr_Main_2 # +#Else case +li $s4, 0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +j fin_new_ctr_Main_2 # +then_new_ctr_Main_2: +#Then case +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable out +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +move $s4, $t1 #Guarda el valor de la propiedad testee en la variable local _ +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded out +sw $t1, 4($t0) #Setea la propiedad out con el valor de _ +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad out +move $s4, $t1 #Guarda el valor de la propiedad out en la variable local _ +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property out +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad out +sw $t1, 20($sp) #Guarda el valor de la propiedad out en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 108($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 116($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_new_ctr_Main_2: +#Fin de un If +#Inicio del paso 4 de una sequencia Block +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion leq +#Get Self Property stop +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 16($t0) #Lee la propiedad stop +sw $t1, 12($sp) #Guarda el valor de la propiedad stop en la variable local leq@_a@0 +#Resolucion del operado izquierdo de una operacion leq +#Evaluando el operado derecho de una operacion leq +#Get Self Property testee +lw $t0, 108($sp) #Instancia de la clase Main +lw $t1, 8($t0) #Lee la propiedad testee +sw $t1, 8($sp) #Guarda el valor de la propiedad testee en la variable local leq@_b@0 +#Resolucion del operado derecha de una operacion leq +lw $s6, 108($sp) #Guarda self +lw $a0, 12($sp) #Guarda el parametro 0 -> leq@_a@0 +lw $a1, 8($sp) #Guarda el parametro 1 -> leq@_b@0 +jal __int__leq__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 108($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_new_ctr_Main_3 # +#Else case +la $t0, string_2 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +move $s4, $v0 # +j fin_new_ctr_Main_3 # +then_new_ctr_Main_3: +#Then case +#Evalua la Expresion para el DinamicDispatch abort +la $t0, string_3 # +move $s4, $t0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin de la exprecion previa al DinamicDispatch abort +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_abort@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_abort@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_new_ctr_Main_3: +#Fin de un If +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +li $s4, 1 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 108($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 108($sp) # +move $s4, $t0 # +lw $t0, 108($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded m +sw $t1, 20($t0) #Setea la propiedad m con el valor de _ +#Fin De la Asignacion +lw $v0, 108($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 112 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/primes_input.txt b/tests/codegen/primes_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/primes_output.txt b/tests/codegen/primes_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/print-cool.cl b/tests/codegen/print-cool.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/print-cool.mips b/tests/codegen/print-cool.mips new file mode 100644 index 000000000..90a5759a5 --- /dev/null +++ b/tests/codegen/print-cool.mips @@ -0,0 +1,894 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +Main_parents: .word 1, 6, 7, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 1, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +string_0: .asciiz "\n" + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 64 +addi $sp, $sp, -4 #Push local var new_Object@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_type_name@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_out_string@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var ref_eq@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var ref_eq@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_type_name@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_substr@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch out_string +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch substr +#Evalua la Expresion para el DinamicDispatch type_name +#Creando instancia de tipo Object +#Allocate a una class Object +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 60($sp) #Guardando en la variable local new_Object@0 puntero de la instancia de la clase Object +#Assignacion de la insformacion de tipo a la instancia +la $t0, Object # +move $s4, $t0 # +lw $t0, 60($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 60($sp) #Lee el valor de la var new_Object@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Object@0 +jal new_ctr_Object # +sw $v0, 56($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch type_name +lw $t0, 56($sp) #Lee el valor de la var instance_dynamic_to_type_name@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_type_name@0 +lw $t0, 60($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Object +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion type_name +jal $t3 # +sw $v0, 52($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 4 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 48($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 44($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 52($sp) #Lee el valor de la var instance_dynamic_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@0 +lw $t0, 52($sp) #Lee el valor de la var param_0_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@0 +lw $t0, 52($sp) #Lee el valor de la var param_1_to_substr@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@0 +lw $t0, 64($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 40($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 44($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +#Evalua la Expresion para el DinamicDispatch substr +#Evalua la Expresion para el DinamicDispatch type_name +la $t0, _______null_______ # +sw $t0, 28($sp) # +#void check +#Get Local Var self +lw $t0, 64($sp) # +sw $t0, 32($sp) # +lw $t0, 28($sp) # +lw $t1, 32($sp) # +seq $a0, $t1, $t0 # +lw $s6, 64($sp) #Guarda self +jal __int__new__ # +sw $v0, 24($sp) # +move $a0, $v0 # +lw $s6, 64($sp) #Guarda self +jal __bool__new__ # +sw $v0, 24($sp) # +#Fin de la exprecion previa al DinamicDispatch type_name +lw $t0, 24($sp) #Lee el valor de la var instance_dynamic_to_type_name@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_type_name@1 +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Bool +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion type_name +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch substr +#Evalua el parametro 0 para el CastingDispatch substr +li $s4, 1 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 16($sp) # +#Fin del paramentro 0 al CastingDispatch substr +#Evalua el parametro 1 para el CastingDispatch substr +li $s4, 3 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Fin del paramentro 1 al CastingDispatch substr +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_substr@1 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_substr@1 +lw $t0, 20($sp) #Lee el valor de la var param_1_to_substr@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_substr@1 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de String +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_out_string@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@1 +lw $t0, 44($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 64($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 64($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_out_string@2 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@2 +lw $t0, 72($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 68 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Object_type_name: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_type_name +lw $s6, 4($sp) #Guarda self +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +String_substr: # +#Parametro self en stackpoiner + 8 +#Parametro index en stackpoiner + 4 +#Parametro count en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion String_substr +lw $s6, 12($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> index +lw $a1, 4($sp) #Guarda el parametro 1 -> count +jal __str__substr__ # +lw $ra, 0($sp) # +addi $sp, $sp, 16 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_int: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +IO_out_int: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_abort: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/print-cool_input.txt b/tests/codegen/print-cool_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/print-cool_output.txt b/tests/codegen/print-cool_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/sort-list.cl b/tests/codegen/sort-list.cl old mode 100644 new mode 100755 diff --git a/tests/codegen/sort-list.mips b/tests/codegen/sort-list.mips new file mode 100644 index 000000000..65e583fe5 --- /dev/null +++ b/tests/codegen/sort-list.mips @@ -0,0 +1,1780 @@ +.data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" +Bool_parents: .word 1, 2, 0, +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, Bool_parents, Object_abort, Object_copy, Object_type_name, +Int_parents: .word 1, 3, 0, +Int_Name: .asciiz "Int" +Int: .word Int_Name, 2, Int_parents, Object_abort, Object_copy, Object_type_name, +String_parents: .word 1, 4, 0, +String_Name: .asciiz "String" +String: .word String_Name, 2, String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +SELF_TYPE_parents: .word 1, 5, 0, +SELF_TYPE_Name: .asciiz "SELF_TYPE" +SELF_TYPE: .word SELF_TYPE_Name, 1, SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +Object_parents: .word 1, 0, +Object_Name: .asciiz "Object" +Object: .word Object_Name, 1, Object_parents, Object_abort, Object_copy, Object_type_name, +IO_parents: .word 1, 6, 0, +IO_Name: .asciiz "IO" +IO: .word IO_Name, 1, IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +List_parents: .word 1, 6, 7, 0, +List_Name: .asciiz "List" +List: .word List_Name, 1, List_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, List_isNil, List_cons, List_car, List_cdr, List_rev, List_sort, List_insert, List_rcons, List_print_list, +Cons_parents: .word 1, 6, 7, 8, 0, +Cons_Name: .asciiz "Cons" +Cons: .word Cons_Name, 3, Cons_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Cons_isNil, List_cons, Cons_car, Cons_cdr, Cons_rev, Cons_sort, Cons_insert, Cons_rcons, Cons_print_list, Cons_init, +Nil_parents: .word 1, 6, 7, 9, 0, +Nil_Name: .asciiz "Nil" +Nil: .word Nil_Name, 1, Nil_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Nil_isNil, List_cons, List_car, List_cdr, Nil_rev, Nil_sort, Nil_insert, Nil_rcons, Nil_print_list, +Main_parents: .word 1, 6, 10, 0, +Main_Name: .asciiz "Main" +Main: .word Main_Name, 2, Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_iota, Main_main, +string_0: .asciiz "\n" +string_1: .asciiz "How many numbers to sort? " + +.text +.globl main +main: # +addi $sp, $sp, -4 #Push local var self stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main +#atributo type_name en puntero + 0 +#atributo l en puntero + 4 +li $a0, 8 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local self puntero de la instancia de la clase Main +#Assignacion de la insformacion de tipo a Main +la $t0, Main # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Main # +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal Main_main # +li $v0, 10 # +syscall + +new_ctr_Main: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Main +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded l +sw $t1, 4($t0) #Setea la propiedad l con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Main_main: # +#Parametro self en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_iota@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_rev@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_sort@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_list@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_main +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_1 # +move $s4, $t0 # +lw $s6, 24($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 20($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 24($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 24($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_list +#Evalua la Expresion para el DinamicDispatch sort +#Evalua la Expresion para el DinamicDispatch rev +#StaticDispatch iota +#Evalua el parametro 0 para el CastingDispatch iota +#StaticDispatch in_int +lw $t0, 24($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 28($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion in_int +jal $t3 # +sw $v0, 16($sp) #Asigna el resultado de la funcion +#Fin del paramentro 0 al CastingDispatch iota +lw $t0, 24($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 20($sp) #Lee el valor de la var param_0_to_iota@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_iota@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Main +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion iota +jal $t3 # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch rev +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_rev@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_rev@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion rev +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch sort +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_sort@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_sort@0 +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion sort +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch print_list +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_list@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 72($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +new_ctr_IO: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_IO +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_Object # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +IO_out_string: # +#Parametro self en stackpoiner + 4 +#Parametro string en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_string +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> string +jal __str__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +IO_in_int: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_in_int +lw $s6, 4($sp) #Guarda self +jal __int__input__ # +lw $ra, 0($sp) # +addi $sp, $sp, 8 # +jr $ra # + +Main_iota: # +#Parametro self en stackpoiner + 48 +#Parametro i@0 en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var new_Nil@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var j stackpointer 36 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Main_iota +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable l +#Creando instancia de tipo Nil +#Allocate a una class Nil +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 40($sp) #Guardando en la variable local new_Nil@0 puntero de la instancia de la clase Nil +#Assignacion de la insformacion de tipo a la instancia +la $t0, Nil # +move $s4, $t0 # +lw $t0, 40($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 40($sp) #Lee el valor de la var new_Nil@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Nil@0 +jal new_ctr_Nil # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 48($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded l +sw $t1, 4($t0) #Setea la propiedad l con el valor de _ +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad l +move $s4, $t1 #Guarda el valor de la propiedad l en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Eval Expression to Let j +li $s4, 0 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 36($sp) # +#Fin de la asignacion Let j +#Inicio de un While +j while_cond_0 # +while_back_0: +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable l +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 32($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 32($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 32($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 28($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var j +lw $t0, 36($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Self Property l +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad l +sw $t1, 20($sp) #Guarda el valor de la propiedad l en la variable local param_1_to_init@0 +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 28($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 40($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +lw $t0, 48($sp) #Instancia de la clase Main +move $t1, $s4 #Guarda el valor que se le asignara a la propieded l +sw $t1, 4($t0) #Setea la propiedad l con el valor de _ +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad l +move $s4, $t1 #Guarda el valor de la propiedad l en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable j +#Evaluando el operado izquierdo de una operacion sum +#Get Local Var j +lw $t0, 36($sp) # +sw $t0, 16($sp) # +#Resolucion del operado izquierdo de una operacion sum +#Evaluando el operado derecho de una operacion sum +li $s4, 1 # +lw $s6, 48($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +sw $v0, 12($sp) # +#Resolucion del operado derecha de una operacion sum +lw $s6, 48($sp) #Guarda self +lw $a0, 16($sp) #Guarda el parametro 0 -> sum@_a@0 +lw $a1, 12($sp) #Guarda el parametro 1 -> sum@_b@0 +jal __int__sum__ # +move $s4, $v0 # +move $t0, $s4 # +sw $t0, 36($sp) # +lw $t0, 36($sp) # +move $s4, $t0 # +#Fin del cuerpo e inicio de la condicion de un While +while_cond_0: +#Evaluando el operado izquierdo de una operacion less +#Get Local Var j +lw $t0, 36($sp) # +sw $t0, 8($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Local Var i +lw $t0, 44($sp) # +sw $t0, 4($sp) # +#Resolucion del operado derecha de una operacion less +lw $s6, 48($sp) #Guarda self +lw $a0, 8($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 4($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 48($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, while_back_0 # +#Fin de la condicion de un While +lw $t0, 48($sp) # +move $s4, $t0 # +#Inicio del paso 2 de una sequencia Block +#Get Self Property l +lw $t0, 48($sp) #Instancia de la clase Main +lw $t1, 4($t0) #Lee la propiedad l +move $s4, $t1 #Guarda el valor de la propiedad l en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 52 # +jr $ra # + +List_rev: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_rev +#StaticDispatch cdr +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cdr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_rev: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_rev@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_rcons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_rcons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_rev +#Evalua la Expresion para el DinamicDispatch rcons +#Evalua la Expresion para el DinamicDispatch rev +#Get Self Property xcdr +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 12($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_rev@0 +#Fin de la exprecion previa al DinamicDispatch rev +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_rev@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_rev@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 56($t1) #Buscando el metodo dinamico para la funcion rev +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch rcons +#Evalua el parametro 0 para el CastingDispatch rcons +#Get Self Property xcar +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 4($sp) #Guarda el valor de la propiedad xcar en la variable local param_0_to_rcons@0 +#Fin del paramentro 0 al CastingDispatch rcons +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_rcons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_rcons@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_rcons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_rcons@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion rcons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +Nil_rev: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_rev +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +List_sort: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_sort +#StaticDispatch cdr +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cdr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_sort: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_sort@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_insert@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_0_to_insert@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_sort +#Evalua la Expresion para el DinamicDispatch insert +#Evalua la Expresion para el DinamicDispatch sort +#Get Self Property xcdr +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 12($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_sort@0 +#Fin de la exprecion previa al DinamicDispatch sort +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_sort@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_sort@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion sort +jal $t3 # +sw $v0, 8($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch insert +#Evalua el parametro 0 para el CastingDispatch insert +#Get Self Property xcar +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 4($sp) #Guarda el valor de la propiedad xcar en la variable local param_0_to_insert@0 +#Fin del paramentro 0 al CastingDispatch insert +lw $t0, 8($sp) #Lee el valor de la var instance_dynamic_to_insert@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_insert@0 +lw $t0, 8($sp) #Lee el valor de la var param_0_to_insert@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_insert@0 +lw $t0, 16($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion insert +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +Nil_sort: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_sort +#Get Local Var self +lw $t0, 4($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +List_print_list: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_print_list +#StaticDispatch abort +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_print_list: # +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_int@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_print_list@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_print_list +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch out_int +#Evalua el parametro 0 para el CastingDispatch out_int +#Get Self Property xcar +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 12($sp) #Guarda el valor de la propiedad xcar en la variable local param_0_to_out_int@0 +#Fin del paramentro 0 al CastingDispatch out_int +lw $t0, 16($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 16($sp) #Lee el valor de la var param_0_to_out_int@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_int@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_int +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#StaticDispatch out_string +#Evalua el parametro 0 para el CastingDispatch out_string +la $t0, string_0 # +move $s4, $t0 # +lw $s6, 16($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __str__new__ # +sw $v0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch out_string +lw $t0, 16($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) #Lee el valor de la var param_0_to_out_string@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_out_string@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 2 de una sequencia Block +#Evalua la Expresion para el DinamicDispatch print_list +#Get Self Property xcdr +lw $t0, 16($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 4($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_print_list@0 +#Fin de la exprecion previa al DinamicDispatch print_list +lw $t0, 4($sp) #Lee el valor de la var instance_dynamic_to_print_list@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_print_list@0 +lw $t0, 8($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 72($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 20 # +jr $ra # + +Nil_print_list: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_print_list +li $s4, 1 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __bool__new__ # +move $s4, $v0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Object: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Object +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Nil: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Nil +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_List # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Cons: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Cons +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_List # +li $s4, 0 # +lw $s6, 4($sp) #Guarda self +move $a0, $s4 #Guarda el parametro 0 -> _ +jal __int__new__ # +move $s4, $v0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcar +sw $t1, 4($t0) #Setea la propiedad xcar con el valor de _ +la $t0, _______null_______ # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcdr +sw $t1, 8($t0) #Setea la propiedad xcdr con el valor de _ +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +Cons_init: # +#Parametro self en stackpoiner + 12 +#Parametro hd@0 en stackpoiner + 8 +#Parametro tl@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_init +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#Asignando un nuevo valor a la variable xcar +#Get Local Var hd +lw $t0, 8($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcar +sw $t1, 4($t0) #Setea la propiedad xcar con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +move $s4, $t1 #Guarda el valor de la propiedad xcar en la variable local _ +#Inicio del paso 1 de una sequencia Block +#Asignando un nuevo valor a la variable xcdr +#Get Local Var tl +lw $t0, 4($sp) # +move $s4, $t0 # +lw $t0, 12($sp) #Instancia de la clase Cons +move $t1, $s4 #Guarda el valor que se le asignara a la propieded xcdr +sw $t1, 8($t0) #Setea la propiedad xcdr con el valor de _ +lw $t0, 12($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +move $s4, $t1 #Guarda el valor de la propiedad xcdr en la variable local _ +#Inicio del paso 2 de una sequencia Block +#Get Local Var self +lw $t0, 12($sp) # +move $s4, $t0 # +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +List_cdr: # +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var new_List@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_cdr +#Inicio de una secuencia Block +#Inicio del paso 0 de una sequencia Block +#StaticDispatch abort +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 12($t1) #Buscando el metodo dinamico para la funcion abort +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +#Inicio del paso 1 de una sequencia Block +#Creando instancia de tipo List +#Allocate a una class List +#atributo type_name en puntero + 0 +li $a0, 4 # +li $v0, 9 # +syscall +sw $v0, 4($sp) #Guardando en la variable local new_List@0 puntero de la instancia de la clase List +#Assignacion de la insformacion de tipo a la instancia +la $t0, List # +move $s4, $t0 # +lw $t0, 4($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 4($sp) #Lee el valor de la var new_List@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_List@0 +jal new_ctr_List # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Cons_cdr: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_cdr +#Get Self Property xcdr +lw $t0, 4($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +move $s4, $t1 #Guarda el valor de la propiedad xcdr en la variable local _ +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +List_rcons: # +#Parametro self en stackpoiner + 8 +#Parametro i@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_rcons +#StaticDispatch cdr +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cdr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Cons_rcons: # +#Parametro self en stackpoiner + 32 +#Parametro i@0 en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_rcons@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_rcons@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_rcons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 24($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 24($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 24($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Self Property xcar +lw $t0, 32($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 16($sp) #Guarda el valor de la propiedad xcar en la variable local param_0_to_init@0 +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Evalua la Expresion para el DinamicDispatch rcons +#Get Self Property xcdr +lw $t0, 32($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 12($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_rcons@0 +#Fin de la exprecion previa al DinamicDispatch rcons +#Evalua el parametro 0 para el CastingDispatch rcons +#Get Local Var i +lw $t0, 28($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch rcons +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_rcons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_rcons@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_rcons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_rcons@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion rcons +jal $t3 # +sw $v0, 4($sp) #Asigna el resultado de la funcion +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 20($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 20($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 32($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 36 # +jr $ra # + +Nil_rcons: # +#Parametro self en stackpoiner + 24 +#Parametro i@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_rcons +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var i +lw $t0, 20($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 24($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 # +jr $ra # + +List_insert: # +#Parametro self en stackpoiner + 8 +#Parametro i@0 en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion List_insert +#StaticDispatch cdr +lw $t0, 8($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 12($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 52($t1) #Buscando el metodo dinamico para la funcion cdr +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 # +jr $ra # + +Cons_insert: # +#Parametro self en stackpoiner + 56 +#Parametro i@0 en stackpoiner + 52 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var new_Cons@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_insert@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_insert@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var new_Cons@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_dynamic_to_init@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_init@1 stackpointer 8 +addi $sp, $sp, -4 #Push local var param_1_to_init@1 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Cons_insert +#Evalua la condicion de un If +#Evaluando el operado izquierdo de una operacion less +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 48($sp) # +#Resolucion del operado izquierdo de una operacion less +#Evaluando el operado derecho de una operacion less +#Get Self Property xcar +lw $t0, 56($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 44($sp) #Guarda el valor de la propiedad xcar en la variable local less@_b@0 +#Resolucion del operado derecha de una operacion less +lw $s6, 56($sp) #Guarda self +lw $a0, 48($sp) #Guarda el parametro 0 -> less@_a@0 +lw $a1, 44($sp) #Guarda el parametro 1 -> less@_b@0 +jal __int__le__ # +move $s4, $v0 # +move $a0, $v0 # +lw $s6, 56($sp) #Guarda self +jal __bool__new__ # +move $s4, $v0 # +#Fin de la evaluacion de la condicion de un IF +#Check Condition And Try Jump +move $t0, $s4 #Guarda el parametro 0 -> _ +lw $t1, 4($t0) #Lee la propiedad **value** del bool +li $t0, 1 #Carga un 1 para comparar +beq $t0, $t1, then_Cons_insert_0 # +#Else case +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 40($sp) #Guardando en la variable local new_Cons@0 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 40($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 40($sp) #Lee el valor de la var new_Cons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@0 +jal new_ctr_Cons # +sw $v0, 36($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Self Property xcar +lw $t0, 56($sp) #Instancia de la clase Cons +lw $t1, 4($t0) #Lee la propiedad xcar +sw $t1, 32($sp) #Guarda el valor de la propiedad xcar en la variable local param_0_to_init@0 +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Evalua la Expresion para el DinamicDispatch insert +#Get Self Property xcdr +lw $t0, 56($sp) #Instancia de la clase Cons +lw $t1, 8($t0) #Lee la propiedad xcdr +sw $t1, 28($sp) #Guarda el valor de la propiedad xcdr en la variable local instance_dynamic_to_insert@0 +#Fin de la exprecion previa al DinamicDispatch insert +#Evalua el parametro 0 para el CastingDispatch insert +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 24($sp) # +#Fin del paramentro 0 al CastingDispatch insert +lw $t0, 28($sp) #Lee el valor de la var instance_dynamic_to_insert@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_insert@0 +lw $t0, 28($sp) #Lee el valor de la var param_0_to_insert@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_insert@0 +lw $t0, 36($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de List +lw $t3, 64($t1) #Buscando el metodo dinamico para la funcion insert +jal $t3 # +sw $v0, 20($sp) #Asigna el resultado de la funcion +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 36($sp) #Lee el valor de la var instance_dynamic_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@0 +lw $t0, 36($sp) #Lee el valor de la var param_0_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@0 +lw $t0, 28($sp) #Lee el valor de la var param_1_to_init@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@0 +lw $t0, 48($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +j fin_Cons_insert_0 # +then_Cons_insert_0: +#Then case +#Evalua la Expresion para el DinamicDispatch init +#Creando instancia de tipo Cons +#Allocate a una class Cons +#atributo type_name en puntero + 0 +#atributo xcar en puntero + 4 +#atributo xcdr en puntero + 8 +li $a0, 12 # +li $v0, 9 # +syscall +sw $v0, 16($sp) #Guardando en la variable local new_Cons@1 puntero de la instancia de la clase Cons +#Assignacion de la insformacion de tipo a la instancia +la $t0, Cons # +move $s4, $t0 # +lw $t0, 16($sp) #Instancia de la clase +move $t1, $s4 #Guarda el valor que se le asignara a la propieded type_name +sw $t1, 0($t0) #Setea la propiedad type_name con el valor de _ +lw $t0, 16($sp) #Lee el valor de la var new_Cons@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con new_Cons@1 +jal new_ctr_Cons # +sw $v0, 12($sp) #Asigna el resultado de la funcion +#Fin de la exprecion previa al DinamicDispatch init +#Evalua el parametro 0 para el CastingDispatch init +#Get Local Var i +lw $t0, 52($sp) # +sw $t0, 8($sp) # +#Fin del paramentro 0 al CastingDispatch init +#Evalua el parametro 1 para el CastingDispatch init +#Get Local Var self +lw $t0, 56($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 1 al CastingDispatch init +lw $t0, 12($sp) #Lee el valor de la var instance_dynamic_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con instance_dynamic_to_init@1 +lw $t0, 12($sp) #Lee el valor de la var param_0_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_init@1 +lw $t0, 12($sp) #Lee el valor de la var param_1_to_init@1 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_1_to_init@1 +lw $t0, 24($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Cons +lw $t3, 76($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +fin_Cons_insert_0: +#Fin de un If +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 60 # +jr $ra # + +Nil_insert: # +#Parametro self en stackpoiner + 12 +#Parametro i@0 en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var param_0_to_rcons@0 stackpointer 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Nil_insert +#StaticDispatch rcons +#Evalua el parametro 0 para el CastingDispatch rcons +#Get Local Var i +lw $t0, 8($sp) # +sw $t0, 4($sp) # +#Fin del paramentro 0 al CastingDispatch rcons +lw $t0, 12($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +lw $t0, 8($sp) #Lee el valor de la var param_0_to_rcons@0 +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con param_0_to_rcons@0 +lw $t0, 20($sp) # +lw $t1, 0($t0) #Leyendo el tipo dinamico de la instancia que hereda de Nil +lw $t3, 68($t1) #Buscando el metodo dinamico para la funcion rcons +jal $t3 # +move $s4, $v0 #Asigna el resultado de la funcion +move $v0, $s4 #Return _ +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 # +jr $ra # + +Object_abort: # +#Parametro self en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion Object_abort +lw $s6, 4($sp) #Guarda self +la $a0, _______error______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "Abort called from class " +lw $t0, ($s6) #Read type property of self +lw $a0, ($t0) #Read type_name of self type +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Type class" +la $a0, _______endline_______ # +jal __str__new__ # +move $a0, $v0 # +jal __str__print__ #Print "endline" +li $v0, 10 # +syscall + +IO_out_int: # +#Parametro self en stackpoiner + 4 +#Parametro number en stackpoiner + 0 +addi $sp, $sp, -4 #Push local var $ra stackpointer -4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion IO_out_int +lw $s6, 8($sp) #Guarda self +lw $a0, 4($sp) #Guarda el parametro 0 -> number +jal __int__print__ # +lw $ra, 0($sp) # +addi $sp, $sp, 12 # +jr $ra # + +new_ctr_List: # +#Parametro self en stackpoiner + 4 +addi $sp, $sp, -4 #Push local var $ra stackpointer 0 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_List +lw $t0, 4($sp) #Lee el valor de la var self +addi $sp, $sp, -4 # +sw $t0, 0($sp) #Push a la pila con self +jal new_ctr_IO # +lw $v0, 4($sp) #Return self +lw $ra, 0($sp) #Lee $ra de la pila para retornar a la funcion anterior +addi $sp, $sp, 8 # +jr $ra # + +new_ctr_Bool: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_Int: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_String: #Esta funcion no se invoca en la ejecucion del programa + +new_ctr_SELF_TYPE: #Esta funcion no se invoca en la ejecucion del programa + +List_isNil: #Esta funcion no se invoca en la ejecucion del programa + +List_cons: #Esta funcion no se invoca en la ejecucion del programa + +List_car: #Esta funcion no se invoca en la ejecucion del programa + +Cons_isNil: #Esta funcion no se invoca en la ejecucion del programa + +Cons_car: #Esta funcion no se invoca en la ejecucion del programa + +Nil_isNil: #Esta funcion no se invoca en la ejecucion del programa + +IO_in_string: #Esta funcion no se invoca en la ejecucion del programa + +String_length: #Esta funcion no se invoca en la ejecucion del programa + +String_concat: #Esta funcion no se invoca en la ejecucion del programa + +String_substr: #Esta funcion no se invoca en la ejecucion del programa + +Object_copy: #Esta funcion no se invoca en la ejecucion del programa + +Object_type_name: #Esta funcion no se invoca en la ejecucion del programa + +###########################################################################region +######################################################################################################### +___fin___: +li $v0, 10 # system call #4 - print string +syscall # execute + +######################################################################################################### + +__int__new__: +# En $s6 self +# En $a0 el valor del entero +# Return $v0 la instancia del nuevo int + +move $t2, $a0 #Salva el valor del entero + +#Allocate a una class Int +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo Int + +la $t0, Int #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__int__print__: +# En $s6 **self** +# En $a0 la direccion del **Int** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 1 +move $a0, $t0 #Pinta el valor la propiedad **value** del int +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__int__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $v0, 5 #Lee un entero por la consola +syscall #Guarda el entero en $v0 + +move $s5, $ra #Salva $ra en $s5 para saltar a crear un Int con el valor leido +move $a0, $v0 +jal __int__new__ #En $v0 la instancia del nuevo entero + +move $ra, $s5 #Reasigna $ra para salir de **input** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sum__: +# En $s6 **self** +# En $a0 la direccion del **Int** a sumando A +# En $a1 la direccion del **Int** a sumando B +# Return $v0 new **Int** con **value** A+B + +lw $t0, 4($a0) #Lee la propiedad **value** del sumando A +lw $t1, 4($a1) #Lee la propiedad **value** del sumando B +add $a0, $t0, $t1 #$a0 = A + B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **sum** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__sub__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +sub $a0, $t0, $t1 #$a0 = A - B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A-B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__mul__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A*B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +mul $a0, $t0, $t1 #$a0 = A * B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A*B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **mul** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__div__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A/B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +div $a0, $t0, $t1 #$a0 = A/B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A/B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **div** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__le__: +# En $s6 **self** +# En $a0 la direccion del **Int** a operador A +# En $a1 la direccion del **Int** a operador B +# Return $v0 new **Int** con **value** A-B + +lw $t0, 4($a0) #Lee la propiedad **value** del operador A +lw $t1, 4($a1) #Lee la propiedad **value** del operador B +slt $a0, $t0, $t1 #$a0 = A < B + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A if A == 0 then $a0 = -1 else $a0 = 0 +mul $a0, $a0, -1 #$a0 = -$a0 => if $a0 == 0 then $a0 = 0 else 1 + +move $s5, $ra #Guardando $ra para saltar a crear en **Int** +jal __int__new__ #Con A+B en $a0 instancia el **Int** con el valor y devuelve en $v0 + +move $ra, $s5 #Reasigna $ra para salir de **rest** volver a la funcion anterior +# No modifica la pila +jr $ra #Esta funcion tiene saltos internos y en $v0 esta la instancia del nuevo **Int** + +########################################################################################################## +__int__clone__: +# En $s6 self + + + +#region +########################################################################################## +__bool__new__: +# En $s6 self +# En $a0 instancia de Int para convertir +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) # Guardando el valor la propiedad de **value** + +li $t1, 1 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 1 +li $t1, 0 +beq $t0, $t1, __bool__ok_value__ #Comparando el valor con 0 + +# Si el valor no es ni cero ni uno cierra el programa +li $v0, 4 # system call #4 - print string +la $a0, Bool_Name +syscall # execute +li $v0, 1 # system call #4 - print string +move $a0, $t0 +syscall # execute +li $v0, 10 # system call #4 - print string +syscall # execute + +__bool__ok_value__: +la $t0, Bool #Carga la direccion de memoria de la definicion de tipo Bool +sw $t0, ($a0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo + +move $v0, $a0 +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Bool + +########################################################################################################## +__bool__if_go_to__: +# En $s6 self +# En $a0 instancia de Bool a evaluar +# En $a1 direccion a la que saltar +# Return $v0 la instancia del nuevo Bool + +lw $t0, 4($a0) #Guarda el valor de la propiedad **value** del Bool +li $t1, 1 #Guarda 1 en $t0 para comparar con la propiedad **value** + +beq $t0, $t1, __go_to__ # if $t0 == $t1 then __go_to__ +jr $ra #esta funcion solo termina si el bool es false +__go_to__: +j $a1 # La condicion se cumple salta hacia el segundo parametro + +########################################################################################################## +__bool__check__type__: +# En $s6 **self** +# En $a0 direccion de memoria de la lista de ancestro de un typo +# En $a1 identificador numerico de un tipo + +li $v0, 1 # Por default devuelve 1 +__check__type__loop__: + lw $t0, ($a0) #Lee el id de un typo + beq $t0, $zero, __check__type__false__ + beq $t0, $a1, __check__type__end__ + addi $a0, $a0, 4 + j __check__type__loop__ + +__check__type__false__: + li $v0, 0 +__check__type__end__: + jr $ra + +#region +############################################################################################# +__str__new__: +# En $s6 self +# En $a0 el direccion de memoria que apunta a un string +# Return $v0 la instancia del nuevo string + +move $t2, $a0 #Salva la direccion de memoria + +#Allocate a una class String +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall #en $v0 la instancia del nuevo String + +la $t0, String #Carga la direccion de memoria de la definicion de tipo Int +sw $t0, ($v0) #Guarda en la pocision cero de la instancia la direccion de la definicion del tipo +sw $t2, 4($v0) #Guarda en la pocicion 4 de la instancia el valor del la propiedad **value** + +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta la instancia del nuevo Int + +########################################################################################################## +__str__print__: +# En $s6 **self** +# En $a0 la direccion del **String** a pintar +# Return $v0 **self** + +lw $t0, 4($a0) #Lee la propiedad **value** + +li $v0, 4 +move $a0, $t0 #Pinta el valor la propiedad **value** del String +syscall + +move $v0, $s6 #Guarda en $v0 **self** para retornar +# No modifica la pila +jr $ra # Esta funcion no tiene saltos internos y en $v0 esta self + +########################################################################################################## +__str__input__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **String** + +addi $sp, $sp, -4 +sw $ra ($sp) #Salva $ra en 12($sp) +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva self en 8($sp) + +li $a0, 1000 # reserva memoria para el string +li $v0, 9 +syscall # En $v0 direccion de memoria del nuevo string + +move $a0, $v0 # Asigan la direccion del nuevo string para llamar a la funcion de leer +li $v0, 8 # Leer un string de la consola +li $a1 , 1000 +syscall # En $a0 el string leido en la consola +jal __str__new__ #En $v0 la instancia del nuevo entero +move $a0, $v0 + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el nuevo string en 4($sp) + +move $s6, $v0 #cambia sefl por el nuevo string +jal __str__length__ + +lw $t0, 4($v0) #Lee la propiedad **value** del **Int** que devuelve length + +beq $t0,$zero, jline +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' + +jline: +sw $t0, 4($v0) #Actualiza la propieded **value** del **Int** length + +addi $sp, $sp, -4 +sw $v0, ($sp) #Salva el length en ($sp) + +li $a0, 0 +jal __int__new__ #Crea un nuevo entero con **value** 0 + +lw $s6, 4($sp) #Self = al string leido en la consola +move $a0, $v0 #index = 0 +lw $a1, ($sp) #count = length - 1 + +jal __str__substr__ #En $v0 el substring sin '\n' + +lw $s6, 8($sp) #Reasigna Self para salir de **input** volver a la funcion anterior +lw $ra, 12($sp) #Reasigna $ra para salir de **input** volver a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Devuelve en $v0 el subsstring leido por la consola + +########################################################################################################## +__str__length__: +# En $s6 **self** +# Return $v0 la instancia del nuevo **Int** + +li $t0 , 0 # len result +lw $t2 , 4($s6) # Leer la propiedad value a self + +loop_len: +lb $t3, ($t2) # Guarda la primara letra +beq $t3, $zero, end_len +add $t0, $t0, 1 # Suma al contador +add $t2, $t2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +move $a0, $t0 +move $s5, $ra +jal __int__new__ +move $ra, $s5 +jr $ra + +########################################################################################################### +__str__substr__: +# En $s6 **self** +# En $a0 **Int** el indece en el que inicia el sub +# En $a1 **Int** cantidad de caracteres que tiene el sub + +lw $t0, 4($s6) # Lee la propiedad value de **sefl** +lw $t1, 4($a0) # Lee la propiedad value del **Int** indice +lw $t2, 4($a1) # Lee la propiedad value del **Int** length + +li $t3, 0 # Contador para iterar el string en busqueda de indice +li $t4, 1 # Contador para iterar el string hasta llegar al length + +addi $t5, $t2, 1 +move $a0, $t5 # reserva memoria para el string +li $v0,9 +syscall # En $v0 la direccion de memoria del nuevo string +move $t5, $v0 + +beq $t2, $zero, end_sub_string + +find_index: + beq $t3, $t1, find_length # si el contador es el indice comiensa a crear el sub + add $t0, $t0, 1 # mueve el puntero del string de self + add $t3, $t3, 1 # mueve el contador + j find_index + +find_length: + lb $t6, ($t0) # Lee la primera letra del string self + sb $t6, ($t5) # guarda la primera letra del string self en el nuevo string + beq $t2, $t4, end_sub_string # si el contador del tamaño es igual a j end + add $t5, $t5, 1 # Mueve el puntero del nuevo string + add $t0, $t0, 1 # Mueve el puntero del string self + add $t4, $t4, 1 # Contador de tamaño += 1 + j find_length + +end_sub_string: + add $t5, $t5, 1 # Mueve el puntero del nuevo string + sb $zero, ($t5) # guarda la primera letra del string self en el nuevo string + + addi $sp, $sp, -4 + sw $ra, ($sp) # Guarda en la pila $ra + + move $a0, $v0 # Pasa como parametros la direccion de memoria del string + jal __str__new__ # En $v0 la instancia del nuevos string + + lw $ra, ($sp) # Reasigna $ra para volver al la funcion anterior + addi $sp, $sp, 4 # Limpia la pila + jr $ra # Return instancia del substring en $v0 + +############################################################################################################ +__str__concat__: +# En $s6 **self** +# En #a0 instancia de otro string + +addi $sp, $sp, -4 +sw $s6, ($sp) #Salva **self** +addi $sp, $sp, -4 +sw $a0, ($sp) #Salva el string que se paso como parametro +addi $sp, $sp, -4 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ +addi $sp, $sp, -4 +lw $t0, 4($v0) #Lee el valor de la propiedad **value** +sw $t0, ($sp) #Salva el valor del primer length + +lw $t0, 8($sp) +move $s6, $t0 #Cambia self por el otro string +jal __str__length__ +lw $t0, ($sp) #Lee el lenght del string self +lw $t1, 4($v0) #Lee el valor de la pripiedad value del resultado de la funcion length +add $t0, $t0, $t1 # Suma los length de ambos string + +add $t0, $t0, 1 +move $a0, $t0 +li $v0, 9 +syscall # Reserva espacion para un string de tamaño length1 + length2 +#En $v0 el nuevo string + +move $t3, $v0 +lw $t2, 8($sp) #Lee el string que se paso por parametro +lw $t1, 4($t2) #Lee la propiedad **value** del string +lw $t2, 12($sp) #Lee self +lw $t0, 4($t2) #Lee la propiedad **value** de self + +loop_str1: + lb $t2, ($t0) # primera letra del puntero al string self + beq $t2, $zero, loop_str2 + add $t0, $t0, 1 # mueve el puntero del string self + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +loop_str2: + lb $t2, ($t1) # primera letra del puntero al string str1 + beq $t2, $zero, end_concat + add $t1, $t1, 1 # mueve el puntero del string str1 + sb $t2, ($t3) # guarda la letra en el nuevo string + add $t3, $t3, 1 # mueve el puntero del nuevo string + j loop_str1 + +end_concat: + move $a0, $v0 + jal __str__new__ + lw $ra, 4($sp) + lw $s6, 12($sp) + addi $sp, $sp, 16 #Limpia la pila + jr $ra # Return en $v0 la nueva instancia de self + +############################################################################################################ +__str__cmp__: +# En $s6 **self** +# En $a0 instancia de str1 +# En $a1 instancia de str2 + +addi $sp, $sp -4 +sw $ra, ($sp) + +lw $t0, 4($a0) #Lee la propiedad **value** de str1 +lw $t1, 4($a1) #Lee la propiedad **value** de str2 +li $a0, 1 # True por default + +str_cmp_loop: + lb $t2, ($t0) #Lee una letra de str1 + lb $t3, ($t1) #Lee una letra de str2 + addi $t0, $t0, 1 + addi $t1, $t1, 1 + beq $t2, $zero, cmp_end_to_zero #Se llego al fin del str1 + beq $t3, $zero, cmp_end_to_zero #Se llego al fin del str2 + beq $t2, $t3, str_cmp_loop #Continua comparando si son iguales + j str_cmp_false + +cmp_end_to_zero: + beq $t2, $t3, end_str_cmp #Chequea que ambos hallan llegado al final + j str_cmp_false + +str_cmp_false: + li $a0, 0 #Cambia el defaul True por False +end_str_cmp: + jal __int__new__ #Crea un Int que luego se debe cambiar por bool + lw $ra, ($sp) #Lee $ra para retornar + addi $sp, $sp, 4 #Limpia la pila + jr $ra #En $v0 un Int que hay que cambiar por Bool + diff --git a/tests/codegen/sort-list_input.txt b/tests/codegen/sort-list_input.txt old mode 100644 new mode 100755 diff --git a/tests/codegen/sort-list_output.txt b/tests/codegen/sort-list_output.txt old mode 100644 new mode 100755 diff --git a/tests/codegen_test.py b/tests/codegen_test.py old mode 100644 new mode 100755 diff --git a/tests/conftest.py b/tests/conftest.py old mode 100644 new mode 100755 diff --git a/tests/lexer/comment1.cl b/tests/lexer/comment1.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/comment1_error.txt b/tests/lexer/comment1_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis1.cl b/tests/lexer/iis1.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis1_error.txt b/tests/lexer/iis1_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis2.cl b/tests/lexer/iis2.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis2_error.txt b/tests/lexer/iis2_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis3.cl b/tests/lexer/iis3.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis3_error.txt b/tests/lexer/iis3_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis4.cl b/tests/lexer/iis4.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis4_error.txt b/tests/lexer/iis4_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis5.cl b/tests/lexer/iis5.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis5_error.txt b/tests/lexer/iis5_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/iis6.cl b/tests/lexer/iis6.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/iis6_error.txt b/tests/lexer/iis6_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/mixed1.cl b/tests/lexer/mixed1.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/mixed1_error.txt b/tests/lexer/mixed1_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/mixed2.cl b/tests/lexer/mixed2.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/mixed2_error.txt b/tests/lexer/mixed2_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/string1.cl b/tests/lexer/string1.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/string1_error.txt b/tests/lexer/string1_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/string2.cl b/tests/lexer/string2.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/string2_error.txt b/tests/lexer/string2_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/string3.cl b/tests/lexer/string3.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/string3_error.txt b/tests/lexer/string3_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer/string4.cl b/tests/lexer/string4.cl old mode 100644 new mode 100755 diff --git a/tests/lexer/string4_error.txt b/tests/lexer/string4_error.txt old mode 100644 new mode 100755 diff --git a/tests/lexer_test.py b/tests/lexer_test.py old mode 100644 new mode 100755 diff --git a/tests/parser/assignment1.cl b/tests/parser/assignment1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/assignment1_error.txt b/tests/parser/assignment1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/assignment2.cl b/tests/parser/assignment2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/assignment2_error.txt b/tests/parser/assignment2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/assignment3.cl b/tests/parser/assignment3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/assignment3_error.txt b/tests/parser/assignment3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/attribute1.cl b/tests/parser/attribute1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/attribute1_error.txt b/tests/parser/attribute1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/attribute2.cl b/tests/parser/attribute2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/attribute2_error.txt b/tests/parser/attribute2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/attribute3.cl b/tests/parser/attribute3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/attribute3_error.txt b/tests/parser/attribute3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/block1.cl b/tests/parser/block1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/block1_error.txt b/tests/parser/block1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/block2.cl b/tests/parser/block2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/block2_error.txt b/tests/parser/block2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/block3.cl b/tests/parser/block3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/block3_error.txt b/tests/parser/block3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/block4.cl b/tests/parser/block4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/block4_error.txt b/tests/parser/block4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case1.cl b/tests/parser/case1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case1_error.txt b/tests/parser/case1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case2.cl b/tests/parser/case2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case2_error.txt b/tests/parser/case2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case3.cl b/tests/parser/case3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case3_error.txt b/tests/parser/case3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case4.cl b/tests/parser/case4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case4_error.txt b/tests/parser/case4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case5.cl b/tests/parser/case5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case5_error.txt b/tests/parser/case5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/case6.cl b/tests/parser/case6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/case6_error.txt b/tests/parser/case6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class1.cl b/tests/parser/class1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class1_error.txt b/tests/parser/class1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class2.cl b/tests/parser/class2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class2_error.txt b/tests/parser/class2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class3.cl b/tests/parser/class3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class3_error.txt b/tests/parser/class3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class4.cl b/tests/parser/class4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class4_error.txt b/tests/parser/class4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class5.cl b/tests/parser/class5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class5_error.txt b/tests/parser/class5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/class6.cl b/tests/parser/class6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/class6_error.txt b/tests/parser/class6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional1.cl b/tests/parser/conditional1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional1_error.txt b/tests/parser/conditional1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional2.cl b/tests/parser/conditional2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional2_error.txt b/tests/parser/conditional2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional3.cl b/tests/parser/conditional3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional3_error.txt b/tests/parser/conditional3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional4.cl b/tests/parser/conditional4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional4_error.txt b/tests/parser/conditional4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional5.cl b/tests/parser/conditional5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional5_error.txt b/tests/parser/conditional5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/conditional6.cl b/tests/parser/conditional6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/conditional6_error.txt b/tests/parser/conditional6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch1.cl b/tests/parser/dispatch1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch1_error.txt b/tests/parser/dispatch1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch2.cl b/tests/parser/dispatch2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch2_error.txt b/tests/parser/dispatch2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch3.cl b/tests/parser/dispatch3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch3_error.txt b/tests/parser/dispatch3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch4.cl b/tests/parser/dispatch4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch4_error.txt b/tests/parser/dispatch4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch5.cl b/tests/parser/dispatch5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch5_error.txt b/tests/parser/dispatch5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch6.cl b/tests/parser/dispatch6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch6_error.txt b/tests/parser/dispatch6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch7.cl b/tests/parser/dispatch7.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch7_error.txt b/tests/parser/dispatch7_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch8.cl b/tests/parser/dispatch8.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch8_error.txt b/tests/parser/dispatch8_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch9.cl b/tests/parser/dispatch9.cl old mode 100644 new mode 100755 diff --git a/tests/parser/dispatch9_error.txt b/tests/parser/dispatch9_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let1.cl b/tests/parser/let1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let1_error.txt b/tests/parser/let1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let2.cl b/tests/parser/let2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let2_error.txt b/tests/parser/let2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let3.cl b/tests/parser/let3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let3_error.txt b/tests/parser/let3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let4.cl b/tests/parser/let4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let4_error.txt b/tests/parser/let4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let5.cl b/tests/parser/let5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let5_error.txt b/tests/parser/let5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let6.cl b/tests/parser/let6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let6_error.txt b/tests/parser/let6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/let7.cl b/tests/parser/let7.cl old mode 100644 new mode 100755 diff --git a/tests/parser/let7_error.txt b/tests/parser/let7_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/loop1.cl b/tests/parser/loop1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/loop1_error.txt b/tests/parser/loop1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/loop2.cl b/tests/parser/loop2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/loop2_error.txt b/tests/parser/loop2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/loop3.cl b/tests/parser/loop3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/loop3_error.txt b/tests/parser/loop3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/loop4.cl b/tests/parser/loop4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/loop4_error.txt b/tests/parser/loop4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method1.cl b/tests/parser/method1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method1_error.txt b/tests/parser/method1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method2.cl b/tests/parser/method2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method2_error.txt b/tests/parser/method2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method3.cl b/tests/parser/method3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method3_error.txt b/tests/parser/method3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method4.cl b/tests/parser/method4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method4_error.txt b/tests/parser/method4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method5.cl b/tests/parser/method5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method5_error.txt b/tests/parser/method5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/method6.cl b/tests/parser/method6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/method6_error.txt b/tests/parser/method6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed1.cl b/tests/parser/mixed1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed1_error.txt b/tests/parser/mixed1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed2.cl b/tests/parser/mixed2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed2_error.txt b/tests/parser/mixed2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed3.cl b/tests/parser/mixed3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed3_error.txt b/tests/parser/mixed3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed4.cl b/tests/parser/mixed4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed4_error.txt b/tests/parser/mixed4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed5.cl b/tests/parser/mixed5.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed5_error.txt b/tests/parser/mixed5_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/mixed6.cl b/tests/parser/mixed6.cl old mode 100644 new mode 100755 diff --git a/tests/parser/mixed6_error.txt b/tests/parser/mixed6_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/operation1.cl b/tests/parser/operation1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/operation1_error.txt b/tests/parser/operation1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/operation2.cl b/tests/parser/operation2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/operation2_error.txt b/tests/parser/operation2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/operation3.cl b/tests/parser/operation3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/operation3_error.txt b/tests/parser/operation3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/operation4.cl b/tests/parser/operation4.cl old mode 100644 new mode 100755 diff --git a/tests/parser/operation4_error.txt b/tests/parser/operation4_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/program1.cl b/tests/parser/program1.cl old mode 100644 new mode 100755 diff --git a/tests/parser/program1_error.txt b/tests/parser/program1_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/program2.cl b/tests/parser/program2.cl old mode 100644 new mode 100755 diff --git a/tests/parser/program2_error.txt b/tests/parser/program2_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser/program3.cl b/tests/parser/program3.cl old mode 100644 new mode 100755 diff --git a/tests/parser/program3_error.txt b/tests/parser/program3_error.txt old mode 100644 new mode 100755 diff --git a/tests/parser_test.py b/tests/parser_test.py old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic1.cl b/tests/semantic/arithmetic1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic10.cl b/tests/semantic/arithmetic10.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic10_error.txt b/tests/semantic/arithmetic10_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic11.cl b/tests/semantic/arithmetic11.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic11_error.txt b/tests/semantic/arithmetic11_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic12.cl b/tests/semantic/arithmetic12.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic12_error.txt b/tests/semantic/arithmetic12_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic1_error.txt b/tests/semantic/arithmetic1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic2.cl b/tests/semantic/arithmetic2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic2_error.txt b/tests/semantic/arithmetic2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic3.cl b/tests/semantic/arithmetic3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic3_error.txt b/tests/semantic/arithmetic3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic4.cl b/tests/semantic/arithmetic4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic4_error.txt b/tests/semantic/arithmetic4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic5.cl b/tests/semantic/arithmetic5.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic5_error.txt b/tests/semantic/arithmetic5_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic6.cl b/tests/semantic/arithmetic6.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic6_error.txt b/tests/semantic/arithmetic6_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic7.cl b/tests/semantic/arithmetic7.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic7_error.txt b/tests/semantic/arithmetic7_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic8.cl b/tests/semantic/arithmetic8.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic8_error.txt b/tests/semantic/arithmetic8_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic9.cl b/tests/semantic/arithmetic9.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/arithmetic9_error.txt b/tests/semantic/arithmetic9_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment1.cl b/tests/semantic/assignment1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment1_error.txt b/tests/semantic/assignment1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment2.cl b/tests/semantic/assignment2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment2_error.txt b/tests/semantic/assignment2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment3.cl b/tests/semantic/assignment3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/assignment3_error.txt b/tests/semantic/assignment3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes1.cl b/tests/semantic/attributes1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes1_error.txt b/tests/semantic/attributes1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes2.cl b/tests/semantic/attributes2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes2_error.txt b/tests/semantic/attributes2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes3.cl b/tests/semantic/attributes3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes3_error.txt b/tests/semantic/attributes3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes4.cl b/tests/semantic/attributes4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/attributes4_error.txt b/tests/semantic/attributes4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics1.cl b/tests/semantic/basics1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics1_error.txt b/tests/semantic/basics1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics2.cl b/tests/semantic/basics2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics2_error.txt b/tests/semantic/basics2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics3.cl b/tests/semantic/basics3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics3_error.txt b/tests/semantic/basics3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics4.cl b/tests/semantic/basics4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics4_error.txt b/tests/semantic/basics4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics5.cl b/tests/semantic/basics5.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics5_error.txt b/tests/semantic/basics5_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics6.cl b/tests/semantic/basics6.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics6_error.txt b/tests/semantic/basics6_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics7.cl b/tests/semantic/basics7.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics7_error.txt b/tests/semantic/basics7_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/basics8.cl b/tests/semantic/basics8.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/basics8_error.txt b/tests/semantic/basics8_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/blocks1.cl b/tests/semantic/blocks1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/blocks1_error.txt b/tests/semantic/blocks1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/case1.cl b/tests/semantic/case1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/case1_error.txt b/tests/semantic/case1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/case2.cl b/tests/semantic/case2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/case2_error.txt b/tests/semantic/case2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/case3.cl b/tests/semantic/case3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/case3_error.txt b/tests/semantic/case3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/class1.cl b/tests/semantic/class1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/class1_error.txt b/tests/semantic/class1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/conditionals1.cl b/tests/semantic/conditionals1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/conditionals1_error.txt b/tests/semantic/conditionals1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/conditionals2.cl b/tests/semantic/conditionals2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/conditionals2_error.txt b/tests/semantic/conditionals2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch1.cl b/tests/semantic/dispatch1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch1_error.txt b/tests/semantic/dispatch1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch2.cl b/tests/semantic/dispatch2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch2_error.txt b/tests/semantic/dispatch2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch3.cl b/tests/semantic/dispatch3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch3_error.txt b/tests/semantic/dispatch3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch4.cl b/tests/semantic/dispatch4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch4_error.txt b/tests/semantic/dispatch4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch5.cl b/tests/semantic/dispatch5.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch5_error.txt b/tests/semantic/dispatch5_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch6.cl b/tests/semantic/dispatch6.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/dispatch6_error.txt b/tests/semantic/dispatch6_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/eq1.cl b/tests/semantic/eq1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/eq1_error.txt b/tests/semantic/eq1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/eq2.cl b/tests/semantic/eq2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/eq2_error.txt b/tests/semantic/eq2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/eq3.cl b/tests/semantic/eq3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/eq3_error.txt b/tests/semantic/eq3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/eq4.cl b/tests/semantic/eq4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/eq4_error.txt b/tests/semantic/eq4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/inheritance3_error.txt b/tests/semantic/inheritance3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/inheritance4_error.txt b/tests/semantic/inheritance4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/inheritance5_error.txt b/tests/semantic/inheritance5_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/isvoid1.cl b/tests/semantic/isvoid1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/isvoid1_error.txt b/tests/semantic/isvoid1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/let1.cl b/tests/semantic/let1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/let1_error.txt b/tests/semantic/let1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/let2.cl b/tests/semantic/let2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/let2_error.txt b/tests/semantic/let2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/let3.cl b/tests/semantic/let3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/let3_error.txt b/tests/semantic/let3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/loops1.cl b/tests/semantic/loops1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/loops1_error.txt b/tests/semantic/loops1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/loops2.cl b/tests/semantic/loops2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/loops2_error.txt b/tests/semantic/loops2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods1.cl b/tests/semantic/methods1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods1_error.txt b/tests/semantic/methods1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods2.cl b/tests/semantic/methods2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods2_error.txt b/tests/semantic/methods2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods3.cl b/tests/semantic/methods3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods3_error.txt b/tests/semantic/methods3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods4.cl b/tests/semantic/methods4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods4_error.txt b/tests/semantic/methods4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods5.cl b/tests/semantic/methods5.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods5_error.txt b/tests/semantic/methods5_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods6.cl b/tests/semantic/methods6.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods6_error.txt b/tests/semantic/methods6_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods7.cl b/tests/semantic/methods7.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods7_error.txt b/tests/semantic/methods7_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/methods8.cl b/tests/semantic/methods8.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/methods8_error.txt b/tests/semantic/methods8_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/new1.cl b/tests/semantic/new1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/new1_error.txt b/tests/semantic/new1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/self1.cl b/tests/semantic/self1.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/self1_error.txt b/tests/semantic/self1_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/self2.cl b/tests/semantic/self2.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/self2_error.txt b/tests/semantic/self2_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/self3.cl b/tests/semantic/self3.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/self3_error.txt b/tests/semantic/self3_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic/self4.cl b/tests/semantic/self4.cl old mode 100644 new mode 100755 diff --git a/tests/semantic/self4_error.txt b/tests/semantic/self4_error.txt old mode 100644 new mode 100755 diff --git a/tests/semantic_test.py b/tests/semantic_test.py old mode 100644 new mode 100755 diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py old mode 100644 new mode 100755 diff --git a/tests/utils/utils.py b/tests/utils/utils.py old mode 100644 new mode 100755