Skip to content
This repository has been archived by the owner on Feb 14, 2021. It is now read-only.

Primera Entrega #57

Open
wants to merge 166 commits into
base: entrega-parser
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
166 commits
Select commit Hold shift + click to select a range
0e51c23
Existing src files added
adriangs1996 Feb 13, 2020
015c95a
"Starting comments development"
adriangs1996 Feb 13, 2020
3ef77a6
"added some project management and building files. Done some tunnigs …
adriangs1996 Feb 13, 2020
44434d8
Added function to process coments
adriangs1996 Feb 17, 2020
606586c
"Passes first 4 Lexer tests"
adriangs1996 Feb 17, 2020
e8ea7bf
"Tunning makefile"
adriangs1996 Feb 17, 2020
9074018
* src/makefile: Lexer passed tests. So LEXER DONE?
adriangs1996 Feb 21, 2020
5f265f8
Added install function to makefile.
adriangs1996 Feb 21, 2020
7eedfc2
Fixed requirements
adriangs1996 Feb 21, 2020
3918cbe
Another requirement
adriangs1996 Feb 21, 2020
f045179
fixing makefile
adriangs1996 Feb 21, 2020
312fd0b
Fixing grammar, first parser test ok.
adriangs1996 Feb 22, 2020
1071bc3
fixed tilde strings
adriangs1996 Feb 22, 2020
48513ee
Some parser test ok, Keep fixing.
adriangs1996 Feb 22, 2020
a1cf1b0
Almost there
adriangs1996 Feb 22, 2020
ac216ae
Just two more to go.
adriangs1996 Feb 22, 2020
a5c258a
Passed every parser test.
adriangs1996 Feb 22, 2020
ab9bddf
Merge branch 'parser-dev' into entrega-parser
adriangs1996 Feb 22, 2020
5aa1548
Merge branch 'entrega-parser' into entrega-parser
adriangs1996 Feb 24, 2020
bced313
Added names to doc/Readme.md. Added semantic check to pipeline.
adriangs1996 Mar 1, 2020
a78ef64
Merge branch 'entrega-parser' of https://github.com/IOverflow/cool-co…
adriangs1996 Mar 1, 2020
63244e4
[CHANGE] Used re to implement tokenizer instead of Lexer Class.
adriangs1996 Apr 13, 2020
7a30adf
Formatting and CIL AST template.
adriangs1996 May 9, 2020
8d3e318
Started cool to CIL travel.
adriangs1996 May 10, 2020
522a423
Annotated and formated all travels built so far.
adriangs1996 May 11, 2020
e1be7c3
Added .builds file to gitignore.
adriangs1996 May 11, 2020
26f8f81
Added src/.builds to gitignore.
adriangs1996 May 11, 2020
ddd1c07
IfThenElseNode to CIL.
adriangs1996 May 12, 2020
4a73815
Annotated typecheck.py.
adriangs1996 May 12, 2020
16530c6
Correctly annotated comments.py.
adriangs1996 May 12, 2020
8bce467
[TODO] Added TODO: REIMPLEMENT visitor over VariableDeclaration on in…
adriangs1996 May 12, 2020
82ec77c
Added visitor over VariableCallNode on ctcill.py
adriangs1996 May 13, 2020
b55a831
Implemented visitor over BlockNode on ctcill.py
adriangs1996 May 13, 2020
fbe9cc3
Implemented visitor over AssignNode in ccil.py
adriangs1996 May 13, 2020
c103070
Implemented visitor over WhileBlockNode on ctcill.py
adriangs1996 May 13, 2020
5038fbb
Added LCA tables to baseCilVisitor.py to support runtime-type-checking.
adriangs1996 May 15, 2020
9abd7c8
LCA table build seems to work.
adriangs1996 May 15, 2020
4aebce5
Added some comments in baseCilVisitory.py
adriangs1996 May 18, 2020
01272be
Done some reformats.
adriangs1996 May 19, 2020
3e7773e
Changed LCA table for TDT for runtime-type-checking.
adriangs1996 May 19, 2020
581154f
Added some comments to baseCilVisitor.py
adriangs1996 May 19, 2020
bad9519
First attempt to implement a Case Node in CIL.
adriangs1996 May 20, 2020
11aa0a6
Implemented DifNode and PlusNode in CIL.
adriangs1996 May 20, 2020
c83a519
Implemented MulNode and DivNode in CIL.
adriangs1996 May 20, 2020
a7f2e6b
Implemented constants (strings, integers, true and false).
adriangs1996 May 21, 2020
eb787bd
Implemented "==" in CIL.
adriangs1996 May 25, 2020
14cbb73
Implemented "<" and "<=" in CIL.
adriangs1996 May 25, 2020
d347d3e
Implemented ">" and ">=" in CIL.
adriangs1996 May 25, 2020
2455fe3
[TODO] NEED TO CHECK THE TYPE_INFERER. Fixed a lot of bugs with gramm…
adriangs1996 May 27, 2020
06e5848
A first attempt of pipeline from COOL to CIL.
adriangs1996 May 29, 2020
58070ae
MIPS INSTRUCTIONS wrappers.
adriangs1996 May 29, 2020
6676bc6
Implemented Branch and Jump MIPS Instructions
adriangs1996 May 31, 2020
6584159
More MIPS Instructions
adriangs1996 Jun 3, 2020
0d6eb67
Added more mips instructions and started CIL to MIPS visitor
adriangs1996 Jun 8, 2020
4effc9c
Checkpoint
adriangs1996 Jun 22, 2020
1ec28e1
Implemented VTABLES & TYPE RECORDS
adriangs1996 Jun 24, 2020
4a4463b
Checkpoint on MIPS Types
adriangs1996 Jun 24, 2020
cfdb3de
Implemented DataNodes
adriangs1996 Jun 24, 2020
74def88
Implemented FunctionNode
adriangs1996 Jun 25, 2020
cebaf81
Implemented labels and added current function to MIPS visitor
adriangs1996 Jun 25, 2020
dae119c
Fixed return values for visitor in ctcill.py
adriangs1996 Jun 25, 2020
d88effe
Implemented ParamNode
adriangs1996 Jun 25, 2020
8b9973e
Added support function get_location_address
adriangs1996 Jun 25, 2020
e52a160
Implemented Arithmetic Operations
adriangs1996 Jun 25, 2020
f0e817b
Added prototypes for remaining nodes.
adriangs1996 Jun 25, 2020
8fc7a97
change visitors to use singledispatchmethod instead
adriangs1996 Jul 25, 2020
34acb8c
completed visitor implementation with singledispatchmethod
adriangs1996 Jul 28, 2020
9bf7396
Added type annotations to cool AST
adriangs1996 Aug 2, 2020
14e9339
Fixed Pylance errors over inference.py
adriangs1996 Aug 2, 2020
1a86fbd
More type annotations
adriangs1996 Aug 30, 2020
da94009
Refactoring arithmetic nodes
adriangs1996 Aug 31, 2020
5653e63
Primera aproximacion a la instanciacion de clases
adriangs1996 Aug 31, 2020
2a5fa29
Implemented TypeOFNode
adriangs1996 Aug 31, 2020
780d032
Implemented branching nodes
adriangs1996 Aug 31, 2020
0961f9d
Implemented stack frames and StaticCallNode
adriangs1996 Sep 1, 2020
45f9b97
Implemented DinamicCall and VTABLE
adriangs1996 Sep 2, 2020
cacca3b
Implemented LoadNode
adriangs1996 Sep 2, 2020
7f87411
Implement ArgNode
adriangs1996 Sep 3, 2020
8fb8496
Complete compiler pipeline
adriangs1996 Sep 3, 2020
0c6c006
Remove printing in Inferer Visitor
adriangs1996 Sep 3, 2020
d79b122
Tunning cil and mips display formatter
adriangs1996 Sep 3, 2020
6ea0554
Fix allignment in Type's memory allocation
adriangs1996 Sep 3, 2020
15f0454
Remove unused imports in baseMipsVisitor.py
adriangs1996 Sep 4, 2020
4053ffd
Fix args deallocation
adriangs1996 Sep 4, 2020
b83c4dc
Fix entry point
adriangs1996 Sep 7, 2020
97a4eb0
Builtin types and methods
adriangs1996 Sep 10, 2020
3805e3b
Fix ilegal attribute redefinition
adriangs1996 Oct 2, 2020
ada8f96
Fix duplicated attribute redefinition check
adriangs1996 Oct 2, 2020
7cd4ff6
Fix type inference and type check in attributes init expressions
adriangs1996 Oct 2, 2020
cd94d57
Inference for IsVoidNode
adriangs1996 Oct 2, 2020
1d65f79
Add attribute visitor in ctcill.py
adriangs1996 Oct 2, 2020
e182e06
Implement attribute initialization
adriangs1996 Oct 2, 2020
e2c0dc3
Implement MIPS code for attribute initialization
adriangs1996 Oct 2, 2020
043eb84
Formatt MIPS output
adriangs1996 Oct 2, 2020
ad49f4b
Remove comment from formatter
adriangs1996 Oct 2, 2020
c11308b
Fix CIL AssignNode implementation
adriangs1996 Oct 3, 2020
53cf339
Fix formatting in TypeOf Node
adriangs1996 Oct 3, 2020
7d74001
Implement SetAttribute and GetAttribute
adriangs1996 Oct 3, 2020
f0a82f2
Remove unused imports in ciltomips.py
adriangs1996 Oct 3, 2020
eb90bf1
Add testing.py to gitignore
adriangs1996 Oct 3, 2020
7567b73
Add .text directive to entry point
adriangs1996 Oct 3, 2020
d4a930f
Fix allocation of builtin types
adriangs1996 Oct 29, 2020
070f6d6
Fix attributes inheritance
adriangs1996 Oct 29, 2020
c83d7e1
Add comment when deallocating args
adriangs1996 Oct 29, 2020
ede3815
Update self pointer in dinamic func calls
adriangs1996 Oct 30, 2020
a24257d
Fix attributes initialization calling wrong methods
adriangs1996 Oct 30, 2020
e7f0427
Fix missing NegNode and fix bug with grammar
adriangs1996 Oct 31, 2020
faacd80
implement read-write builtin funcs, fix typecollector and bootstrap
adriangs1996 Nov 10, 2020
82aba0a
Update Readme.md
apiad Nov 24, 2020
2a2af03
Change formatter to black
adriangs1996 Nov 25, 2020
65d81fb
Merge branch 'entrega-final' of https://github.com/matcom/cool-compil…
adriangs1996 Nov 26, 2020
76a3dd1
Implement line and columns for class features. Change Grammar to allo…
adriangs1996 Nov 26, 2020
308e932
Change errors to SemanticErrors in Inferer
adriangs1996 Nov 26, 2020
4c68e8a
Added line and column to blockNode
adriangs1996 Nov 26, 2020
29d88eb
Fix Redefined method check
adriangs1996 Nov 27, 2020
75abba1
Pass methods
adriangs1996 Nov 27, 2020
3314cc3
Fix arithmetic error messages
adriangs1996 Nov 27, 2020
1932b24
Fix Arithmetic and basic error message. Fix bugs in grammar with post…
adriangs1996 Nov 28, 2020
46d08ab
Fix precedence with ~operator
adriangs1996 Nov 28, 2020
56083e4
Fix StringConstant line and column
adriangs1996 Nov 28, 2020
ef927ed
Fix assignment report error message
adriangs1996 Nov 28, 2020
b04ea25
Fix attributes error message
adriangs1996 Nov 28, 2020
555bdb5
fix case error messages
adriangs1996 Nov 28, 2020
8c47c7b
fix conditionals error messages
adriangs1996 Nov 28, 2020
5d3883f
Fix error messages for dispatchs
adriangs1996 Nov 28, 2020
71699d1
Fix features
adriangs1996 Nov 28, 2020
babbb3f
Fix inheritance error messages
adriangs1996 Nov 28, 2020
ea3e391
Fix isvoid expression
adriangs1996 Nov 28, 2020
ab54eba
Fix lets
adriangs1996 Nov 28, 2020
e702afe
fix new
adriangs1996 Nov 28, 2020
2f5c627
Fix address loading in out_string. Fix method lookup in type hierarch…
adriangs1996 Nov 30, 2020
ee8ddd5
Patch SyntaxError instead of SemanticError
adriangs1996 Dec 1, 2020
b4571d6
Change makefile
adriangs1996 Dec 1, 2020
a93a151
Change makefile again
adriangs1996 Dec 1, 2020
9d07546
add report
adriangs1996 Dec 1, 2020
2a40be0
Fix self handling. Fix dispatching and inheritance
adriangs1996 Dec 2, 2020
c7f79e0
Fix not node
adriangs1996 Dec 3, 2020
c39d44d
Fix let regex containing "space"
adriangs1996 Dec 3, 2020
9d3e8ae
FIx infix operator "~"
adriangs1996 Dec 3, 2020
7496072
Make strings type records
adriangs1996 Dec 3, 2020
95e75d7
Fix Strings attributes allocation
adriangs1996 Dec 3, 2020
8b60d29
Fix substr function
adriangs1996 Dec 4, 2020
ab28f7e
Reimplement concat
adriangs1996 Dec 4, 2020
476b5d5
Fix methods indexing invariant in dynamic dispatch
adriangs1996 Dec 4, 2020
c0cbc28
Fix substr implementation to take starting index and length instead o…
adriangs1996 Dec 4, 2020
2d33623
Fix isvoid not returning Bool instance and return for out_string and …
adriangs1996 Dec 4, 2020
91fabc3
Fix scoping
adriangs1996 Dec 5, 2020
cc56f31
Add offset to type records
adriangs1996 Dec 5, 2020
cc008ed
Fix TDT lookups to just move to an offset
adriangs1996 Dec 5, 2020
5fe3b7e
Fix case expr. Change find min algorithm
adriangs1996 Dec 5, 2020
18c2552
Fix if-then-else expr not returning a value
adriangs1996 Dec 6, 2020
810044c
Fix attributes having access to previous defined attributes
adriangs1996 Dec 6, 2020
2ae2f72
Add abortion message
adriangs1996 Dec 6, 2020
03b8ba6
Fixing scoping
adriangs1996 Dec 6, 2020
68185c3
Fix Allocate not initializing inherited attributes
adriangs1996 Dec 6, 2020
8c0934c
Fix var name lookup in function localvars in MIPS
adriangs1996 Dec 7, 2020
4d9ef0a
make string instantiable
adriangs1996 Dec 7, 2020
3ac521a
Reimplement equality and comparison ops. Change "int" and "bool" type…
adriangs1996 Dec 7, 2020
13661f4
Just need to fix a bug in VTABLE
adriangs1996 Dec 8, 2020
64d25fe
Fix vtables bugs
adriangs1996 Dec 8, 2020
682f2b4
clean
adriangs1996 Dec 8, 2020
96ad348
compiled
adriangs1996 Dec 8, 2020
cec7872
change makefile
adriangs1996 Dec 8, 2020
2cd442d
Fix EOF handling. Case graph was wrongly passed, now it is OK
adriangs1996 Dec 8, 2020
222e78f
remove unused imports
adriangs1996 Dec 8, 2020
65ee19a
Improve type inference explanation in Report
adriangs1996 Dec 14, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,9 @@ dmypy.json

# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)

### Sublime Text Projects ###
*.sublime-project

src/.builds

src/testing.py
12 changes: 12 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"python.pythonPath": "/bin/python",
"cmake.configureOnOpen": false,
"python.linting.enabled": false,
"python.linting.mypyEnabled": true,
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true,
}
17 changes: 17 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "test",
"type": "shell",
"command": "cd src && make test",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
4 changes: 2 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ En este proyecto se realizarán entregas parciales a lo largo del curso. Para re
### 2. Asegúrese de tener la siguiente configuración antes de hacer click en **Create pull request**.

- **base repository**: `matcom/cool-compiler-2020` (repositorio original)
- **branch**: `entrega-parser`
- **branch**: `entrega-final`
- **head repository**: `<usuario>/cool-compiler-2020` (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 `entrega-parser`.
> **NOTA**: Asegúrese que el _pull request_ se hace a la rama `entrega-final`.

![](img/img6.png)

Expand Down
9 changes: 6 additions & 3 deletions doc/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

**Nombre** | **Grupo** | **Github**
--|--|--
Nombre1 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/<user>)
Nombre2 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/<user>)
Nombre3 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/<user>)

Adrian Gonzalez Sanchez | C412 | [@adriangs1996](https://github.com/adriangs1996)

Eliane Puerta Cabrera | C412 | [@NaniPuerta](https://github.com/NaniPuerta)

Liset Alfaro | C411 | [@LisetAlfaro](https://github.com/LisetAlfaro)

## Readme

Expand Down
Binary file added doc/informe.pdf
Binary file not shown.
265 changes: 265 additions & 0 deletions doc/informe.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
\documentclass[a4paper, 12pt]{article}
% General Document formatting
\usepackage[margin=0.7in]{geometry}
\usepackage[parfill]{parskip}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{amsthm}
\usepackage{amsmath}
\usepackage{mathtools}

\newtheorem{mydef}{Definici\'on}
\newtheorem{mytheo}{Teorema}

\begin{document}
\title{Documentacion del Proyecto final de Complementos de Compilación}
\date{Curso 2019-2020}

\author{
Adrian Gonzalez Sánchez- C412 - [@adriangs1996]\\
Eliane Puerta Cabrera- C412 - [@NaniPuerta]\\
Liset Alfaro Gonzalez- C411 - [@LisetAlfaro]\\
}

\maketitle

\section{Introducción}
\textit{COOL (Classroom Object-Oriented Language)} es un lenguaje pequeño, prácticamente de expresiones; pero que aun así,
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.
La gramatica de Cool utilizada es libre del contexto y es definida en nuestro proyecto como
una gram\'atica s-atributada, una definici\'on informal de la misma
puede encontrarse en el manual de Cool que aparece en la carpeta doc, precisamente donde se encuentra esta documentación.\\
En este documento quedan reflejadas las principales ideas a seguir por el equipo para
la implementación de un compilador funcional de este lenguaje,
pasando por un lenguaje intermedio CIL que facilita su transición a Mips.

\section{Requerimientos para ejecutar el compilador}
Lo primero que se debe hacer ejecutar el archivo Makefile que se encuentra en la carpeta src del proyecto utilizando el siguiente
comando:
\begin{verbatim}
$ make
\end{verbatim}

una vez termine de ejecutarse, habr\'a ocurrido lo siguiente
\begin{itemize}
\item Se tendr\'a instalada la librería cloudpickle, requerida para cargar el Parser que posteriormente mencionaremos.
\item Se crear\'a la carpeta build donde habr\'a un m\'odulo que contiene el binario de nuestro Lexer y nuestro Parser.
\end{itemize}
\section{Arquitectura:}

\subsection*{Módulos:}
\begin{itemize}
\item \textbf{Tokenizer}: \textit{src/tknizer.py}
\item \textbf{Parser}: El parser no es un m\'odulo, en vez de eso utilizamos nuestro
propio generador de parsers, el cual se encuentra en \textit{src/parserr/slr.py}. La tabla de parsing
devuelta es lo que se compila con cloudpickle.
\item \textbf{COOL AST}: \textit{src/abstract/tree.py}
\item \textbf{Visitors}: \textit{src/travels/*.py}
\item \textbf{CIL AST}: \textit{src/cil/nodes.py}
\item \textbf{MIPS Instruction Set}: \textit{src/mips/*.py}
\end{itemize}

\subsection*{Fases en las que se divide el compilador:}
Para una mejor organización se divide el compilador en varias fases
\begin{itemize}
\item \textbf{Lexer}: En esta fase se realiza un preprocesamiento de la entrada.
Este preprocesamiento consiste en sustituir los comentarios ,que pueden ser anidados y
por tanto no admiten una expresi\'on regular para detectarlos, por el caracter $espacio$,
manteniendo los caracteres fin de línea en el archivo fuente
(Esto es necesario para detectar un errores en la línea y la columna exacta donde ocurren).\\
El tokenizer que recibe este archivo fuente ya procesado tiene una tabla de expresiones regulares
donde se encuentran clasificados los tokens por prioridad,
esto nos permite, por ejemplo, no confundir palabras claves(keywords) con identificadores.
Este devuelve una lista de $tokens$ y pasamos a la segunda fase.\\

\item \textbf{Parser:} El generador del parser fue hecho por el equipo y la implementación
puede encontrarse en los archivos cuyo nombre corresponden con esta fase.
Este devuelve un parser $LALR$, que produce una derivaci\'on extrema derecha sobre una cadena de tokens y luego
esta se evalúa en una función llamada $evaluate$ que devuelve al \textit{AST de Cool}.\\

\item \textbf{Chequeo Sem\'antico:} En esta fase implementan varios recorridos sobre el AST de COOL, siguiendo
el patr\'on $visitor$.
Cada uno recolecta errores de índole sem\'antica y si uno de ellos encuentra un error lanza una excepción,
siendo este el comportamiento deseado:
\begin{itemize}
\item Recolector de Tipos(TypeCollector): Este recolecta los tipos y los define en el contexto. En este recorrido se
detecta si se redefinen las clases built-in, o si las clases son redefinidas.

\item Constructor de Tipos(TypeBuilder): Este Visitor define en cada tipo las funciones y atributos,
y maneja la herencia y redefinición de funciones.
En este se detectan errores como dependencias circulares, los atributos definidos con tipos inexistentes,
se chequean la correctitud de las definiciones de los par\'ametros de los m\'etodos que se redefinen, etc..

\item Inferencia de tipos(Inferer): En este recorrido se realiza el chequeo de Tipos y
adem\'as incorporamos inferencia de tipos al lenguage, feature que no est\'a contemplado
en la definici\'on formal. Este recorrido visualiza el codigo de COOL como una gran expresi\'on
y realiza un an\'alisi Bottom-Up, partiendo de tipos bien definidos de las expresiones en las hojas
como enteros, strings, etc. Como paso extra, para inferir los tipos nos basamos en las mismas reglas
sem\'anticas de tipos, pero agregamos recorridos para resolver los problemas de dependencia que puedan surgir
entre los elementos a inferir. Tomemos como ejemplo el siguiente fragmento de c\'odigo, tomado en parte del
test \textbf{Complex.cl}:

\begin{verbatim}
class Main inherits IO {
main() : AUTO_TYPE {
(let c : AUTO_TYPE <- (new Complex).init(4, 5) in
out_int(c.sum())
)
};
};

class Complex inherits IO {
x : AUTO_TYPE;
y : AUTO_TYPE;

init(a : AUTO_TYPE, b : AUTO_TYPE) : Complex {
{
x <- a;
y <- b;
self;
}
};

sum() : AUTO_TYPE {
x + y
};
};
\end{verbatim}

\begin{verbatim}
$ python testing.py > testing.mips
$ spim -file testing.mips
SPIM Version 8.0 of January 8, 2010
Copyright 1990-2010, James R. Larus.
All Rights Reserved.
See the file README for a full copyright notice.
Loaded: /usr/lib/spim/exceptions.s
9%
\end{verbatim}
\paragraph{}
El compilador es perfectamente capaz de inferir los tipos de cada argumento y de cada
atributo en este caso, pero, c\'omo ???
\paragraph{}
Es f\'acil resolver los tipos en este ejemplo a vista, ya que miramos primeramente el m\'etodo \textbf{sum}
en el cual los atributos son usados en una suma, y como en \textit{COOL} solo se pueden sumar enteros,
entonces los atributos deben ser enteros. Por otro lado, luego verificamos los argumentos de la funci\'on \textbf{init}
y vemos que est\'an siendo utilizados como asignaci\'on para los atributos, por lo que deben ser enteros tambi\'en.
La inferencia de los tipos de retorno de los m\'etodos \textbf{sum y main} es trivial, como lo es inferir el tipo de
la variable \textit{c}. Pero para el compilador, esta forma de "elegir" por donde comenzar a mirar, no es para nada trivial, ya que
las dependencias de los tipos de retorno forman un grafo que debe ser recorrido en orden topol\'ogico (de no existir dicho orden, o sea, no ser un DAG,
evidentemente existir\'ia una dependencia c\'iclica que no es posible resolver), pero definir este recorrido se ve complicado
por el scoping de los m\'etodos, y nuestra forma de tratar la inicializaci\'on de atributos, que terminan siendo m\'etodos "an\'onimos".
Dicho esto, nuestro enfoque es definir una relaci\'on de dependencia en profundidad, o sea, $d(x) = p$ si para
poder inferir el tipo de "$x$", es necesario inferir, como m\'aximo, $p$ elementos antes. Luego se hacen $p$ recorridos, sobre el AST
de COOL, en cada paso actualizando el contexto en el que existe cada elemento para poder utilizarlo en pasadas posteriores. As\'i
pudi\'eramos inferir en una primera pasada los tipos de retornos de los atributos, y luego en una segunda pasada, los argumentos.
En la pr\'actica, el \textbf{inferer} revisa primero los m\'etodos de inicializaci\'on de cada atributo, y luego
los m\'etodos en orden de definici\'on en el c\'odigo fuente, por lo que en este caso, se infieren primero los argumentos del m\'etodo,
pues son usados constantes enteras en su llamada a \textbf{init}, y de ah\'i se deduce el tipo de los atributos al ser asignados en la función.
Es f\'acil entonces ver que esta forma de inferencia est\'a limitada a la profundidad configurada por el compilador, la cual, por defecto
es $5$, ya que en la pr\'actica, un nivel de anidaci\'on de dependencias mayor es dificil de conseguir, aunque se puede modificar
pas\'andole como argumento la profundidad al compilador, de la siguiente manera:

\begin{verbatim}
$ python pycoolc.py --deep=10 <INPUT> [<OUTPUT>]
\end{verbatim}

\end{itemize}
\item \textbf{Generación de código:} En esta fase se pasa de Cool a CIL y luego de CIL a MIPS.
El conjunto de instrucciones de MIPS que se utiliza son del emulador de SPIM, o sea, utilizamos el conjunto
de instrucciones extendidas de MIPS, donde existen instrucciones como LW y MOVE que no son parte de la Arquitectura
original y que se traducen en dos o m\'as instrucciones en modo \textit{bare}. En esta fase primeramente traducimos
el AST de Cool a un AST de CIL (lenguaje intermedio), con el objetivo de facilitar el paso hacia MIPS. Este es un c\'odigo
de tres direcciones, compuesto por tres secciones principales \textbf{.DATA} \textbf{.CODE} \textbf{.TYPES}.
En la secci\'on .DATA almacenamos nuestros strings literales y lo que nosotros llamamos \textit{TDT}. En la secci\'on
de tipos va una representaci\'on de los tipos que luego se puedan convertir f\'acilmente a MIPS, aqu\'i ocurre el mangling
de los nombres de las funciones de modo que se puedan referenciar distintamente luego. Por \'ultimo en la secci\'on
.CODE van todas las funciones que nuestro programa necesite, incluidas las built-in que son bootstrapeadas al
inicio de este recorrido. Es interesante resaltar en CIL como manejamos los m\'etodos y atributos heredados, ya
que en los records que representan los tipos, cada m\'etodo y atributo heredado es agregado primero antes que los definidos
por el tipo en particular; lo que garantiza que para cualquier m\'etodo "$x$", el \'indice de $x$ en la lista de m\'etodos
de cualquier tipo que lo herede, es el mismo. Una vez que se termina el recorrido por el AST de COOL, hemos conformado
las tres secciones de CIL, y estas son pasadas al Generador de MIPS, que no es m\'as que otro recorrido sobre este nuevo
AST que hemos obtenido.

\item \textbf{Generaci\'on de c\'odigo MIPS}: El primer reto para generar c\'odigo ensamblador es representar el
conjunto de instrucciones de la arquitectura. Para lograr esto definimos varias clases bases (branches, loads, stores, comparisson, etc)
que redefinen el m\'etodo \textbf{\_\_str\_\_}, de modo que utilizan el nombre de la clase para representarse, y agregan el s\'imbolo
\$ en dependencia de si ponemos una constante o un registro. De esta forma la generaci\'on de c\'odigo referente a un nodo de CIL
se realiza de manera natural, casi como si program\'aramos en ensamblador, como por ejemplo, en este caso:

\begin{verbatim}
@visit.register
def _(self, node: cil.ArgNode):
# Pasar los argumentos en la pila.
self.add_source_line_comment(node)
src = self.visit(node.name)
reg = self.get_available_register()
assert src is not None and reg is not None

if isinstance(src, int):
self.register_instruction(LI(reg, src))
else:
self.register_instruction(LW(reg, src))

self.comment("Push arg into stack")
self.register_instruction(SUBU(sp, sp, 4, True))
self.register_instruction(SW(reg, "0($sp)"))

self.used_registers[reg] = False
\end{verbatim}

Como se puede ver, registramos una instruccion, casi como si program\'aramos assembly.

\paragraph{}
Otra aspecto significativo es la representaci\'on de los tipos en runtime. Al final, todo son solo n\'umeros,
por lo que tenemos que darles un formato que sea adecuado para poderlos referenciar y, que, adem\'as, permita
acceder a sus propiedades de manera eficiente. En este aspecto, usamos la siguiente estructura para los tipos:

\begin{verbatim}
################################# address
# TYPE_POINTER #
################################# address + 4
# VTABLE_POINTER #
################################# address + 8
# ATTRIBUTE_1 #
################################# address + 12
# ATTRIBUTE_2 #
#################################
# ... #
# ... #
# ... #
#################################
\end{verbatim}

Esta estructura permite varias cosas:
\begin{itemize}
\item Acceso a atributos en $O(1)$.
\item Acceso al nombre del tipo que corresponda a una instancia en $O(1)$.
\item Dispatch din\'amico en $O(1)$.
\end{itemize}

El mencionado puntero a la VTABLE, no es m\'as que el inicio de un array (Idea sacada de \textit{C++}) que en cada
tipo contiene los nombres manglados de sus funciones, y recordemos que anteriormente dijimos que en CIL,
garantiz\'abamos que el ind\'ice de cada m\'etodo es el mismo en cada tipo que lo herede, de ah\'i que
acceder a una funci\'on determinada sobre una instancia es tan f\'acil como cargar el puntero a la VTABLE
de la instancia, calcular el \'indice del m\'etodo que se quiere en tiempo de compilaci\'on y indexar en la
VTABLE en ese indice en runtime, para un dispatch en $O(1)$.

Otro aspecto que le prestamos inter\'es en esta fase es el tema de los \textit{case}. Las expresiones "case"
requieren que la jerarqu\'ia de tipos sea mantenida de alguna forma en runtime. En vez de esto, calculamos
lo que llamamos una $TDT$ (Type Distance Table), que no es m\'as que una tabla donde para cada par de tipos
A y B se le asigna la distancia a la que se encuentran en la jerarqu\'ia, o $-1$ en caso de que no pertenezcan
a la misma rama. Para conformar esta tabla hacemos un preprocesamiento en $O(n^2)$ basado en los resultados
de los tiempos de descubrimiento de un recorrido DFS sobre la jerarqu\'ia de tipos, partiendo desde la ra\'iz,
Object.

Importante tambi\'en son las convenciones que adoptamos al generar c\'odigo. Por ejemplo, cada funci\'on
de MIPS tiene un marco de pila que es creado con un m\'inimo de 32 bytes, porque es convenio entre programadores
de MIPS. Los par\'ametros a funciones se pasan en la pila, ya que aunque MIPS cuenta con 32 registros, no todos
son de prop\'osito general y complica mucho la implementaci\'on el hecho de llevar una cuenta de los registros
utilizados.

\end{itemize}
\end{document}
Binary file added doc/mipsassemblytutorial.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pytest
pytest-ordering
cloudpickle
Loading