From 50e12b0f5fa48aca84d3408ee6f2c8588452099c Mon Sep 17 00:00:00 2001 From: dany Date: Tue, 2 Mar 2021 17:59:19 -0800 Subject: [PATCH 01/91] init cool_compiler --- src/cool_compiler/Readme.md | 31 ++ src/cool_compiler/__init__.py | 0 src/cool_compiler/__main__.py | 0 .../cmp/.ipynb_checkpoints/ast-checkpoint.py | 20 + .../.ipynb_checkpoints/automata-checkpoint.py | 154 ++++++ .../languages-checkpoint.py | 220 ++++++++ .../nbpackage-checkpoint.py | 87 +++ .../pycompiler-checkpoint.py | 447 +++++++++++++++ .../.ipynb_checkpoints/tools-checkpoint.py | 10 + .../.ipynb_checkpoints/utils-checkpoint.py | 141 +++++ .../.ipynb_checkpoints/visitor-checkpoint.py | 80 +++ src/cool_compiler/cmp/__init__.py | 0 src/cool_compiler/cmp/ast.py | 62 +++ src/cool_compiler/cmp/ast_abstract_node.py | 33 ++ src/cool_compiler/cmp/automata.py | 207 +++++++ src/cool_compiler/cmp/cil.py | 231 ++++++++ src/cool_compiler/cmp/evaluation.py | 33 ++ src/cool_compiler/cmp/languages.py | 228 ++++++++ src/cool_compiler/cmp/nbpackage.py | 87 +++ src/cool_compiler/cmp/pycompiler.py | 512 ++++++++++++++++++ src/cool_compiler/cmp/semantic.py | 246 +++++++++ .../.ipynb_checkpoints/__init__-checkpoint.py | 0 .../.ipynb_checkpoints/automata-checkpoint.py | 3 + .../evaluation-checkpoint.py | 3 + .../.ipynb_checkpoints/parsing-checkpoint.py | 10 + src/cool_compiler/cmp/tools/__init__.py | 0 src/cool_compiler/cmp/tools/automata.py | 3 + src/cool_compiler/cmp/tools/evaluation.py | 3 + src/cool_compiler/cmp/tools/parsing.py | 16 + src/cool_compiler/cmp/tools/regex.py | 3 + src/cool_compiler/cmp/utils.py | 223 ++++++++ src/cool_compiler/cmp/visitor.py | 80 +++ src/cool_compiler/codegen/__dependency.py | 0 src/cool_compiler/codegen/__init__.py | 0 src/cool_compiler/codegen/__main__.py | 1 + src/cool_compiler/codegen/pipeline.py | 2 + src/cool_compiler/grammar.py | 0 src/cool_compiler/lexer/__dependency.py | 0 src/cool_compiler/lexer/__init__.py | 1 + src/cool_compiler/lexer/__main__.py | 2 + src/cool_compiler/parser/__dependency.py | 0 src/cool_compiler/parser/__init__.py | 0 src/cool_compiler/parser/__main__.py | 2 + src/cool_compiler/semantic/__dependency.py | 0 src/cool_compiler/semantic/__init__.py | 0 src/cool_compiler/semantic/__main__.py | 2 + src/cool_compiler/semantic_ast.py | 0 src/cool_compiler/table_regex.py | 19 + src/makefile | 14 + 49 files changed, 3216 insertions(+) create mode 100644 src/cool_compiler/Readme.md create mode 100644 src/cool_compiler/__init__.py create mode 100644 src/cool_compiler/__main__.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py create mode 100644 src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py create mode 100644 src/cool_compiler/cmp/__init__.py create mode 100644 src/cool_compiler/cmp/ast.py create mode 100644 src/cool_compiler/cmp/ast_abstract_node.py create mode 100644 src/cool_compiler/cmp/automata.py create mode 100644 src/cool_compiler/cmp/cil.py create mode 100644 src/cool_compiler/cmp/evaluation.py create mode 100644 src/cool_compiler/cmp/languages.py create mode 100644 src/cool_compiler/cmp/nbpackage.py create mode 100644 src/cool_compiler/cmp/pycompiler.py create mode 100644 src/cool_compiler/cmp/semantic.py create mode 100644 src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py create mode 100644 src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py create mode 100644 src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py create mode 100644 src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py create mode 100644 src/cool_compiler/cmp/tools/__init__.py create mode 100644 src/cool_compiler/cmp/tools/automata.py create mode 100644 src/cool_compiler/cmp/tools/evaluation.py create mode 100644 src/cool_compiler/cmp/tools/parsing.py create mode 100644 src/cool_compiler/cmp/tools/regex.py create mode 100644 src/cool_compiler/cmp/utils.py create mode 100644 src/cool_compiler/cmp/visitor.py create mode 100644 src/cool_compiler/codegen/__dependency.py create mode 100644 src/cool_compiler/codegen/__init__.py create mode 100644 src/cool_compiler/codegen/__main__.py create mode 100644 src/cool_compiler/codegen/pipeline.py create mode 100644 src/cool_compiler/grammar.py create mode 100644 src/cool_compiler/lexer/__dependency.py create mode 100644 src/cool_compiler/lexer/__init__.py create mode 100644 src/cool_compiler/lexer/__main__.py create mode 100644 src/cool_compiler/parser/__dependency.py create mode 100644 src/cool_compiler/parser/__init__.py create mode 100644 src/cool_compiler/parser/__main__.py create mode 100644 src/cool_compiler/semantic/__dependency.py create mode 100644 src/cool_compiler/semantic/__init__.py create mode 100644 src/cool_compiler/semantic/__main__.py create mode 100644 src/cool_compiler/semantic_ast.py create mode 100644 src/cool_compiler/table_regex.py diff --git a/src/cool_compiler/Readme.md b/src/cool_compiler/Readme.md new file mode 100644 index 000000000..a54bfa781 --- /dev/null +++ b/src/cool_compiler/Readme.md @@ -0,0 +1,31 @@ +# El modulo cool_compiler + +Se componen de otros 5 modulos, cmp, lexer, parser, semantic, generator_code. +Menos cmp el cuale 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 + compisicion 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 externo 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 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 consenso 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 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py new file mode 100644 index 000000000..e69de29bb 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/cmp/ast.py b/src/cool_compiler/cmp/ast.py new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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 100644 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/semantic.py b/src/cool_compiler/cmp/semantic.py new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/cmp/tools/automata.py b/src/cool_compiler/cmp/tools/automata.py new file mode 100644 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 100644 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 100644 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 100644 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 100644 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 100644 index 000000000..964842836 --- /dev/null +++ b/src/cool_compiler/cmp/visitor.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/codegen/__dependency.py b/src/cool_compiler/codegen/__dependency.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/codegen/__init__.py b/src/cool_compiler/codegen/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/codegen/__main__.py b/src/cool_compiler/codegen/__main__.py new file mode 100644 index 000000000..c986d5f81 --- /dev/null +++ b/src/cool_compiler/codegen/__main__.py @@ -0,0 +1 @@ +print("aaaaaa") \ No newline at end of file diff --git a/src/cool_compiler/codegen/pipeline.py b/src/cool_compiler/codegen/pipeline.py new file mode 100644 index 000000000..f898d0ce3 --- /dev/null +++ b/src/cool_compiler/codegen/pipeline.py @@ -0,0 +1,2 @@ +def run_code_generator(ast): + pass \ No newline at end of file diff --git a/src/cool_compiler/grammar.py b/src/cool_compiler/grammar.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/lexer/__dependency.py b/src/cool_compiler/lexer/__dependency.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/lexer/__init__.py b/src/cool_compiler/lexer/__init__.py new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/src/cool_compiler/lexer/__init__.py @@ -0,0 +1 @@ + \ 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 100644 index 000000000..df7c38525 --- /dev/null +++ b/src/cool_compiler/lexer/__main__.py @@ -0,0 +1,2 @@ +def lexer(code): + pass \ No newline at end of file diff --git a/src/cool_compiler/parser/__dependency.py b/src/cool_compiler/parser/__dependency.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/parser/__init__.py b/src/cool_compiler/parser/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/parser/__main__.py b/src/cool_compiler/parser/__main__.py new file mode 100644 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/semantic/__dependency.py b/src/cool_compiler/semantic/__dependency.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/semantic/__main__.py b/src/cool_compiler/semantic/__main__.py new file mode 100644 index 000000000..76c5c7dc3 --- /dev/null +++ b/src/cool_compiler/semantic/__main__.py @@ -0,0 +1,2 @@ +def semantic_checking(ast): + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic_ast.py b/src/cool_compiler/semantic_ast.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/cool_compiler/table_regex.py b/src/cool_compiler/table_regex.py new file mode 100644 index 000000000..a20159eab --- /dev/null +++ b/src/cool_compiler/table_regex.py @@ -0,0 +1,19 @@ +from enum import Enum + +class TokenType(Enum): + pass + + +class RegexTable: + + def __call__(self): + return self.symbol_table() + self.keyword_table() + self.identifier_table() + + def symbol_table(self): + pass + + def identifier_table(self): + pass + + def keyword_table(self): + pass \ No newline at end of file diff --git a/src/makefile b/src/makefile index 30df993f5..481b765b7 100644 --- a/src/makefile +++ b/src/makefile @@ -10,3 +10,17 @@ 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 \ No newline at end of file From 3da3b8bd681b385ee330661369051570a45f3059 Mon Sep 17 00:00:00 2001 From: dany Date: Thu, 4 Mar 2021 09:55:17 -0800 Subject: [PATCH 02/91] bug in readme --- src/cool_compiler/Readme.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/cool_compiler/Readme.md b/src/cool_compiler/Readme.md index a54bfa781..3b7eb910d 100644 --- a/src/cool_compiler/Readme.md +++ b/src/cool_compiler/Readme.md @@ -1,24 +1,25 @@ # El modulo cool_compiler Se componen de otros 5 modulos, cmp, lexer, parser, semantic, generator_code. -Menos cmp el cuale contiene implementaciones utiles aportadas por los profesores +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 +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 - compisicion del mismo + 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) + 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 externo en el proceso de implementacion. Y en el caso - particular del modulo cool_compiler supone la puerta de inicio de todo el proyecto + 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 del proyecto las `.py` que contienen caracteristicas destintivas +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 consenso en la implementacion +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 From 427e8ea0de89663efb3b38b15e3af081245cf5d0 Mon Sep 17 00:00:00 2001 From: dany Date: Thu, 4 Mar 2021 11:30:47 -0800 Subject: [PATCH 03/91] add ast factory interface --- src/cool_compiler/__dependency.py | 1 + src/cool_compiler/ast_factory.py | 24 ++++++++++++++++++++++++ src/cool_compiler/grammar.py | 2 ++ src/cool_compiler/table_regex.py | 5 +++++ 4 files changed, 32 insertions(+) create mode 100644 src/cool_compiler/__dependency.py create mode 100644 src/cool_compiler/ast_factory.py diff --git a/src/cool_compiler/__dependency.py b/src/cool_compiler/__dependency.py new file mode 100644 index 000000000..5a43b46bc --- /dev/null +++ b/src/cool_compiler/__dependency.py @@ -0,0 +1 @@ +from .ast_factory import AstFactory as Factory \ No newline at end of file diff --git a/src/cool_compiler/ast_factory.py b/src/cool_compiler/ast_factory.py new file mode 100644 index 000000000..917027705 --- /dev/null +++ b/src/cool_compiler/ast_factory.py @@ -0,0 +1,24 @@ +from enum import Enum + +class KeyNameNode(Enum): + kclass = "class" + +# interface to create ast nodes +# and decouple the grammar of these nodes +class AstFactory: + def __init__(self, dict_knn_ast_node : dict = {}): + self.__dict = dict_knn_ast_node + + def __call__(self, key_name_node : str ) : + return self.Builder(key_name_node, self.__dict) + + class Builder: + def __init__(self, knn, dicc): + self.knn = knn + self.dicc = dicc + + # synteticed is a list with tokens and nodes + def build(self, synteticed_list : list): + return self.dicc[self.knn](synteticed_list) + + diff --git a/src/cool_compiler/grammar.py b/src/cool_compiler/grammar.py index e69de29bb..b98306422 100644 --- a/src/cool_compiler/grammar.py +++ b/src/cool_compiler/grammar.py @@ -0,0 +1,2 @@ +from .__dependency import Factory + diff --git a/src/cool_compiler/table_regex.py b/src/cool_compiler/table_regex.py index a20159eab..50cceda59 100644 --- a/src/cool_compiler/table_regex.py +++ b/src/cool_compiler/table_regex.py @@ -3,6 +3,11 @@ class TokenType(Enum): pass +class Token: + def __init__(self, lex, ttype : TokenType, pos : tuple) : + self.lex = lex + self.type = ttype + self.pos = pos class RegexTable: From 8a44db09de57ebae9954b63dd32ab47eb34af78e Mon Sep 17 00:00:00 2001 From: dany Date: Tue, 16 Mar 2021 08:27:17 -0700 Subject: [PATCH 04/91] add poetry --- poetry.lock | 193 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 18 +++++ 2 files changed, 211 insertions(+) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 000000000..ee30530e7 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,193 @@ +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "20.3.0" +description = "Classes Without Boilerplate" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "packaging" +version = "20.9" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "py" +version = "1.10.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pytest" +version = "6.2.2" +description = "pytest: simple powerful testing with Python" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<1.0.0a1" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-ordering" +version = "0.6" +description = "pytest plugin to run your tests in a specific order" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pytest = "*" + +[[package]] +name = "sly" +version = "0.4" +description = "SLY - Sly Lex Yacc" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +test = ["pytest", "regex"] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[metadata] +lock-version = "1.1" +python-versions = "3.8.5" +content-hash = "27b884dfe56b92705f08ba9a9cf886bc788e356820b4779be6dcb1847ab3f0b3" + +[metadata.files] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +packaging = [ + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +ply = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] +py = [ + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, +] +pytest-ordering = [ + {file = "pytest-ordering-0.6.tar.gz", hash = "sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6"}, + {file = "pytest_ordering-0.6-py2-none-any.whl", hash = "sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2"}, + {file = "pytest_ordering-0.6-py3-none-any.whl", hash = "sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6"}, +] +sly = [ + {file = "sly-0.4.tar.gz", hash = "sha256:e5f2266a231322cc17519fbc3a3ba1c6335fed5a9a55abe0e598a35aea0ac32a"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..538c6512c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[tool.poetry] +name = "cmp" +version = "0.1.0" +description = "" +authors = ["dany"] + +[tool.poetry.dependencies] +python = "3.8.5" +pytest = "^6.2.2" +pytest-ordering = "^0.6" +sly = "^0.4" +ply = "^3.11" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From 6661eee9113268badad86db5d67a9351ea1d3eb0 Mon Sep 17 00:00:00 2001 From: dany Date: Tue, 16 Mar 2021 18:43:17 -0700 Subject: [PATCH 05/91] add comment lexer --- .vscode/settings.json | 3 + src/cool_compiler/lexer/__main__.py | 9 ++- src/cool_compiler/lexer/comment_lexer.py | 38 ++++++++++++ src/cool_compiler/lexer/cool_lexer.py | 76 ++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/cool_compiler/lexer/comment_lexer.py create mode 100644 src/cool_compiler/lexer/cool_lexer.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..993b38259 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/home/dany/.cache/pypoetry/virtualenvs/cmp-Jp0snq0--py3.8/bin/python" +} \ No newline at end of file diff --git a/src/cool_compiler/lexer/__main__.py b/src/cool_compiler/lexer/__main__.py index df7c38525..534790c46 100644 --- a/src/cool_compiler/lexer/__main__.py +++ b/src/cool_compiler/lexer/__main__.py @@ -1,2 +1,7 @@ -def lexer(code): - pass \ No newline at end of file +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 100644 index 000000000..39ce362ec --- /dev/null +++ b/src/cool_compiler/lexer/comment_lexer.py @@ -0,0 +1,38 @@ +from sly import Lexer + +class CoolComment(Lexer): + tokens = { TEXT } + + ignore_open = r'\(\*' + ignore_close = r'\*\)' + ignore_newline = r'\n+' + TEXT = r'.' + + def __init__(self): + 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.len = len(text) + for _ in self.tokenize(text): + pass + + return 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 100644 index 000000000..1f91a23fe --- /dev/null +++ b/src/cool_compiler/lexer/cool_lexer.py @@ -0,0 +1,76 @@ +from typing import ClassVar +from sly import Lexer +from sly.lex import LexError +from .comment_lexer import CoolComment + +class CoolLexer(Lexer): + tokens = { + CLASS,IF, + ID,NUMBER, + PLUS,MINUS,TIMES,DIVIDE, + ASSIGN,LPAREN,RPAREN, + } + + ignore = r' \t' + ignore_comment = r'\(\*' + ignore_newline = r'\n+' + + CLASS = r'class' + IF = f'if' + ID = r'[a-zA-Z][a-zA-Z0-9]*' + NUMBER = r'\d+' + PLUS = r'\+' + MINUS = r'-' + TIMES = r'\*' + DIVIDE = r'/' + ASSIGN = r'=' + LPAREN = r'\(' + RPAREN = r'\)' + + def ignore_newline(self,token): + self.lineno += 1 + + def ignore_comment(self,token): + lexer = CoolComment() + text = self.text[self.index-2:] + pos, line = lexer.comment_analizer(text) + self.index += pos + self.lineno += line + #text = token.value[2:] + #print(text) + #copen = '(*' + #cclse = '*)' + #s = 1 + # mas (* que *) + #for i in range(len(text)): + # if s == 0: + # text = text[i+1:] + # break + # if copen == text[ i:i+2 ]: s = s + 1 + # if cclse == text[ i:i+2 ]: s = s - 1 + + # mas *) que (* + #pos = 0 + #for i in range(len(text)): + # if copen == text[ i:i+2 ]: break + # if cclse == text[ i:i+2 ]: + # s = s - 1 + # pos = i+2 + + #self.index -= len(text[pos:] + + + def NUMBER(self, token): + token.value = int(token.value) + return token + + + + +if __name__ == '__main__': + data = ''' + (* (* (* *) *) *) a *) e*) eeeee (* a*) + ''' + lexer = CoolLexer() + for tok in lexer.tokenize(data): + print(tok) \ No newline at end of file From de1afb2e9483ab560c0b75d9ab3afd9f948ac872 Mon Sep 17 00:00:00 2001 From: dany Date: Mon, 22 Mar 2021 19:54:49 -0700 Subject: [PATCH 06/91] kill tester --- src/cool_compiler/__main__.py | 16 +++ src/cool_compiler/error/__init__.py | 1 + src/cool_compiler/error/error.py | 29 +++++ src/cool_compiler/lexer/__init__.py | 2 +- src/cool_compiler/lexer/comment_lexer.py | 14 ++- src/cool_compiler/lexer/cool_lexer.py | 134 ++++++++++++++++------- src/cool_compiler/lexer/string_lexer.py | 86 +++++++++++++++ src/coolc.sh | 3 +- src/makefile | 2 +- src/mixed2.cl | 20 ++++ src/string1.cl | 6 + src/string3.cl | Bin 0 -> 234 bytes 12 files changed, 264 insertions(+), 49 deletions(-) create mode 100644 src/cool_compiler/error/__init__.py create mode 100644 src/cool_compiler/error/error.py create mode 100644 src/cool_compiler/lexer/string_lexer.py create mode 100644 src/mixed2.cl create mode 100644 src/string1.cl create mode 100644 src/string3.cl diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index e69de29bb..168c74401 100644 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -0,0 +1,16 @@ +import sys +from .error import CoolError +from .lexer import CoolLexer + +path = "" +if len(sys.argv) > 1: + path = sys.argv[1] + + +with open(path, 'r') as _file: + text = _file.read() + errors = CoolError(text) + lexer = CoolLexer(errors) + + tokens = [token for token in lexer.tokenize(text)] + if errors.any(): sys.exit(1) \ 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 100644 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 100644 index 000000000..84b16373d --- /dev/null +++ b/src/cool_compiler/error/error.py @@ -0,0 +1,29 @@ +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)) + + 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 + + def __add(self, etype, text): + self._list.append(f'{self.pos} - {etype}: {text}') + + def add_lexical(self, text): + self.__add("LexicographicError", text) diff --git a/src/cool_compiler/lexer/__init__.py b/src/cool_compiler/lexer/__init__.py index 0519ecba6..03209d807 100644 --- a/src/cool_compiler/lexer/__init__.py +++ b/src/cool_compiler/lexer/__init__.py @@ -1 +1 @@ - \ No newline at end of file +from .cool_lexer import CoolLexer \ No newline at end of file diff --git a/src/cool_compiler/lexer/comment_lexer.py b/src/cool_compiler/lexer/comment_lexer.py index 39ce362ec..b69e293c2 100644 --- a/src/cool_compiler/lexer/comment_lexer.py +++ b/src/cool_compiler/lexer/comment_lexer.py @@ -1,14 +1,15 @@ -from sly import Lexer +from sly import Lexer, lex class CoolComment(Lexer): tokens = { TEXT } ignore_open = r'\(\*' ignore_close = r'\*\)' - ignore_newline = r'\n+' + ignore_newline = r'\n' TEXT = r'.' - def __init__(self): + def __init__(self, lexer ): + self.lexer = lexer self.pos = 0 self.count_new_line = 0 self.s = 0 @@ -26,12 +27,13 @@ def ignore_close(self, token): def ignore_newline(self, token): self.count_new_line += 1 - def comment_analizer(self, text): + def comment_analizer(self): + text = self.lexer.text[self.lexer.index-2:] self.len = len(text) - for _ in self.tokenize(text): + for last in self.tokenize(text): pass - return self.pos, self.count_new_line + 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 index 1f91a23fe..9db74947b 100644 --- a/src/cool_compiler/lexer/cool_lexer.py +++ b/src/cool_compiler/lexer/cool_lexer.py @@ -2,75 +2,129 @@ from sly import Lexer from sly.lex import LexError from .comment_lexer import CoolComment +from .string_lexer import CoolString class CoolLexer(Lexer): + def __init__(self, error=None) -> None: + super().__init__() + self.cool_error = error + tokens = { - CLASS,IF, - ID,NUMBER, - PLUS,MINUS,TIMES,DIVIDE, - ASSIGN,LPAREN,RPAREN, + CLASS, INHERITS, + IF, THEN, ELSE, FI, + LET, IN, + WHILE, LOOP, POOL, + CASE, OF, ESAC, + ISVOID, NEW, NOT, + TRUE, FALSE, + ID, NUMBER, + TWOPOINT, ARROW, OPENKEY, CLOSEKEY, ATSING, POINT, COLON, SEMICOL, LOGICAR, + EQUAL, LESS_OR, LESS, + COMPLEM, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, + STRING } ignore = r' \t' ignore_comment = r'\(\*' - ignore_newline = r'\n+' + ignore_newline = r'\n' + ignore_line = r'--.*\n' CLASS = r'class' - IF = f'if' - ID = r'[a-zA-Z][a-zA-Z0-9]*' + INHERITS= r'inherits' + + IF = r'if' + THEN = r'then' + ELSE = r'else' + FI = r'fi' + + LET = r'let' + IN = r'in' + + + WHILE = r'while' + LOOP = r'loop' + POOL = r'pool' + + CASE = r'case' + OF = r'of' + ESAC = r'esac' + + ISVOID = r'isvoid' + NEW = r'new' + NOT = r'not' + + TRUE = r'true' + FALSE = r'false' + + ID = r'[a-zA-Z][a-zA-Z0-9_]*' NUMBER = r'\d+' + + TWOPOINT= r':' + ARROW = r'<-' + OPENKEY = r'{' + CLOSEKEY= r'}' + ATSING = r'@' + POINT = r'\.' + COLON = r',' + SEMICOL = r';' + LOGICAR = r'=>' + + EQUAL = r'=' + LESS_OR = r'<=' + LESS = r'<' + + COMPLEM = r'~' PLUS = r'\+' MINUS = r'-' TIMES = r'\*' DIVIDE = r'/' - ASSIGN = r'=' LPAREN = r'\(' RPAREN = r'\)' + + STRING = r'\"' + + def ignore_line(self, token): + self.lineno += 1 def ignore_newline(self,token): self.lineno += 1 def ignore_comment(self,token): - lexer = CoolComment() - text = self.text[self.index-2:] - pos, line = lexer.comment_analizer(text) - self.index += pos + lexer = CoolComment(self) + _bool, pos, line = lexer.comment_analizer() self.lineno += line - #text = token.value[2:] - #print(text) - #copen = '(*' - #cclse = '*)' - #s = 1 - # mas (* que *) - #for i in range(len(text)): - # if s == 0: - # text = text[i+1:] - # break - # if copen == text[ i:i+2 ]: s = s + 1 - # if cclse == text[ i:i+2 ]: s = s - 1 - # mas *) que (* - #pos = 0 - #for i in range(len(text)): - # if copen == text[ i:i+2 ]: break - # if cclse == text[ i:i+2 ]: - # s = s - 1 - # pos = i+2 - - #self.index -= len(text[pos:] + 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 -if __name__ == '__main__': - data = ''' - (* (* (* *) *) *) 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/string_lexer.py b/src/cool_compiler/lexer/string_lexer.py new file mode 100644 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/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 index 481b765b7..25a1ef33f 100644 --- a/src/makefile +++ b/src/makefile @@ -1,7 +1,7 @@ .PHONY: clean main: - # Compiling the compiler :) + python -m cool_compiler string3.cl clean: rm -rf build/* diff --git a/src/mixed2.cl b/src/mixed2.cl new file mode 100644 index 000000000..9c4b6917b --- /dev/null +++ b/src/mixed2.cl @@ -0,0 +1,20 @@ +"kjas\"lnnsdj /0 flj\trdsaf" +@.$.@ +@*%*@ +"alkjfldajf""dasfadsf + +(* +#1 STR_CONST "kjas\"lnnsdj\nfljrdsaf" +#2 '@' +#2 '.' +#2 ERROR "$" +#2 '.' +#2 '@' +#3 '@' +#3 '*' +#3 ERROR "%" +#3 '*' +#3 '@' +#4 STR_CONST "alkjfldajf" +#4 ERROR "Unterminated string constant" +*) \ No newline at end of file diff --git a/src/string1.cl b/src/string1.cl new file mode 100644 index 000000000..6c3c00833 --- /dev/null +++ b/src/string1.cl @@ -0,0 +1,6 @@ +(* A non-escaped newline character may not appear in a string *) + +"This \ +is OK" +"This is not +OK" \ No newline at end of file diff --git a/src/string3.cl b/src/string3.cl new file mode 100644 index 0000000000000000000000000000000000000000..78abc4972e218bca373ba1750c99a3450cef4ea3 GIT binary patch literal 234 zcmX|4yAH!34D8HToS2dhRoZ?*=Jpd<90*B>0}_xSe_!a!lI8Q=*(aJadZZi|KVhQ- zK4j?NGc6u@9^rRpGmYcJ^ifl$K@ Mi{IIrdU_-I0>Lp*mH+?% literal 0 HcmV?d00001 From 318ef11edb380061b85c05204822169b0855fc65 Mon Sep 17 00:00:00 2001 From: Daniel Orlando Ortiz Pacheco Date: Sun, 3 Oct 2021 17:04:13 -0400 Subject: [PATCH 07/91] reinit proyect --- .DS_Store | Bin 0 -> 6148 bytes .github/workflows/tests.yml | 0 .gitignore | 0 .ipynb_checkpoints/cp1-checkpoint.ipynb | 463 ++++++++++++++++++ .vscode/settings.json | 3 +- LICENSE | 0 Readme.md | 0 doc/Readme.md | 0 doc/cool-manual.pdf | Bin doc/github-git-cheat-sheet.pdf | Bin doc/team.yml | 0 img/img1.png | Bin img/img10.png | Bin img/img11.png | Bin img/img12.png | Bin img/img2.png | Bin img/img3.png | Bin img/img4.png | Bin img/img5.png | Bin img/img6.png | Bin img/img7.png | Bin img/img8.png | Bin img/img9.png | Bin poetry.lock | 0 pyproject.toml | 0 requirements.txt | 0 src/.DS_Store | Bin 0 -> 6148 bytes src/Readme.md | 0 src/assignment1.cl | 15 + src/cool_compiler/.DS_Store | Bin 0 -> 6148 bytes src/cool_compiler/Readme.md | 0 src/cool_compiler/__dependency.py | 1 - src/cool_compiler/__init__.py | 0 src/cool_compiler/__main__.py | 21 +- src/cool_compiler/ast_factory.py | 24 - .../cmp/.ipynb_checkpoints/ast-checkpoint.py | 0 .../.ipynb_checkpoints/automata-checkpoint.py | 0 .../languages-checkpoint.py | 0 .../nbpackage-checkpoint.py | 0 .../pycompiler-checkpoint.py | 0 .../.ipynb_checkpoints/tools-checkpoint.py | 0 .../.ipynb_checkpoints/utils-checkpoint.py | 0 .../.ipynb_checkpoints/visitor-checkpoint.py | 0 src/cool_compiler/cmp/__init__.py | 0 src/cool_compiler/cmp/ast.py | 0 src/cool_compiler/cmp/ast_abstract_node.py | 0 src/cool_compiler/cmp/automata.py | 0 src/cool_compiler/cmp/cil.py | 0 src/cool_compiler/cmp/evaluation.py | 0 src/cool_compiler/cmp/languages.py | 0 src/cool_compiler/cmp/nbpackage.py | 0 src/cool_compiler/cmp/pycompiler.py | 0 src/cool_compiler/cmp/semantic.py | 0 .../.ipynb_checkpoints/__init__-checkpoint.py | 0 .../.ipynb_checkpoints/automata-checkpoint.py | 0 .../evaluation-checkpoint.py | 0 .../.ipynb_checkpoints/parsing-checkpoint.py | 0 src/cool_compiler/cmp/tools/__init__.py | 0 src/cool_compiler/cmp/tools/automata.py | 0 src/cool_compiler/cmp/tools/evaluation.py | 0 src/cool_compiler/cmp/tools/parsing.py | 0 src/cool_compiler/cmp/tools/regex.py | 0 src/cool_compiler/cmp/utils.py | 0 src/cool_compiler/cmp/visitor.py | 0 src/cool_compiler/codegen/__dependency.py | 0 src/cool_compiler/codegen/__init__.py | 0 src/cool_compiler/codegen/__main__.py | 1 - src/cool_compiler/codegen/pipeline.py | 0 src/cool_compiler/error/__init__.py | 0 src/cool_compiler/error/error.py | 23 +- src/cool_compiler/grammar.py | 2 - .../cool_lexer-checkpoint.py | 105 ++++ src/cool_compiler/lexer/__dependency.py | 2 + src/cool_compiler/lexer/__init__.py | 0 src/cool_compiler/lexer/__main__.py | 0 src/cool_compiler/lexer/comment_lexer.py | 0 src/cool_compiler/lexer/cool_lexer.py | 81 ++- src/cool_compiler/lexer/string_lexer.py | 0 src/cool_compiler/parser/__dependency.py | 1 + src/cool_compiler/parser/__init__.py | 2 + src/cool_compiler/parser/__main__.py | 0 src/cool_compiler/parser/cool_parser.py | 285 +++++++++++ src/cool_compiler/parser/factory_decored.py | 65 +++ src/cool_compiler/semantic/.DS_Store | Bin 0 -> 6148 bytes src/cool_compiler/semantic/__dependency.py | 12 + src/cool_compiler/semantic/__init__.py | 2 + src/cool_compiler/semantic/__main__.py | 0 src/cool_compiler/semantic/ast_print.py | 250 ++++++++++ .../semantic/create_type/__init__.py | 8 + .../semantic/create_type/main.py | 79 +++ .../semantic/create_type/node__.py | 13 + .../semantic/create_type/node_atoms.py | 53 ++ .../semantic/create_type/node_binary.py | 40 ++ .../semantic/create_type/node_case.py | 20 + .../semantic/create_type/node_class.py | 39 ++ .../semantic/create_type/node_defattr.py | 25 + .../semantic/create_type/node_deffunc.py | 26 + .../semantic/create_type/node_dispatch.py | 51 ++ .../semantic/create_type/node_let.py | 23 + .../semantic/create_type/node_program.py | 19 + .../semantic/create_type/node_statements.py | 49 ++ src/cool_compiler/semantic/factory_node.py | 166 +++++++ .../semantic/factory_return_ast.py | 147 ++++++ src/cool_compiler/semantic/scope.py | 43 ++ .../semantic/semantic_checking/__init__.py | 8 + .../ast2_semantic_checking_return.py | 160 ++++++ .../semantic/semantic_checking/main.py | 77 +++ .../semantic/semantic_checking/node__.py | 16 + .../semantic/semantic_checking/node_class.py | 27 + .../semantic_checking/node_program.py | 12 + .../semantic_checking/v2_semantic_checking.py | 338 +++++++++++++ src/cool_compiler/semantic/tools.py | 98 ++++ src/cool_compiler/semantic/visitor.py | 92 ++++ src/cool_compiler/semantic_ast.py | 0 src/cool_compiler/table_regex.py | 24 - src/cool_compiler/types/__init__.py | 4 + .../types/build_in_types/__init__.py | 9 + .../types/build_in_types/bool.py | 13 + src/cool_compiler/types/build_in_types/int.py | 11 + src/cool_compiler/types/build_in_types/io.py | 21 + .../types/build_in_types/object.py | 19 + .../types/build_in_types/self.py | 15 + src/cool_compiler/types/build_in_types/str.py | 24 + .../types/cool_type_build_in_manager.py | 31 ++ src/cool_compiler/types/error_type.py | 18 + src/cool_compiler/types/tools.py | 35 ++ src/cool_compiler/types/type.py | 122 +++++ src/makefile | 2 +- src/mixed2.cl | 20 - src/string1.cl | 6 - src/string3.cl | Bin 234 -> 0 bytes tests/codegen/arith_input.txt | 0 tests/codegen/arith_output.txt | 0 tests/codegen/atoi.cl | 0 tests/codegen/atoi_input.txt | 0 tests/codegen/atoi_output.txt | 0 tests/codegen/book_list_input.txt | 0 tests/codegen/book_list_output.txt | 0 tests/codegen/cells_input.txt | 0 tests/codegen/cells_output.txt | 0 tests/codegen/complex_input.txt | 0 tests/codegen/complex_output.txt | 0 tests/codegen/fib.cl | 0 tests/codegen/fib_input.txt | 0 tests/codegen/fib_output.txt | 0 tests/codegen/graph_input.txt | 0 tests/codegen/graph_output.txt | 0 tests/codegen/hairyscary_input.txt | 0 tests/codegen/hairyscary_output.txt | 0 tests/codegen/hello_world_input.txt | 0 tests/codegen/hello_world_output.txt | 0 tests/codegen/io_input.txt | 0 tests/codegen/io_output.txt | 0 tests/codegen/life_input.txt | 0 tests/codegen/life_output.txt | 0 tests/codegen/list.cl | 0 tests/codegen/list_input.txt | 0 tests/codegen/list_output.txt | 0 tests/codegen/new_complex_input.txt | 0 tests/codegen/new_complex_output.txt | 0 tests/codegen/palindrome_input.txt | 0 tests/codegen/palindrome_output.txt | 0 tests/codegen/primes.cl | 0 tests/codegen/primes_input.txt | 0 tests/codegen/primes_output.txt | 0 tests/codegen/print-cool.cl | 0 tests/codegen/print-cool_input.txt | 0 tests/codegen/print-cool_output.txt | 0 tests/codegen/sort-list.cl | 0 tests/codegen/sort-list_input.txt | 0 tests/codegen/sort-list_output.txt | 0 tests/codegen_test.py | 0 tests/conftest.py | 0 tests/lexer/comment1.cl | 0 tests/lexer/comment1_error.txt | 0 tests/lexer/iis1.cl | 0 tests/lexer/iis1_error.txt | 0 tests/lexer/iis2.cl | 0 tests/lexer/iis2_error.txt | 0 tests/lexer/iis3.cl | 0 tests/lexer/iis3_error.txt | 0 tests/lexer/iis4.cl | 0 tests/lexer/iis4_error.txt | 0 tests/lexer/iis5.cl | 0 tests/lexer/iis5_error.txt | 0 tests/lexer/iis6.cl | 0 tests/lexer/iis6_error.txt | 0 tests/lexer/mixed1.cl | 0 tests/lexer/mixed1_error.txt | 0 tests/lexer/mixed2.cl | 0 tests/lexer/mixed2_error.txt | 0 tests/lexer/string1.cl | 0 tests/lexer/string1_error.txt | 0 tests/lexer/string2.cl | 0 tests/lexer/string2_error.txt | 0 tests/lexer/string3.cl | Bin tests/lexer/string3_error.txt | 0 tests/lexer/string4.cl | 0 tests/lexer/string4_error.txt | 0 tests/lexer_test.py | 0 tests/parser/assignment1.cl | 0 tests/parser/assignment1_error.txt | 0 tests/parser/assignment2.cl | 0 tests/parser/assignment2_error.txt | 0 tests/parser/assignment3.cl | 0 tests/parser/assignment3_error.txt | 0 tests/parser/attribute1.cl | 0 tests/parser/attribute1_error.txt | 0 tests/parser/attribute2.cl | 0 tests/parser/attribute2_error.txt | 0 tests/parser/attribute3.cl | 0 tests/parser/attribute3_error.txt | 0 tests/parser/block1.cl | 0 tests/parser/block1_error.txt | 0 tests/parser/block2.cl | 0 tests/parser/block2_error.txt | 0 tests/parser/block3.cl | 0 tests/parser/block3_error.txt | 0 tests/parser/block4.cl | 0 tests/parser/block4_error.txt | 0 tests/parser/case1.cl | 0 tests/parser/case1_error.txt | 0 tests/parser/case2.cl | 0 tests/parser/case2_error.txt | 0 tests/parser/case3.cl | 0 tests/parser/case3_error.txt | 0 tests/parser/case4.cl | 0 tests/parser/case4_error.txt | 0 tests/parser/case5.cl | 0 tests/parser/case5_error.txt | 0 tests/parser/case6.cl | 0 tests/parser/case6_error.txt | 0 tests/parser/class1.cl | 0 tests/parser/class1_error.txt | 0 tests/parser/class2.cl | 0 tests/parser/class2_error.txt | 0 tests/parser/class3.cl | 0 tests/parser/class3_error.txt | 0 tests/parser/class4.cl | 0 tests/parser/class4_error.txt | 0 tests/parser/class5.cl | 0 tests/parser/class5_error.txt | 0 tests/parser/class6.cl | 0 tests/parser/class6_error.txt | 0 tests/parser/conditional1.cl | 0 tests/parser/conditional1_error.txt | 0 tests/parser/conditional2.cl | 0 tests/parser/conditional2_error.txt | 0 tests/parser/conditional3.cl | 0 tests/parser/conditional3_error.txt | 0 tests/parser/conditional4.cl | 0 tests/parser/conditional4_error.txt | 0 tests/parser/conditional5.cl | 0 tests/parser/conditional5_error.txt | 0 tests/parser/conditional6.cl | 0 tests/parser/conditional6_error.txt | 0 tests/parser/dispatch1.cl | 0 tests/parser/dispatch1_error.txt | 0 tests/parser/dispatch2.cl | 0 tests/parser/dispatch2_error.txt | 0 tests/parser/dispatch3.cl | 0 tests/parser/dispatch3_error.txt | 0 tests/parser/dispatch4.cl | 0 tests/parser/dispatch4_error.txt | 0 tests/parser/dispatch5.cl | 0 tests/parser/dispatch5_error.txt | 0 tests/parser/dispatch6.cl | 0 tests/parser/dispatch6_error.txt | 0 tests/parser/dispatch7.cl | 0 tests/parser/dispatch7_error.txt | 0 tests/parser/dispatch8.cl | 0 tests/parser/dispatch8_error.txt | 0 tests/parser/dispatch9.cl | 0 tests/parser/dispatch9_error.txt | 0 tests/parser/let1.cl | 0 tests/parser/let1_error.txt | 0 tests/parser/let2.cl | 0 tests/parser/let2_error.txt | 0 tests/parser/let3.cl | 0 tests/parser/let3_error.txt | 0 tests/parser/let4.cl | 0 tests/parser/let4_error.txt | 0 tests/parser/let5.cl | 0 tests/parser/let5_error.txt | 0 tests/parser/let6.cl | 0 tests/parser/let6_error.txt | 0 tests/parser/let7.cl | 0 tests/parser/let7_error.txt | 0 tests/parser/loop1.cl | 0 tests/parser/loop1_error.txt | 0 tests/parser/loop2.cl | 0 tests/parser/loop2_error.txt | 0 tests/parser/loop3.cl | 0 tests/parser/loop3_error.txt | 0 tests/parser/loop4.cl | 0 tests/parser/loop4_error.txt | 0 tests/parser/method1.cl | 0 tests/parser/method1_error.txt | 0 tests/parser/method2.cl | 0 tests/parser/method2_error.txt | 0 tests/parser/method3.cl | 0 tests/parser/method3_error.txt | 0 tests/parser/method4.cl | 0 tests/parser/method4_error.txt | 0 tests/parser/method5.cl | 0 tests/parser/method5_error.txt | 0 tests/parser/method6.cl | 0 tests/parser/method6_error.txt | 0 tests/parser/mixed1.cl | 0 tests/parser/mixed1_error.txt | 0 tests/parser/mixed2.cl | 0 tests/parser/mixed2_error.txt | 0 tests/parser/mixed3.cl | 0 tests/parser/mixed3_error.txt | 0 tests/parser/mixed4.cl | 0 tests/parser/mixed4_error.txt | 0 tests/parser/mixed5.cl | 0 tests/parser/mixed5_error.txt | 0 tests/parser/mixed6.cl | 0 tests/parser/mixed6_error.txt | 0 tests/parser/operation1.cl | 0 tests/parser/operation1_error.txt | 0 tests/parser/operation2.cl | 0 tests/parser/operation2_error.txt | 0 tests/parser/operation3.cl | 0 tests/parser/operation3_error.txt | 0 tests/parser/operation4.cl | 0 tests/parser/operation4_error.txt | 0 tests/parser/program1.cl | 0 tests/parser/program1_error.txt | 0 tests/parser/program2.cl | 0 tests/parser/program2_error.txt | 0 tests/parser/program3.cl | 0 tests/parser/program3_error.txt | 0 tests/parser_test.py | 0 tests/semantic/arithmetic1.cl | 0 tests/semantic/arithmetic10.cl | 0 tests/semantic/arithmetic10_error.txt | 0 tests/semantic/arithmetic11.cl | 0 tests/semantic/arithmetic11_error.txt | 0 tests/semantic/arithmetic12.cl | 0 tests/semantic/arithmetic12_error.txt | 0 tests/semantic/arithmetic1_error.txt | 0 tests/semantic/arithmetic2.cl | 0 tests/semantic/arithmetic2_error.txt | 0 tests/semantic/arithmetic3.cl | 0 tests/semantic/arithmetic3_error.txt | 0 tests/semantic/arithmetic4.cl | 0 tests/semantic/arithmetic4_error.txt | 0 tests/semantic/arithmetic5.cl | 0 tests/semantic/arithmetic5_error.txt | 0 tests/semantic/arithmetic6.cl | 0 tests/semantic/arithmetic6_error.txt | 0 tests/semantic/arithmetic7.cl | 0 tests/semantic/arithmetic7_error.txt | 0 tests/semantic/arithmetic8.cl | 0 tests/semantic/arithmetic8_error.txt | 0 tests/semantic/arithmetic9.cl | 0 tests/semantic/arithmetic9_error.txt | 0 tests/semantic/assignment1.cl | 0 tests/semantic/assignment1_error.txt | 0 tests/semantic/assignment2.cl | 0 tests/semantic/assignment2_error.txt | 0 tests/semantic/assignment3.cl | 0 tests/semantic/assignment3_error.txt | 0 tests/semantic/attributes1.cl | 0 tests/semantic/attributes1_error.txt | 0 tests/semantic/attributes2.cl | 0 tests/semantic/attributes2_error.txt | 0 tests/semantic/attributes3.cl | 0 tests/semantic/attributes3_error.txt | 0 tests/semantic/attributes4.cl | 0 tests/semantic/attributes4_error.txt | 0 tests/semantic/basics1.cl | 0 tests/semantic/basics1_error.txt | 0 tests/semantic/basics2.cl | 0 tests/semantic/basics2_error.txt | 0 tests/semantic/basics3.cl | 0 tests/semantic/basics3_error.txt | 0 tests/semantic/basics4.cl | 0 tests/semantic/basics4_error.txt | 0 tests/semantic/basics5.cl | 0 tests/semantic/basics5_error.txt | 0 tests/semantic/basics6.cl | 0 tests/semantic/basics6_error.txt | 0 tests/semantic/basics7.cl | 0 tests/semantic/basics7_error.txt | 0 tests/semantic/basics8.cl | 0 tests/semantic/basics8_error.txt | 0 tests/semantic/blocks1.cl | 0 tests/semantic/blocks1_error.txt | 0 tests/semantic/case1.cl | 0 tests/semantic/case1_error.txt | 0 tests/semantic/case2.cl | 0 tests/semantic/case2_error.txt | 0 tests/semantic/case3.cl | 0 tests/semantic/case3_error.txt | 0 tests/semantic/class1.cl | 0 tests/semantic/class1_error.txt | 0 tests/semantic/conditionals1.cl | 0 tests/semantic/conditionals1_error.txt | 0 tests/semantic/conditionals2.cl | 0 tests/semantic/conditionals2_error.txt | 0 tests/semantic/dispatch1.cl | 0 tests/semantic/dispatch1_error.txt | 0 tests/semantic/dispatch2.cl | 0 tests/semantic/dispatch2_error.txt | 0 tests/semantic/dispatch3.cl | 0 tests/semantic/dispatch3_error.txt | 0 tests/semantic/dispatch4.cl | 0 tests/semantic/dispatch4_error.txt | 0 tests/semantic/dispatch5.cl | 0 tests/semantic/dispatch5_error.txt | 0 tests/semantic/dispatch6.cl | 0 tests/semantic/dispatch6_error.txt | 0 tests/semantic/eq1.cl | 0 tests/semantic/eq1_error.txt | 0 tests/semantic/eq2.cl | 0 tests/semantic/eq2_error.txt | 0 tests/semantic/eq3.cl | 0 tests/semantic/eq3_error.txt | 0 tests/semantic/eq4.cl | 0 tests/semantic/eq4_error.txt | 0 tests/semantic/inheritance3_error.txt | 0 tests/semantic/inheritance4_error.txt | 0 tests/semantic/inheritance5_error.txt | 0 tests/semantic/isvoid1.cl | 0 tests/semantic/isvoid1_error.txt | 0 tests/semantic/let1.cl | 0 tests/semantic/let1_error.txt | 0 tests/semantic/let2.cl | 0 tests/semantic/let2_error.txt | 0 tests/semantic/let3.cl | 0 tests/semantic/let3_error.txt | 0 tests/semantic/loops1.cl | 0 tests/semantic/loops1_error.txt | 0 tests/semantic/loops2.cl | 0 tests/semantic/loops2_error.txt | 0 tests/semantic/methods1.cl | 0 tests/semantic/methods1_error.txt | 0 tests/semantic/methods2.cl | 0 tests/semantic/methods2_error.txt | 0 tests/semantic/methods3.cl | 0 tests/semantic/methods3_error.txt | 0 tests/semantic/methods4.cl | 0 tests/semantic/methods4_error.txt | 0 tests/semantic/methods5.cl | 0 tests/semantic/methods5_error.txt | 0 tests/semantic/methods6.cl | 0 tests/semantic/methods6_error.txt | 0 tests/semantic/methods7.cl | 0 tests/semantic/methods7_error.txt | 0 tests/semantic/methods8.cl | 0 tests/semantic/methods8_error.txt | 0 tests/semantic/new1.cl | 0 tests/semantic/new1_error.txt | 0 tests/semantic/self1.cl | 0 tests/semantic/self1_error.txt | 0 tests/semantic/self2.cl | 0 tests/semantic/self2_error.txt | 0 tests/semantic/self3.cl | 0 tests/semantic/self3_error.txt | 0 tests/semantic/self4.cl | 0 tests/semantic/self4_error.txt | 0 tests/semantic_test.py | 0 tests/utils/__init__.py | 0 tests/utils/utils.py | 0 467 files changed, 3226 insertions(+), 135 deletions(-) create mode 100644 .DS_Store mode change 100644 => 100755 .github/workflows/tests.yml mode change 100644 => 100755 .gitignore create mode 100755 .ipynb_checkpoints/cp1-checkpoint.ipynb mode change 100644 => 100755 .vscode/settings.json mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Readme.md mode change 100644 => 100755 doc/Readme.md mode change 100644 => 100755 doc/cool-manual.pdf mode change 100644 => 100755 doc/github-git-cheat-sheet.pdf mode change 100644 => 100755 doc/team.yml mode change 100644 => 100755 img/img1.png mode change 100644 => 100755 img/img10.png mode change 100644 => 100755 img/img11.png mode change 100644 => 100755 img/img12.png mode change 100644 => 100755 img/img2.png mode change 100644 => 100755 img/img3.png mode change 100644 => 100755 img/img4.png mode change 100644 => 100755 img/img5.png mode change 100644 => 100755 img/img6.png mode change 100644 => 100755 img/img7.png mode change 100644 => 100755 img/img8.png mode change 100644 => 100755 img/img9.png mode change 100644 => 100755 poetry.lock mode change 100644 => 100755 pyproject.toml mode change 100644 => 100755 requirements.txt create mode 100644 src/.DS_Store mode change 100644 => 100755 src/Readme.md create mode 100755 src/assignment1.cl create mode 100644 src/cool_compiler/.DS_Store mode change 100644 => 100755 src/cool_compiler/Readme.md delete mode 100644 src/cool_compiler/__dependency.py mode change 100644 => 100755 src/cool_compiler/__init__.py mode change 100644 => 100755 src/cool_compiler/__main__.py delete mode 100644 src/cool_compiler/ast_factory.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/__init__.py mode change 100644 => 100755 src/cool_compiler/cmp/ast.py mode change 100644 => 100755 src/cool_compiler/cmp/ast_abstract_node.py mode change 100644 => 100755 src/cool_compiler/cmp/automata.py mode change 100644 => 100755 src/cool_compiler/cmp/cil.py mode change 100644 => 100755 src/cool_compiler/cmp/evaluation.py mode change 100644 => 100755 src/cool_compiler/cmp/languages.py mode change 100644 => 100755 src/cool_compiler/cmp/nbpackage.py mode change 100644 => 100755 src/cool_compiler/cmp/pycompiler.py mode change 100644 => 100755 src/cool_compiler/cmp/semantic.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/__init__.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/automata.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/evaluation.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/parsing.py mode change 100644 => 100755 src/cool_compiler/cmp/tools/regex.py mode change 100644 => 100755 src/cool_compiler/cmp/utils.py mode change 100644 => 100755 src/cool_compiler/cmp/visitor.py mode change 100644 => 100755 src/cool_compiler/codegen/__dependency.py mode change 100644 => 100755 src/cool_compiler/codegen/__init__.py mode change 100644 => 100755 src/cool_compiler/codegen/__main__.py mode change 100644 => 100755 src/cool_compiler/codegen/pipeline.py mode change 100644 => 100755 src/cool_compiler/error/__init__.py mode change 100644 => 100755 src/cool_compiler/error/error.py delete mode 100644 src/cool_compiler/grammar.py create mode 100755 src/cool_compiler/lexer/.ipynb_checkpoints/cool_lexer-checkpoint.py mode change 100644 => 100755 src/cool_compiler/lexer/__dependency.py mode change 100644 => 100755 src/cool_compiler/lexer/__init__.py mode change 100644 => 100755 src/cool_compiler/lexer/__main__.py mode change 100644 => 100755 src/cool_compiler/lexer/comment_lexer.py mode change 100644 => 100755 src/cool_compiler/lexer/cool_lexer.py mode change 100644 => 100755 src/cool_compiler/lexer/string_lexer.py mode change 100644 => 100755 src/cool_compiler/parser/__dependency.py mode change 100644 => 100755 src/cool_compiler/parser/__init__.py mode change 100644 => 100755 src/cool_compiler/parser/__main__.py create mode 100755 src/cool_compiler/parser/cool_parser.py create mode 100755 src/cool_compiler/parser/factory_decored.py create mode 100644 src/cool_compiler/semantic/.DS_Store mode change 100644 => 100755 src/cool_compiler/semantic/__dependency.py mode change 100644 => 100755 src/cool_compiler/semantic/__init__.py mode change 100644 => 100755 src/cool_compiler/semantic/__main__.py create mode 100755 src/cool_compiler/semantic/ast_print.py create mode 100755 src/cool_compiler/semantic/create_type/__init__.py create mode 100755 src/cool_compiler/semantic/create_type/main.py create mode 100755 src/cool_compiler/semantic/create_type/node__.py create mode 100755 src/cool_compiler/semantic/create_type/node_atoms.py create mode 100755 src/cool_compiler/semantic/create_type/node_binary.py create mode 100755 src/cool_compiler/semantic/create_type/node_case.py create mode 100755 src/cool_compiler/semantic/create_type/node_class.py create mode 100755 src/cool_compiler/semantic/create_type/node_defattr.py create mode 100755 src/cool_compiler/semantic/create_type/node_deffunc.py create mode 100755 src/cool_compiler/semantic/create_type/node_dispatch.py create mode 100755 src/cool_compiler/semantic/create_type/node_let.py create mode 100755 src/cool_compiler/semantic/create_type/node_program.py create mode 100755 src/cool_compiler/semantic/create_type/node_statements.py create mode 100755 src/cool_compiler/semantic/factory_node.py create mode 100755 src/cool_compiler/semantic/factory_return_ast.py create mode 100755 src/cool_compiler/semantic/scope.py create mode 100755 src/cool_compiler/semantic/semantic_checking/__init__.py create mode 100755 src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py create mode 100755 src/cool_compiler/semantic/semantic_checking/main.py create mode 100755 src/cool_compiler/semantic/semantic_checking/node__.py create mode 100755 src/cool_compiler/semantic/semantic_checking/node_class.py create mode 100755 src/cool_compiler/semantic/semantic_checking/node_program.py create mode 100755 src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py create mode 100755 src/cool_compiler/semantic/tools.py create mode 100755 src/cool_compiler/semantic/visitor.py delete mode 100644 src/cool_compiler/semantic_ast.py delete mode 100644 src/cool_compiler/table_regex.py create mode 100755 src/cool_compiler/types/__init__.py create mode 100755 src/cool_compiler/types/build_in_types/__init__.py create mode 100755 src/cool_compiler/types/build_in_types/bool.py create mode 100755 src/cool_compiler/types/build_in_types/int.py create mode 100755 src/cool_compiler/types/build_in_types/io.py create mode 100755 src/cool_compiler/types/build_in_types/object.py create mode 100755 src/cool_compiler/types/build_in_types/self.py create mode 100755 src/cool_compiler/types/build_in_types/str.py create mode 100755 src/cool_compiler/types/cool_type_build_in_manager.py create mode 100755 src/cool_compiler/types/error_type.py create mode 100755 src/cool_compiler/types/tools.py create mode 100755 src/cool_compiler/types/type.py mode change 100644 => 100755 src/makefile delete mode 100644 src/mixed2.cl delete mode 100644 src/string1.cl delete mode 100644 src/string3.cl mode change 100644 => 100755 tests/codegen/arith_input.txt mode change 100644 => 100755 tests/codegen/arith_output.txt mode change 100644 => 100755 tests/codegen/atoi.cl mode change 100644 => 100755 tests/codegen/atoi_input.txt mode change 100644 => 100755 tests/codegen/atoi_output.txt mode change 100644 => 100755 tests/codegen/book_list_input.txt mode change 100644 => 100755 tests/codegen/book_list_output.txt mode change 100644 => 100755 tests/codegen/cells_input.txt mode change 100644 => 100755 tests/codegen/cells_output.txt mode change 100644 => 100755 tests/codegen/complex_input.txt mode change 100644 => 100755 tests/codegen/complex_output.txt mode change 100644 => 100755 tests/codegen/fib.cl mode change 100644 => 100755 tests/codegen/fib_input.txt mode change 100644 => 100755 tests/codegen/fib_output.txt mode change 100644 => 100755 tests/codegen/graph_input.txt mode change 100644 => 100755 tests/codegen/graph_output.txt mode change 100644 => 100755 tests/codegen/hairyscary_input.txt mode change 100644 => 100755 tests/codegen/hairyscary_output.txt mode change 100644 => 100755 tests/codegen/hello_world_input.txt mode change 100644 => 100755 tests/codegen/hello_world_output.txt mode change 100644 => 100755 tests/codegen/io_input.txt mode change 100644 => 100755 tests/codegen/io_output.txt mode change 100644 => 100755 tests/codegen/life_input.txt mode change 100644 => 100755 tests/codegen/life_output.txt mode change 100644 => 100755 tests/codegen/list.cl mode change 100644 => 100755 tests/codegen/list_input.txt mode change 100644 => 100755 tests/codegen/list_output.txt mode change 100644 => 100755 tests/codegen/new_complex_input.txt mode change 100644 => 100755 tests/codegen/new_complex_output.txt mode change 100644 => 100755 tests/codegen/palindrome_input.txt mode change 100644 => 100755 tests/codegen/palindrome_output.txt mode change 100644 => 100755 tests/codegen/primes.cl mode change 100644 => 100755 tests/codegen/primes_input.txt mode change 100644 => 100755 tests/codegen/primes_output.txt mode change 100644 => 100755 tests/codegen/print-cool.cl mode change 100644 => 100755 tests/codegen/print-cool_input.txt mode change 100644 => 100755 tests/codegen/print-cool_output.txt mode change 100644 => 100755 tests/codegen/sort-list.cl mode change 100644 => 100755 tests/codegen/sort-list_input.txt mode change 100644 => 100755 tests/codegen/sort-list_output.txt mode change 100644 => 100755 tests/codegen_test.py mode change 100644 => 100755 tests/conftest.py mode change 100644 => 100755 tests/lexer/comment1.cl mode change 100644 => 100755 tests/lexer/comment1_error.txt mode change 100644 => 100755 tests/lexer/iis1.cl mode change 100644 => 100755 tests/lexer/iis1_error.txt mode change 100644 => 100755 tests/lexer/iis2.cl mode change 100644 => 100755 tests/lexer/iis2_error.txt mode change 100644 => 100755 tests/lexer/iis3.cl mode change 100644 => 100755 tests/lexer/iis3_error.txt mode change 100644 => 100755 tests/lexer/iis4.cl mode change 100644 => 100755 tests/lexer/iis4_error.txt mode change 100644 => 100755 tests/lexer/iis5.cl mode change 100644 => 100755 tests/lexer/iis5_error.txt mode change 100644 => 100755 tests/lexer/iis6.cl mode change 100644 => 100755 tests/lexer/iis6_error.txt mode change 100644 => 100755 tests/lexer/mixed1.cl mode change 100644 => 100755 tests/lexer/mixed1_error.txt mode change 100644 => 100755 tests/lexer/mixed2.cl mode change 100644 => 100755 tests/lexer/mixed2_error.txt mode change 100644 => 100755 tests/lexer/string1.cl mode change 100644 => 100755 tests/lexer/string1_error.txt mode change 100644 => 100755 tests/lexer/string2.cl mode change 100644 => 100755 tests/lexer/string2_error.txt mode change 100644 => 100755 tests/lexer/string3.cl mode change 100644 => 100755 tests/lexer/string3_error.txt mode change 100644 => 100755 tests/lexer/string4.cl mode change 100644 => 100755 tests/lexer/string4_error.txt mode change 100644 => 100755 tests/lexer_test.py mode change 100644 => 100755 tests/parser/assignment1.cl mode change 100644 => 100755 tests/parser/assignment1_error.txt mode change 100644 => 100755 tests/parser/assignment2.cl mode change 100644 => 100755 tests/parser/assignment2_error.txt mode change 100644 => 100755 tests/parser/assignment3.cl mode change 100644 => 100755 tests/parser/assignment3_error.txt mode change 100644 => 100755 tests/parser/attribute1.cl mode change 100644 => 100755 tests/parser/attribute1_error.txt mode change 100644 => 100755 tests/parser/attribute2.cl mode change 100644 => 100755 tests/parser/attribute2_error.txt mode change 100644 => 100755 tests/parser/attribute3.cl mode change 100644 => 100755 tests/parser/attribute3_error.txt mode change 100644 => 100755 tests/parser/block1.cl mode change 100644 => 100755 tests/parser/block1_error.txt mode change 100644 => 100755 tests/parser/block2.cl mode change 100644 => 100755 tests/parser/block2_error.txt mode change 100644 => 100755 tests/parser/block3.cl mode change 100644 => 100755 tests/parser/block3_error.txt mode change 100644 => 100755 tests/parser/block4.cl mode change 100644 => 100755 tests/parser/block4_error.txt mode change 100644 => 100755 tests/parser/case1.cl mode change 100644 => 100755 tests/parser/case1_error.txt mode change 100644 => 100755 tests/parser/case2.cl mode change 100644 => 100755 tests/parser/case2_error.txt mode change 100644 => 100755 tests/parser/case3.cl mode change 100644 => 100755 tests/parser/case3_error.txt mode change 100644 => 100755 tests/parser/case4.cl mode change 100644 => 100755 tests/parser/case4_error.txt mode change 100644 => 100755 tests/parser/case5.cl mode change 100644 => 100755 tests/parser/case5_error.txt mode change 100644 => 100755 tests/parser/case6.cl mode change 100644 => 100755 tests/parser/case6_error.txt mode change 100644 => 100755 tests/parser/class1.cl mode change 100644 => 100755 tests/parser/class1_error.txt mode change 100644 => 100755 tests/parser/class2.cl mode change 100644 => 100755 tests/parser/class2_error.txt mode change 100644 => 100755 tests/parser/class3.cl mode change 100644 => 100755 tests/parser/class3_error.txt mode change 100644 => 100755 tests/parser/class4.cl mode change 100644 => 100755 tests/parser/class4_error.txt mode change 100644 => 100755 tests/parser/class5.cl mode change 100644 => 100755 tests/parser/class5_error.txt mode change 100644 => 100755 tests/parser/class6.cl mode change 100644 => 100755 tests/parser/class6_error.txt mode change 100644 => 100755 tests/parser/conditional1.cl mode change 100644 => 100755 tests/parser/conditional1_error.txt mode change 100644 => 100755 tests/parser/conditional2.cl mode change 100644 => 100755 tests/parser/conditional2_error.txt mode change 100644 => 100755 tests/parser/conditional3.cl mode change 100644 => 100755 tests/parser/conditional3_error.txt mode change 100644 => 100755 tests/parser/conditional4.cl mode change 100644 => 100755 tests/parser/conditional4_error.txt mode change 100644 => 100755 tests/parser/conditional5.cl mode change 100644 => 100755 tests/parser/conditional5_error.txt mode change 100644 => 100755 tests/parser/conditional6.cl mode change 100644 => 100755 tests/parser/conditional6_error.txt mode change 100644 => 100755 tests/parser/dispatch1.cl mode change 100644 => 100755 tests/parser/dispatch1_error.txt mode change 100644 => 100755 tests/parser/dispatch2.cl mode change 100644 => 100755 tests/parser/dispatch2_error.txt mode change 100644 => 100755 tests/parser/dispatch3.cl mode change 100644 => 100755 tests/parser/dispatch3_error.txt mode change 100644 => 100755 tests/parser/dispatch4.cl mode change 100644 => 100755 tests/parser/dispatch4_error.txt mode change 100644 => 100755 tests/parser/dispatch5.cl mode change 100644 => 100755 tests/parser/dispatch5_error.txt mode change 100644 => 100755 tests/parser/dispatch6.cl mode change 100644 => 100755 tests/parser/dispatch6_error.txt mode change 100644 => 100755 tests/parser/dispatch7.cl mode change 100644 => 100755 tests/parser/dispatch7_error.txt mode change 100644 => 100755 tests/parser/dispatch8.cl mode change 100644 => 100755 tests/parser/dispatch8_error.txt mode change 100644 => 100755 tests/parser/dispatch9.cl mode change 100644 => 100755 tests/parser/dispatch9_error.txt mode change 100644 => 100755 tests/parser/let1.cl mode change 100644 => 100755 tests/parser/let1_error.txt mode change 100644 => 100755 tests/parser/let2.cl mode change 100644 => 100755 tests/parser/let2_error.txt mode change 100644 => 100755 tests/parser/let3.cl mode change 100644 => 100755 tests/parser/let3_error.txt mode change 100644 => 100755 tests/parser/let4.cl mode change 100644 => 100755 tests/parser/let4_error.txt mode change 100644 => 100755 tests/parser/let5.cl mode change 100644 => 100755 tests/parser/let5_error.txt mode change 100644 => 100755 tests/parser/let6.cl mode change 100644 => 100755 tests/parser/let6_error.txt mode change 100644 => 100755 tests/parser/let7.cl mode change 100644 => 100755 tests/parser/let7_error.txt mode change 100644 => 100755 tests/parser/loop1.cl mode change 100644 => 100755 tests/parser/loop1_error.txt mode change 100644 => 100755 tests/parser/loop2.cl mode change 100644 => 100755 tests/parser/loop2_error.txt mode change 100644 => 100755 tests/parser/loop3.cl mode change 100644 => 100755 tests/parser/loop3_error.txt mode change 100644 => 100755 tests/parser/loop4.cl mode change 100644 => 100755 tests/parser/loop4_error.txt mode change 100644 => 100755 tests/parser/method1.cl mode change 100644 => 100755 tests/parser/method1_error.txt mode change 100644 => 100755 tests/parser/method2.cl mode change 100644 => 100755 tests/parser/method2_error.txt mode change 100644 => 100755 tests/parser/method3.cl mode change 100644 => 100755 tests/parser/method3_error.txt mode change 100644 => 100755 tests/parser/method4.cl mode change 100644 => 100755 tests/parser/method4_error.txt mode change 100644 => 100755 tests/parser/method5.cl mode change 100644 => 100755 tests/parser/method5_error.txt mode change 100644 => 100755 tests/parser/method6.cl mode change 100644 => 100755 tests/parser/method6_error.txt mode change 100644 => 100755 tests/parser/mixed1.cl mode change 100644 => 100755 tests/parser/mixed1_error.txt mode change 100644 => 100755 tests/parser/mixed2.cl mode change 100644 => 100755 tests/parser/mixed2_error.txt mode change 100644 => 100755 tests/parser/mixed3.cl mode change 100644 => 100755 tests/parser/mixed3_error.txt mode change 100644 => 100755 tests/parser/mixed4.cl mode change 100644 => 100755 tests/parser/mixed4_error.txt mode change 100644 => 100755 tests/parser/mixed5.cl mode change 100644 => 100755 tests/parser/mixed5_error.txt mode change 100644 => 100755 tests/parser/mixed6.cl mode change 100644 => 100755 tests/parser/mixed6_error.txt mode change 100644 => 100755 tests/parser/operation1.cl mode change 100644 => 100755 tests/parser/operation1_error.txt mode change 100644 => 100755 tests/parser/operation2.cl mode change 100644 => 100755 tests/parser/operation2_error.txt mode change 100644 => 100755 tests/parser/operation3.cl mode change 100644 => 100755 tests/parser/operation3_error.txt mode change 100644 => 100755 tests/parser/operation4.cl mode change 100644 => 100755 tests/parser/operation4_error.txt mode change 100644 => 100755 tests/parser/program1.cl mode change 100644 => 100755 tests/parser/program1_error.txt mode change 100644 => 100755 tests/parser/program2.cl mode change 100644 => 100755 tests/parser/program2_error.txt mode change 100644 => 100755 tests/parser/program3.cl mode change 100644 => 100755 tests/parser/program3_error.txt mode change 100644 => 100755 tests/parser_test.py mode change 100644 => 100755 tests/semantic/arithmetic1.cl mode change 100644 => 100755 tests/semantic/arithmetic10.cl mode change 100644 => 100755 tests/semantic/arithmetic10_error.txt mode change 100644 => 100755 tests/semantic/arithmetic11.cl mode change 100644 => 100755 tests/semantic/arithmetic11_error.txt mode change 100644 => 100755 tests/semantic/arithmetic12.cl mode change 100644 => 100755 tests/semantic/arithmetic12_error.txt mode change 100644 => 100755 tests/semantic/arithmetic1_error.txt mode change 100644 => 100755 tests/semantic/arithmetic2.cl mode change 100644 => 100755 tests/semantic/arithmetic2_error.txt mode change 100644 => 100755 tests/semantic/arithmetic3.cl mode change 100644 => 100755 tests/semantic/arithmetic3_error.txt mode change 100644 => 100755 tests/semantic/arithmetic4.cl mode change 100644 => 100755 tests/semantic/arithmetic4_error.txt mode change 100644 => 100755 tests/semantic/arithmetic5.cl mode change 100644 => 100755 tests/semantic/arithmetic5_error.txt mode change 100644 => 100755 tests/semantic/arithmetic6.cl mode change 100644 => 100755 tests/semantic/arithmetic6_error.txt mode change 100644 => 100755 tests/semantic/arithmetic7.cl mode change 100644 => 100755 tests/semantic/arithmetic7_error.txt mode change 100644 => 100755 tests/semantic/arithmetic8.cl mode change 100644 => 100755 tests/semantic/arithmetic8_error.txt mode change 100644 => 100755 tests/semantic/arithmetic9.cl mode change 100644 => 100755 tests/semantic/arithmetic9_error.txt mode change 100644 => 100755 tests/semantic/assignment1.cl mode change 100644 => 100755 tests/semantic/assignment1_error.txt mode change 100644 => 100755 tests/semantic/assignment2.cl mode change 100644 => 100755 tests/semantic/assignment2_error.txt mode change 100644 => 100755 tests/semantic/assignment3.cl mode change 100644 => 100755 tests/semantic/assignment3_error.txt mode change 100644 => 100755 tests/semantic/attributes1.cl mode change 100644 => 100755 tests/semantic/attributes1_error.txt mode change 100644 => 100755 tests/semantic/attributes2.cl mode change 100644 => 100755 tests/semantic/attributes2_error.txt mode change 100644 => 100755 tests/semantic/attributes3.cl mode change 100644 => 100755 tests/semantic/attributes3_error.txt mode change 100644 => 100755 tests/semantic/attributes4.cl mode change 100644 => 100755 tests/semantic/attributes4_error.txt mode change 100644 => 100755 tests/semantic/basics1.cl mode change 100644 => 100755 tests/semantic/basics1_error.txt mode change 100644 => 100755 tests/semantic/basics2.cl mode change 100644 => 100755 tests/semantic/basics2_error.txt mode change 100644 => 100755 tests/semantic/basics3.cl mode change 100644 => 100755 tests/semantic/basics3_error.txt mode change 100644 => 100755 tests/semantic/basics4.cl mode change 100644 => 100755 tests/semantic/basics4_error.txt mode change 100644 => 100755 tests/semantic/basics5.cl mode change 100644 => 100755 tests/semantic/basics5_error.txt mode change 100644 => 100755 tests/semantic/basics6.cl mode change 100644 => 100755 tests/semantic/basics6_error.txt mode change 100644 => 100755 tests/semantic/basics7.cl mode change 100644 => 100755 tests/semantic/basics7_error.txt mode change 100644 => 100755 tests/semantic/basics8.cl mode change 100644 => 100755 tests/semantic/basics8_error.txt mode change 100644 => 100755 tests/semantic/blocks1.cl mode change 100644 => 100755 tests/semantic/blocks1_error.txt mode change 100644 => 100755 tests/semantic/case1.cl mode change 100644 => 100755 tests/semantic/case1_error.txt mode change 100644 => 100755 tests/semantic/case2.cl mode change 100644 => 100755 tests/semantic/case2_error.txt mode change 100644 => 100755 tests/semantic/case3.cl mode change 100644 => 100755 tests/semantic/case3_error.txt mode change 100644 => 100755 tests/semantic/class1.cl mode change 100644 => 100755 tests/semantic/class1_error.txt mode change 100644 => 100755 tests/semantic/conditionals1.cl mode change 100644 => 100755 tests/semantic/conditionals1_error.txt mode change 100644 => 100755 tests/semantic/conditionals2.cl mode change 100644 => 100755 tests/semantic/conditionals2_error.txt mode change 100644 => 100755 tests/semantic/dispatch1.cl mode change 100644 => 100755 tests/semantic/dispatch1_error.txt mode change 100644 => 100755 tests/semantic/dispatch2.cl mode change 100644 => 100755 tests/semantic/dispatch2_error.txt mode change 100644 => 100755 tests/semantic/dispatch3.cl mode change 100644 => 100755 tests/semantic/dispatch3_error.txt mode change 100644 => 100755 tests/semantic/dispatch4.cl mode change 100644 => 100755 tests/semantic/dispatch4_error.txt mode change 100644 => 100755 tests/semantic/dispatch5.cl mode change 100644 => 100755 tests/semantic/dispatch5_error.txt mode change 100644 => 100755 tests/semantic/dispatch6.cl mode change 100644 => 100755 tests/semantic/dispatch6_error.txt mode change 100644 => 100755 tests/semantic/eq1.cl mode change 100644 => 100755 tests/semantic/eq1_error.txt mode change 100644 => 100755 tests/semantic/eq2.cl mode change 100644 => 100755 tests/semantic/eq2_error.txt mode change 100644 => 100755 tests/semantic/eq3.cl mode change 100644 => 100755 tests/semantic/eq3_error.txt mode change 100644 => 100755 tests/semantic/eq4.cl mode change 100644 => 100755 tests/semantic/eq4_error.txt mode change 100644 => 100755 tests/semantic/inheritance3_error.txt mode change 100644 => 100755 tests/semantic/inheritance4_error.txt mode change 100644 => 100755 tests/semantic/inheritance5_error.txt mode change 100644 => 100755 tests/semantic/isvoid1.cl mode change 100644 => 100755 tests/semantic/isvoid1_error.txt mode change 100644 => 100755 tests/semantic/let1.cl mode change 100644 => 100755 tests/semantic/let1_error.txt mode change 100644 => 100755 tests/semantic/let2.cl mode change 100644 => 100755 tests/semantic/let2_error.txt mode change 100644 => 100755 tests/semantic/let3.cl mode change 100644 => 100755 tests/semantic/let3_error.txt mode change 100644 => 100755 tests/semantic/loops1.cl mode change 100644 => 100755 tests/semantic/loops1_error.txt mode change 100644 => 100755 tests/semantic/loops2.cl mode change 100644 => 100755 tests/semantic/loops2_error.txt mode change 100644 => 100755 tests/semantic/methods1.cl mode change 100644 => 100755 tests/semantic/methods1_error.txt mode change 100644 => 100755 tests/semantic/methods2.cl mode change 100644 => 100755 tests/semantic/methods2_error.txt mode change 100644 => 100755 tests/semantic/methods3.cl mode change 100644 => 100755 tests/semantic/methods3_error.txt mode change 100644 => 100755 tests/semantic/methods4.cl mode change 100644 => 100755 tests/semantic/methods4_error.txt mode change 100644 => 100755 tests/semantic/methods5.cl mode change 100644 => 100755 tests/semantic/methods5_error.txt mode change 100644 => 100755 tests/semantic/methods6.cl mode change 100644 => 100755 tests/semantic/methods6_error.txt mode change 100644 => 100755 tests/semantic/methods7.cl mode change 100644 => 100755 tests/semantic/methods7_error.txt mode change 100644 => 100755 tests/semantic/methods8.cl mode change 100644 => 100755 tests/semantic/methods8_error.txt mode change 100644 => 100755 tests/semantic/new1.cl mode change 100644 => 100755 tests/semantic/new1_error.txt mode change 100644 => 100755 tests/semantic/self1.cl mode change 100644 => 100755 tests/semantic/self1_error.txt mode change 100644 => 100755 tests/semantic/self2.cl mode change 100644 => 100755 tests/semantic/self2_error.txt mode change 100644 => 100755 tests/semantic/self3.cl mode change 100644 => 100755 tests/semantic/self3_error.txt mode change 100644 => 100755 tests/semantic/self4.cl mode change 100644 => 100755 tests/semantic/self4_error.txt mode change 100644 => 100755 tests/semantic_test.py mode change 100644 => 100755 tests/utils/__init__.py mode change 100644 => 100755 tests/utils/utils.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..feca8613504bcd7430524202412f605a970dd548 GIT binary patch literal 6148 zcmeH~JqiLr422VS3&Cbf%V|7-HyA`u-~~i21wpZ&qx41vI)z6#m+=T zbn`f`MFtU>!%bynVPcAXCwIBY>3lz3j@RpDteEA>YT$!Ro{xoGkN^pg011!)3H%HJ zJGWu;MJOW)kN^pc1nmD%;HEXTh5D}p!AAgSkF*=sK1)E0C7?C6g(3sfXoW_r`WRw) zZ-`o{NKSp&Hs}YZb^Uy{)~Y3 z+x>QfkIJ+4?ei>u$gHg!9O~r=FP8vp>?mHs-SE8F0$NjBC^9f!1RMhc34E2n6Mwc5 Aa{vGU literal 0 HcmV?d00001 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 old mode 100644 new mode 100755 index 993b38259..96175924b --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "python.pythonPath": "/home/dany/.cache/pypoetry/virtualenvs/cmp-Jp0snq0--py3.8/bin/python" + "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/Readme.md b/Readme.md old mode 100644 new mode 100755 diff --git a/doc/Readme.md b/doc/Readme.md old mode 100644 new mode 100755 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/team.yml b/doc/team.yml old mode 100644 new mode 100755 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/poetry.lock b/poetry.lock old mode 100644 new mode 100755 diff --git a/pyproject.toml b/pyproject.toml old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b58e639020e253f13bf76630db33ea7aeb12743e GIT binary patch literal 6148 zcmeHKyGjH>5Ukb<4&>lM!}$gOU^vb%xDQagGZ0o*6!VSzE16*hOWGNas85aKwmbyx?h3eLmsbO|V7`GyZ@_ zyq?~U!^1cZ=gG=S0VyB_q<|EV0>4(kdoOK$m8d8Mq<|FoR=~dxjqcbBr^NVlFvJKz zTrnNSb<7gP<_TgioD!L#SyG8fwHh%j>CCsP>xENd(qT1xSe-s{PNGRkxxc_4tfKG*`~Z+pAOS%-DCn-@yZAK54-nA>QPH5W?eJ=npi0y1*Cu!kOETRHwD&x|uuT;Ht_Hy298~uvzG4FIY q?jwauv}0nlV;;O6pG8o{HQ)1jFPsu1oqVJd^)ukQ$fUquEARnuNE;pi literal 0 HcmV?d00001 diff --git a/src/cool_compiler/Readme.md b/src/cool_compiler/Readme.md old mode 100644 new mode 100755 diff --git a/src/cool_compiler/__dependency.py b/src/cool_compiler/__dependency.py deleted file mode 100644 index 5a43b46bc..000000000 --- a/src/cool_compiler/__dependency.py +++ /dev/null @@ -1 +0,0 @@ -from .ast_factory import AstFactory as Factory \ No newline at end of file diff --git a/src/cool_compiler/__init__.py b/src/cool_compiler/__init__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py old mode 100644 new mode 100755 index 168c74401..71d9b5fc7 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -1,6 +1,9 @@ import sys from .error import CoolError from .lexer import CoolLexer +from .parser import CoolParser +from .semantic import * +from .types import CoolTypeBuildInManager path = "" if len(sys.argv) > 1: @@ -11,6 +14,22 @@ text = _file.read() errors = CoolError(text) lexer = CoolLexer(errors) + CoolTypeBuildInManager() + parser = CoolParser(CoolFactory(errors), errors) + tokens = [token for token in lexer.tokenize(text)] - if errors.any(): sys.exit(1) \ No newline at end of file + if errors.any(): sys.exit(1) + + ast = parser.parse(iter(tokens)) + if errors.any(): sys.exit(1) + + visitorList = [ CreateType ] + + for visitorClass in visitorList: + ast = visitorClass(errors).visit(ast) + if errors.any(): sys.exit(1) + + + + diff --git a/src/cool_compiler/ast_factory.py b/src/cool_compiler/ast_factory.py deleted file mode 100644 index 917027705..000000000 --- a/src/cool_compiler/ast_factory.py +++ /dev/null @@ -1,24 +0,0 @@ -from enum import Enum - -class KeyNameNode(Enum): - kclass = "class" - -# interface to create ast nodes -# and decouple the grammar of these nodes -class AstFactory: - def __init__(self, dict_knn_ast_node : dict = {}): - self.__dict = dict_knn_ast_node - - def __call__(self, key_name_node : str ) : - return self.Builder(key_name_node, self.__dict) - - class Builder: - def __init__(self, knn, dicc): - self.knn = knn - self.dicc = dicc - - # synteticed is a list with tokens and nodes - def build(self, synteticed_list : list): - return self.dicc[self.knn](synteticed_list) - - diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/ast-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/automata-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/languages-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/nbpackage-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/pycompiler-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/tools-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/utils-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py b/src/cool_compiler/cmp/.ipynb_checkpoints/visitor-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/__init__.py b/src/cool_compiler/cmp/__init__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/ast.py b/src/cool_compiler/cmp/ast.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/ast_abstract_node.py b/src/cool_compiler/cmp/ast_abstract_node.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/automata.py b/src/cool_compiler/cmp/automata.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/cil.py b/src/cool_compiler/cmp/cil.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/evaluation.py b/src/cool_compiler/cmp/evaluation.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/languages.py b/src/cool_compiler/cmp/languages.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/nbpackage.py b/src/cool_compiler/cmp/nbpackage.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/pycompiler.py b/src/cool_compiler/cmp/pycompiler.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/semantic.py b/src/cool_compiler/cmp/semantic.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/__init__-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/automata-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/evaluation-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py b/src/cool_compiler/cmp/tools/.ipynb_checkpoints/parsing-checkpoint.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/__init__.py b/src/cool_compiler/cmp/tools/__init__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/automata.py b/src/cool_compiler/cmp/tools/automata.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/evaluation.py b/src/cool_compiler/cmp/tools/evaluation.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/parsing.py b/src/cool_compiler/cmp/tools/parsing.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/tools/regex.py b/src/cool_compiler/cmp/tools/regex.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/utils.py b/src/cool_compiler/cmp/utils.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/cmp/visitor.py b/src/cool_compiler/cmp/visitor.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/codegen/__dependency.py b/src/cool_compiler/codegen/__dependency.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/codegen/__init__.py b/src/cool_compiler/codegen/__init__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/codegen/__main__.py b/src/cool_compiler/codegen/__main__.py old mode 100644 new mode 100755 index c986d5f81..e69de29bb --- a/src/cool_compiler/codegen/__main__.py +++ b/src/cool_compiler/codegen/__main__.py @@ -1 +0,0 @@ -print("aaaaaa") \ No newline at end of file diff --git a/src/cool_compiler/codegen/pipeline.py b/src/cool_compiler/codegen/pipeline.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/error/__init__.py b/src/cool_compiler/error/__init__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/error/error.py b/src/cool_compiler/error/error.py old mode 100644 new mode 100755 index 84b16373d..18568ad70 --- a/src/cool_compiler/error/error.py +++ b/src/cool_compiler/error/error.py @@ -14,16 +14,37 @@ def any(self): 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 + 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): + 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/grammar.py b/src/cool_compiler/grammar.py deleted file mode 100644 index b98306422..000000000 --- a/src/cool_compiler/grammar.py +++ /dev/null @@ -1,2 +0,0 @@ -from .__dependency import Factory - 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 old mode 100644 new mode 100755 index e69de29bb..6a747410d --- a/src/cool_compiler/lexer/__dependency.py +++ 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 old mode 100644 new mode 100755 diff --git a/src/cool_compiler/lexer/__main__.py b/src/cool_compiler/lexer/__main__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/lexer/comment_lexer.py b/src/cool_compiler/lexer/comment_lexer.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/lexer/cool_lexer.py b/src/cool_compiler/lexer/cool_lexer.py old mode 100644 new mode 100755 index 9db74947b..034d36093 --- a/src/cool_compiler/lexer/cool_lexer.py +++ b/src/cool_compiler/lexer/cool_lexer.py @@ -1,8 +1,8 @@ -from typing import ClassVar 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: @@ -17,72 +17,47 @@ def __init__(self, error=None) -> None: CASE, OF, ESAC, ISVOID, NEW, NOT, TRUE, FALSE, - ID, NUMBER, - TWOPOINT, ARROW, OPENKEY, CLOSEKEY, ATSING, POINT, COLON, SEMICOL, LOGICAR, - EQUAL, LESS_OR, LESS, - COMPLEM, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, + ID, NUMBER, TYPE, + ARROW, LOGICAR, LESS_OR, STRING } - ignore = r' \t' + literals = { + '{','}', '@', '.', ',', ';', + '=', '<', '~', '+', '-', + '*', '/', '(', ')', ':', + } + + ignore = r' ' + ignore_tab = r'\t' ignore_comment = r'\(\*' ignore_newline = r'\n' ignore_line = r'--.*\n' - CLASS = r'class' - INHERITS= r'inherits' - - IF = r'if' - THEN = r'then' - ELSE = r'else' - FI = r'fi' - - LET = r'let' - IN = r'in' - - - WHILE = r'while' - LOOP = r'loop' - POOL = r'pool' - - CASE = r'case' - OF = r'of' - ESAC = r'esac' - - ISVOID = r'isvoid' - NEW = r'new' - NOT = r'not' - - TRUE = r'true' - FALSE = r'false' - + 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+' - - TWOPOINT= r':' ARROW = r'<-' - OPENKEY = r'{' - CLOSEKEY= r'}' - ATSING = r'@' - POINT = r'\.' - COLON = r',' - SEMICOL = r';' LOGICAR = r'=>' - - EQUAL = r'=' LESS_OR = r'<=' - LESS = r'<' - - COMPLEM = r'~' - PLUS = r'\+' - MINUS = r'-' - TIMES = r'\*' - DIVIDE = r'/' - LPAREN = r'\(' - RPAREN = 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 diff --git a/src/cool_compiler/lexer/string_lexer.py b/src/cool_compiler/lexer/string_lexer.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/parser/__dependency.py b/src/cool_compiler/parser/__dependency.py old mode 100644 new mode 100755 index e69de29bb..5cea93ba9 --- a/src/cool_compiler/parser/__dependency.py +++ 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 old mode 100644 new mode 100755 index e69de29bb..be490ce94 --- a/src/cool_compiler/parser/__init__.py +++ 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 old mode 100644 new mode 100755 diff --git a/src/cool_compiler/parser/cool_parser.py b/src/cool_compiler/parser/cool_parser.py new file mode 100755 index 000000000..31a5e87ae --- /dev/null +++ b/src/cool_compiler/parser/cool_parser.py @@ -0,0 +1,285 @@ +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', '@'), + ('left', '~'), + ('right', 'IN'), + ) + 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.expr, prod.case_list) + + @_('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 0000000000000000000000000000000000000000..5359494b5f2614eedd1b0c588b55e236d72530a8 GIT binary patch literal 6148 zcmeHKF-`+P3>-s>NNGYxxnJN1rzpID2L!l8fCx!MLP2*O-)8JJBFBZ60*xi_oV}i1 z-85bUu-V)43YY>I(;e~Q%g}t^ePCyqakMz&fE5-v;2pa`_34CjCus3X<{g>e{MB;b zuJ5if z7B};pyxDR>vACW266LU_qE;y&1^Nn{*Kq3n|C;{G{NE=jk^)lTUnyXt`OSRBU&`J( w_&M*jg?>x_GS)^pm);|Qfw$tzqq^eXtZNdxia}>S=tMmPTo;)X_zML-0UN*{ssI20 literal 0 HcmV?d00001 diff --git a/src/cool_compiler/semantic/__dependency.py b/src/cool_compiler/semantic/__dependency.py old mode 100644 new mode 100755 index e69de29bb..09c1f85e6 --- a/src/cool_compiler/semantic/__dependency.py +++ b/src/cool_compiler/semantic/__dependency.py @@ -0,0 +1,12 @@ +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 diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py old mode 100644 new mode 100755 index e69de29bb..5949b98c0 --- a/src/cool_compiler/semantic/__init__.py +++ b/src/cool_compiler/semantic/__init__.py @@ -0,0 +1,2 @@ +from .factory_node import CoolFactory +from .create_type import CoolCreateType as CreateType \ No newline at end of file diff --git a/src/cool_compiler/semantic/__main__.py b/src/cool_compiler/semantic/__main__.py old mode 100644 new mode 100755 diff --git a/src/cool_compiler/semantic/ast_print.py b/src/cool_compiler/semantic/ast_print.py new file mode 100755 index 000000000..643c33754 --- /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 . 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/create_type/__init__.py b/src/cool_compiler/semantic/create_type/__init__.py new file mode 100755 index 000000000..2ba994f35 --- /dev/null +++ b/src/cool_compiler/semantic/create_type/__init__.py @@ -0,0 +1,8 @@ +from .main import CoolCreateType + +from .main import Program, CoolClass, AtrDef, FuncDef +from .main import StaticDispatch, CastingDispatch, Dispatch +from .main import Assing, IfThenElse, While, Block, LetIn, Case +from .main import Sum, Rest, Div, Mult, Less, LessOrEquals, Equals +from .main import New, Void, Neg, Complement, Id, Int, Str, Bool + diff --git a/src/cool_compiler/semantic/create_type/main.py b/src/cool_compiler/semantic/create_type/main.py new file mode 100755 index 000000000..acea5f7d7 --- /dev/null +++ b/src/cool_compiler/semantic/create_type/main.py @@ -0,0 +1,79 @@ +from .. import visitor +from ..__dependency import Type +from ..tools import VisitorBase +from .node_program import Program, VisitProgram, AST_Program +from .node_class import CoolClass, VisitCoolClass, AST_CoolClass +from .node_defattr import AtrDef, VisitAttrDef, AST_AtrDef +from .node_deffunc import FuncDef, VisitFuncDef, AST_FuncDef + +from .node_dispatch import CastingDispatch, VisitCastingDispatch, AST_CastingDispatch +from .node_dispatch import Dispatch, VisitDispatch, AST_Dispatch +from .node_dispatch import StaticDispatch, VisitStaticDispatch, AST_StaticDispatch + +from .node_statements import Assing, VisitAssing, AST_Assing +from .node_statements import IfThenElse, VisitIfThenElse, AST_IfThenElse +from .node_statements import While, VisitWhile, AST_While +from .node_statements import Block, VisitBlock, AST_Block +from .node_let import LetIn, VisitLetIn, AST_LetIn +from .node_case import Case, VisitCase, AST_Case + +from .node_binary import Sum, AST_Sum, VisitBinary +from .node_binary import Rest, AST_Rest +from .node_binary import Div, AST_Div +from .node_binary import Mult, AST_Mult +from .node_binary import Less, AST_Less +from .node_binary import LessOrEquals, AST_LessOrEquals +from .node_binary import Equals, AST_Equals + +from .node_atoms import Void, AST_Void, VisitAtomic +from .node_atoms import Neg, AST_Neg +from .node_atoms import Complement, AST_Complement +from .node_atoms import New, AST_New, VisitNew +from .node_atoms import Id, AST_Id, VisitEqualAtomic +from .node_atoms import Int, AST_Int +from .node_atoms import Str, AST_Str +from .node_atoms import Bool, AST_Bool + + +class CoolCreateType(VisitorBase): + @visitor.add(node_type= AST_Program, accion_class= VisitProgram, result= Program) + #class def + @visitor.add(node_type= AST_CoolClass, accion_class= VisitCoolClass, result= CoolClass) + @visitor.add(node_type= AST_AtrDef, accion_class= VisitAttrDef, result= AtrDef) + @visitor.add(node_type= AST_FuncDef, accion_class= VisitFuncDef, result= FuncDef) + # expr dispatch + @visitor.add(node_type= AST_CastingDispatch, accion_class= VisitCastingDispatch, result= CastingDispatch) + @visitor.add(node_type= AST_Dispatch, accion_class= VisitDispatch, result= Dispatch) + @visitor.add(node_type= AST_StaticDispatch, accion_class= VisitStaticDispatch, result= StaticDispatch) + # expr statement + @visitor.add(node_type= AST_Assing, accion_class= VisitAssing, result= Assing) + @visitor.add(node_type= AST_IfThenElse, accion_class= VisitIfThenElse, result= IfThenElse) + @visitor.add(node_type= AST_While, accion_class= VisitWhile, result= While) + @visitor.add(node_type= AST_Block, accion_class= VisitBlock, result= Block) + @visitor.add(node_type= AST_LetIn, accion_class= VisitLetIn, result= LetIn) + @visitor.add(node_type= AST_Case, accion_class= VisitCase, result= Case) + # expr binary + @visitor.add(node_type= AST_Sum, accion_class= VisitBinary, result= Sum) + @visitor.add(node_type= AST_Rest, accion_class= VisitBinary, result= Rest) + @visitor.add(node_type= AST_Div, accion_class= VisitBinary, result= Div) + @visitor.add(node_type= AST_Mult, accion_class= VisitBinary, result= Mult) + @visitor.add(node_type= AST_Less, accion_class= VisitBinary, result= Less) + @visitor.add(node_type= AST_LessOrEquals, accion_class= VisitBinary, result= LessOrEquals) + @visitor.add(node_type= AST_Equals, accion_class= VisitBinary, result= Equals) + # expr atomic + @visitor.add(node_type= AST_New, accion_class= VisitNew, result= New) + @visitor.add(node_type= AST_Neg, accion_class= VisitAtomic, result= Neg) + @visitor.add(node_type= AST_Complement, accion_class= VisitAtomic, result= Complement) + @visitor.add(node_type= AST_Void, accion_class= VisitAtomic, result= Void) + @visitor.add(node_type= AST_Id, accion_class= VisitEqualAtomic, result= Id) + @visitor.add(node_type= AST_Int, accion_class= VisitEqualAtomic, result= Int) + @visitor.add(node_type= AST_Str, accion_class= VisitEqualAtomic, result= Str) + @visitor.add(node_type= AST_Bool, accion_class= VisitEqualAtomic, result= Bool) + + def __init__(self, errors) -> None: + super().__init__(errors) + self.global_types = {} + + @visitor.on("node") + def visit(node): + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node__.py b/src/cool_compiler/semantic/create_type/node__.py new file mode 100755 index 000000000..99346437a --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node__.py @@ -0,0 +1,13 @@ +class Node: + def get_pos_to_error(self, lineno, index): + self.lineno = lineno + self.index = index + +class Feature(Node): + pass + +class Expresion(Node): + pass + +class Statement(Expresion): + pass diff --git a/src/cool_compiler/semantic/create_type/node_atoms.py b/src/cool_compiler/semantic/create_type/node_atoms.py new file mode 100755 index 000000000..2d0ebff8a --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_atoms.py @@ -0,0 +1,53 @@ +from .node__ import Expresion +from ..tools import defVisitClass +from ..factory_return_ast import Void as AST_Void +from ..factory_return_ast import New as AST_New +from ..factory_return_ast import Complement as AST_Complement +from ..factory_return_ast import Neg as AST_Neg +from ..factory_return_ast import Id as AST_Id +from ..factory_return_ast import Int as AST_Int +from ..factory_return_ast import Str as AST_Str +from ..factory_return_ast import Bool as AST_Bool + +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 + +VisitAtomic = defVisitClass( + lambda self, node, error: self.gclss.visit(node.item), +) + +VisitNew = defVisitClass( + lambda self, node, error: self.get_type(node.item, error), +) + +VisitEqualAtomic = defVisitClass( + lambda self, node, error: node.item, +) + + + diff --git a/src/cool_compiler/semantic/create_type/node_binary.py b/src/cool_compiler/semantic/create_type/node_binary.py new file mode 100755 index 000000000..d70e994cb --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_binary.py @@ -0,0 +1,40 @@ +from .node__ import Expresion +from ..tools import defVisitClass +from ..factory_return_ast import Sum as AST_Sum +from ..factory_return_ast import Rest as AST_Rest +from ..factory_return_ast import Div as AST_Div +from ..factory_return_ast import Mult as AST_Mult +from ..factory_return_ast import Less as AST_Less +from ..factory_return_ast import LessOrEquals as AST_LessOrEquals +from ..factory_return_ast import Equals as AST_Equals + +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 + +VisitBinary = defVisitClass( + lambda self, node, error: self.gclss.visit(node.left), + lambda self, node, error: self.gclss.visit(node.right), +) \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_case.py b/src/cool_compiler/semantic/create_type/node_case.py new file mode 100755 index 000000000..1e68c74ff --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_case.py @@ -0,0 +1,20 @@ +from .node__ import Statement +from ..tools import VisitBase +from ..factory_return_ast import Case as AST_Case + +class Case(Statement): + def __init__(self, expr, case_list) -> None: + self.case_list = case_list + self.expr = expr + +class VisitCase(VisitBase): + def visit(self, node : AST_Case) : + error_handler = self.gclss.get_se_handler(node) + + case_list = [] + for name, atype, expr in node.case_list: + rtype = self.get_type(atype, error_handler) + case_list.append((name, rtype, self.gclss.visit(expr))) + + return self.gclss.visit(node.expr), case_list + diff --git a/src/cool_compiler/semantic/create_type/node_class.py b/src/cool_compiler/semantic/create_type/node_class.py new file mode 100755 index 000000000..d0a4949aa --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_class.py @@ -0,0 +1,39 @@ +from .node__ import Node +from ..__dependency import Type, Object, SemanticError, ErrorType +from ..tools import VisitBase, find_type +from ..factory_return_ast import CoolClass as AST_CoolClass + +class CoolClass(Node): + def __init__(self, typee, parent_typee, feature_list) -> None: + self.type : Type = typee + self.parent_type : Type = parent_typee + self.feature_list = feature_list + +class VisitCoolClass(VisitBase): + def visit(self, node : AST_CoolClass) : + self.gclss.current_type = self.gclss.global_types[node.name] + error_handler = self.gclss.get_se_handler(node) + + parent_type = self.get_parent_type(node, error_handler) + try: self.gclss.current_type.set_parent(parent_type) + except SemanticError: pass + + feature_list = self.visit_all(node.feature_list) + + return self.gclss.current_type, parent_type, feature_list + + + def get_parent_type(self, node : AST_CoolClass, error_handler): + if node.parent is None: return Object() + + find_result = find_type(node.parent, self.gclss.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.gclss.current_type.name: + error_handler().add_semantic_error( f"class {self.gclss.current_type.name} can't be inherited from {parent_type.name}" ) + return ErrorType() + + return parent_type + + + \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_defattr.py b/src/cool_compiler/semantic/create_type/node_defattr.py new file mode 100755 index 000000000..92d03c68e --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_defattr.py @@ -0,0 +1,25 @@ +from .node__ import Feature +from ..__dependency import Type, Object, SemanticError, ErrorType +from ..tools import VisitBase, find_type +from ..factory_return_ast import AtrDef as AST_AtrDef + +class AtrDef(Feature): + def __init__(self, name, atype, expr) -> None: + self.name = name + self.type = atype + self.expr = expr + +class VisitAttrDef(VisitBase): + def visit(self, node : AST_AtrDef) : + error_handler = self.gclss.get_se_handler(node) + + atype = self.get_type(node.type, error_handler) + self.gclss.current_type.define_attribute(node.name, atype) + + expr = self.gclss.visit(node.expr) + return node.name, atype, expr + + + + + \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_deffunc.py b/src/cool_compiler/semantic/create_type/node_deffunc.py new file mode 100755 index 000000000..292a72e0c --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_deffunc.py @@ -0,0 +1,26 @@ +from .node__ import Feature +from ..__dependency import Type, Object, SemanticError, ErrorType +from ..tools import VisitBase, find_type +from ..factory_return_ast import FuncDef as AST_FuncDef + +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 VisitFuncDef(VisitBase): + def visit(self, node : AST_FuncDef) : + error_handler = self.gclss.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)) + + self.gclss.current_type.define_method(node.name, params, return_type) + expr = self.gclss.visit(node.expr) + return node.name, params, return_type, expr \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_dispatch.py b/src/cool_compiler/semantic/create_type/node_dispatch.py new file mode 100755 index 000000000..319bec5ed --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_dispatch.py @@ -0,0 +1,51 @@ +from .node__ import Expresion +from ..tools import defVisitClass +from ..factory_return_ast import CastingDispatch as AST_CastingDispatch +from ..factory_return_ast import StaticDispatch as AST_StaticDispatch +from ..factory_return_ast import Dispatch as AST_Dispatch + + +class CastingDispatch(Expresion): + def __init__(self, expr, atype, idf, params) -> None: + self.expr = expr + self.type = atype + self.id = idf + self.params = params + +VisitCastingDispatch = defVisitClass( + lambda self, node, error: self.gclss.visit(node.expr), + lambda self, node, error: self.get_type(node.type, error), + lambda self, node, error: node.id, + lambda self, node, error: self.visit_all(node.params), +) +############################################################################## + +class Dispatch(Expresion): + def __init__(self, expr, idf, params) -> None: + self.expr = expr + self.id = idf + self.params = params + +VisitDispatch = defVisitClass( + lambda self, node, error: self.gclss.visit(node.expr), + lambda self, node, error: node.id, + lambda self, node, error: self.visit_all(node.params), +) + +############################################################################### +class StaticDispatch(Expresion): + def __init__(self, idf, params) -> None: + self.id = idf + self.params = params + +VisitStaticDispatch = defVisitClass( + lambda self, node, error: node.id, + lambda self, node, error: self.visit_all(node.params), +) + + + + + + + diff --git a/src/cool_compiler/semantic/create_type/node_let.py b/src/cool_compiler/semantic/create_type/node_let.py new file mode 100755 index 000000000..acd9e178a --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_let.py @@ -0,0 +1,23 @@ +from .node__ import Statement +from ..tools import VisitBase +from ..factory_return_ast import LetIn as AST_LetIn + +class LetIn(Statement): + def __init__(self, assing_list, expr) -> None: + self.assing_list = assing_list + self.expr = expr + +class VisitLetIn(VisitBase): + def visit(self, node : AST_LetIn) : + error_handler = self.gclss.get_se_handler(node) + + assing_list = [] + for name, atype, expr in node.assing_list: + rtype = self.get_type(atype, error_handler) + assing_list.append((name, rtype, self.gclss.visit(expr))) + + return assing_list, self.gclss.visit(node.expr) + + + + \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_program.py b/src/cool_compiler/semantic/create_type/node_program.py new file mode 100755 index 000000000..94ec98624 --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_program.py @@ -0,0 +1,19 @@ +from .node__ import Node +from ..__dependency import Type +from ..tools import VisitBase +from ..factory_return_ast import Program as AST_Program + +class Program(Node): + def __init__(self, class_list) -> None: + self.class_list = class_list + +class VisitProgram(VisitBase): + def visit(self, node : AST_Program) : + for name, lineno, index in node.names_list: + if name in self.gclss.global_types: + self.gclss.cool_error(lineno, index) + self.gclss.cool_error.add_semantic_error(f"{name} is already defined") + else: self.gclss.global_types[name] = Type(name) + + class_list = self.visit_all(node.class_list) + return class_list, diff --git a/src/cool_compiler/semantic/create_type/node_statements.py b/src/cool_compiler/semantic/create_type/node_statements.py new file mode 100755 index 000000000..5ec8dd626 --- /dev/null +++ b/src/cool_compiler/semantic/create_type/node_statements.py @@ -0,0 +1,49 @@ +from .node__ import Statement +from ..tools import defVisitClass +from ..factory_return_ast import Assing as AST_Assing +from ..factory_return_ast import IfThenElse as AST_IfThenElse +from ..factory_return_ast import While as AST_While +from ..factory_return_ast import Block as AST_Block + +class Assing(Statement): + def __init__(self, name, expr) -> None: + self.id = name + self.expr = expr + +VisitAssing = defVisitClass( + lambda self, node, error: node.id, + lambda self, node, error: self.gclss.visit(node.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 + +VisitIfThenElse = defVisitClass( + lambda self, node, error: self.gclss.visit(node.condition), + lambda self, node, error: self.gclss.visit(node.then_expr), + lambda self, node, error: self.gclss.visit(node.else_expr), +) + +############################################################################### +class While(Statement): + def __init__(self, condition, loop_expr) -> None: + self.condition = condition + self.loop_expr = loop_expr + +VisitWhile = defVisitClass( + lambda self, node, error: self.gclss.visit(node.condition), + lambda self, node, error: self.gclss.visit(node.loop_expr), +) + +############################################################################### +class Block(Statement): + def __init__(self, expr_list) -> None: + self.expr_list = expr_list + +VisitBlock = defVisitClass( + lambda self, node, error: self.visit_all(node.expr_list), +) \ No newline at end of file diff --git a/src/cool_compiler/semantic/factory_node.py b/src/cool_compiler/semantic/factory_node.py new file mode 100755 index 000000000..71d89f231 --- /dev/null +++ b/src/cool_compiler/semantic/factory_node.py @@ -0,0 +1,166 @@ +from .__dependency import factory, decored, Nodes +from .factory_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/factory_return_ast.py b/src/cool_compiler/semantic/factory_return_ast.py new file mode 100755 index 000000000..c1a62c21e --- /dev/null +++ b/src/cool_compiler/semantic/factory_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/scope.py b/src/cool_compiler/semantic/scope.py new file mode 100755 index 000000000..a8269368f --- /dev/null +++ b/src/cool_compiler/semantic/scope.py @@ -0,0 +1,43 @@ +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.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,): + child = Scope(self) + 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): + 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/semantic/semantic_checking/__init__.py b/src/cool_compiler/semantic/semantic_checking/__init__.py new file mode 100755 index 000000000..2ba994f35 --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/__init__.py @@ -0,0 +1,8 @@ +from .main import CoolCreateType + +from .main import Program, CoolClass, AtrDef, FuncDef +from .main import StaticDispatch, CastingDispatch, Dispatch +from .main import Assing, IfThenElse, While, Block, LetIn, Case +from .main import Sum, Rest, Div, Mult, Less, LessOrEquals, Equals +from .main import New, Void, Neg, Complement, Id, Int, Str, Bool + diff --git a/src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py b/src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py new file mode 100755 index 000000000..4e4672d73 --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py @@ -0,0 +1,160 @@ +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 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 + + diff --git a/src/cool_compiler/semantic/semantic_checking/main.py b/src/cool_compiler/semantic/semantic_checking/main.py new file mode 100755 index 000000000..5b922325c --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/main.py @@ -0,0 +1,77 @@ +from .. import visitor +from ..__dependency import Type +from ..tools import VisitorBase, +from .node_program import Program, VisitProgram, AST_Program +from .node_class import CoolClass, VisitCoolClass, AST_CoolClass +from .node_defattr import AtrDef, VisitAttrDef, AST_AtrDef +from .node_deffunc import FuncDef, VisitFuncDef, AST_FuncDef + +from .node_dispatch import CastingDispatch, VisitCastingDispatch, AST_CastingDispatch +from .node_dispatch import Dispatch, VisitDispatch, AST_Dispatch +from .node_dispatch import StaticDispatch, VisitStaticDispatch, AST_StaticDispatch + +from .node_statements import Assing, VisitAssing, AST_Assing +from .node_statements import IfThenElse, VisitIfThenElse, AST_IfThenElse +from .node_statements import While, VisitWhile, AST_While +from .node_statements import Block, VisitBlock, AST_Block +from .node_let import LetIn, VisitLetIn, AST_LetIn +from .node_case import Case, VisitCase, AST_Case + +from .node_binary import Sum, AST_Sum, VisitBinary +from .node_binary import Rest, AST_Rest +from .node_binary import Div, AST_Div +from .node_binary import Mult, AST_Mult +from .node_binary import Less, AST_Less +from .node_binary import LessOrEquals, AST_LessOrEquals +from .node_binary import Equals, AST_Equals + +from .node_atoms import Void, AST_Void, VisitAtomic +from .node_atoms import Neg, AST_Neg +from .node_atoms import Complement, AST_Complement +from .node_atoms import New, AST_New, VisitNew +from .node_atoms import Id, AST_Id, VisitEqualAtomic +from .node_atoms import Int, AST_Int +from .node_atoms import Str, AST_Str +from .node_atoms import Bool, AST_Bool + +class CoolSemanticChecking(VisitorBase): + @visitor.add(node_type= AST_Program, accion_class= VisitProgram, result= Program) + #class def + @visitor.add(node_type= AST_CoolClass, accion_class= VisitCoolClass, result= CoolClass) + @visitor.add(node_type= AST_AtrDef, accion_class= VisitAttrDef, result= AtrDef) + @visitor.add(node_type= AST_FuncDef, accion_class= VisitFuncDef, result= FuncDef) + # expr dispatch + @visitor.add(node_type= AST_CastingDispatch, accion_class= VisitCastingDispatch, result= CastingDispatch) + @visitor.add(node_type= AST_Dispatch, accion_class= VisitDispatch, result= Dispatch) + @visitor.add(node_type= AST_StaticDispatch, accion_class= VisitStaticDispatch, result= StaticDispatch) + # expr statement + @visitor.add(node_type= AST_Assing, accion_class= VisitAssing, result= Assing) + @visitor.add(node_type= AST_IfThenElse, accion_class= VisitIfThenElse, result= IfThenElse) + @visitor.add(node_type= AST_While, accion_class= VisitWhile, result= While) + @visitor.add(node_type= AST_Block, accion_class= VisitBlock, result= Block) + @visitor.add(node_type= AST_LetIn, accion_class= VisitLetIn, result= LetIn) + @visitor.add(node_type= AST_Case, accion_class= VisitCase, result= Case) + # expr binary + @visitor.add(node_type= AST_Sum, accion_class= VisitBinary, result= Sum) + @visitor.add(node_type= AST_Rest, accion_class= VisitBinary, result= Rest) + @visitor.add(node_type= AST_Div, accion_class= VisitBinary, result= Div) + @visitor.add(node_type= AST_Mult, accion_class= VisitBinary, result= Mult) + @visitor.add(node_type= AST_Less, accion_class= VisitBinary, result= Less) + @visitor.add(node_type= AST_LessOrEquals, accion_class= VisitBinary, result= LessOrEquals) + @visitor.add(node_type= AST_Equals, accion_class= VisitBinary, result= Equals) + # expr atomic + @visitor.add(node_type= AST_New, accion_class= VisitNew, result= New) + @visitor.add(node_type= AST_Neg, accion_class= VisitAtomic, result= Neg) + @visitor.add(node_type= AST_Complement, accion_class= VisitAtomic, result= Complement) + @visitor.add(node_type= AST_Void, accion_class= VisitAtomic, result= Void) + @visitor.add(node_type= AST_Id, accion_class= VisitEqualAtomic, result= Id) + @visitor.add(node_type= AST_Int, accion_class= VisitEqualAtomic, result= Int) + @visitor.add(node_type= AST_Str, accion_class= VisitEqualAtomic, result= Str) + @visitor.add(node_type= AST_Bool, accion_class= VisitEqualAtomic, result= Bool) + + def __init__(self, errors) -> None: + super().__init__(errors) + + @visitor.on("node") + def visit(node, scope): + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/node__.py b/src/cool_compiler/semantic/semantic_checking/node__.py new file mode 100755 index 000000000..db5d9b67c --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/node__.py @@ -0,0 +1,16 @@ +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 Feature(Node): + pass + +class Expresion(Node): + pass + +class Statement(Expresion): + pass diff --git a/src/cool_compiler/semantic/semantic_checking/node_class.py b/src/cool_compiler/semantic/semantic_checking/node_class.py new file mode 100755 index 000000000..0f342dd83 --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/node_class.py @@ -0,0 +1,27 @@ +from .node__ import Node +from ..tools import VisitBase +from ..scope import Scope +from ..create_type import CoolClass as AST_CoolClass + +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 VisitCoolClass(VisitBase): + def visit(self, node: AST_CoolClass, scope : Scope): + cls_scope : Scope = scope.create_child() + self.gclss.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.gclss.current_type.name} has circular inheritance") + + cls_scope.define_variable('self', self.gclss.current_type) + for name, atype in node.type.ite_attributes: + if not cls_scope.is_local(name): + cls_scope.define_variable(name, atype) + + feature_list = self.visit_all(node.feature_list, cls_scope) + return node.type, node.parent_type, feature_list \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/node_program.py b/src/cool_compiler/semantic/semantic_checking/node_program.py new file mode 100755 index 000000000..90108f5e9 --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/node_program.py @@ -0,0 +1,12 @@ +from .node__ import Node +from ..tools import defVisitClass +from ..scope import Scope +from ..create_type import Program as AST_Program + +class Program(Node): + def __init__(self, class_list) -> None: + self.class_list = class_list + +VisitProgram = defVisitClass( + lambda self, node, error, scope = Scope() : self.gclss.visit_all(node.class_list, scope) +) \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py b/src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py new file mode 100755 index 000000000..5bd204088 --- /dev/null +++ b/src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py @@ -0,0 +1,338 @@ +from typing import SupportsComplex +from .ASTs import ast1_create_type_return as AST_init +from .ASTs import ast2_semantic_checking_return as AST_result +from . import visitor +from .scope import Scope +from .__dependency import Type, SemanticError, ErrorType, Int, Bool, Object, Str +from .tools import VisitorBase, type_checking, find_variable, parent_common +from .semantic_checking_funcs import * + +class SemanticChecking(VisitorBase): + def __init__(self, error) -> None: + super().__init__(error) + self.casting_error_type = lambda a,b : a if not type(a) is ErrorType else b + + @visitor.on("node") + def visit(self, node, scope) -> AST_result.Node: + pass + + + + + @visitor.when(AST_init.AtrDef) + @visitor.result(AST_result.AtrDef) + def visit(self, node: AST_init.AtrDef, scope: Scope) -> AST_result.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 not self.type_checking(node.type, expr.static_type): + error_handler().add_semantic_error(f"can't save {expr.static_type.name} into {node.type}") + + return node.name, node.type, expr + + @visitor.when(AST_init.FuncDef) + @visitor.result(AST_result.FuncDef) + def visit(self, node: AST_init.FuncDef, scope : Scope) -> AST_result.Node: + error_handler = self.get_se_handler(node) + + try: + func = self.current_type.parent.get_method(node.name) + + for pn, fn in zip(node.params, func.params): + name, tparams = pn + _, tbase_params = fn + if not self.type_checking(tbase_params, tparams): + 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() + for param, ptype in node.params: + new_scope.define_variable(param, ptype) + + expr = self.visit(node.expr, new_scope) + + if not type_checking(node.return_type, expr.static_type): + self.cool_error(node.lineno, node.index).add_type_error(node.return_type.name, expr.static_type.name ) + + return node.name, node.params, node.return_type, expr + + @visitor.when(AST_init.CastingDispatch) + @visitor.result(AST_result.CastingDispatch) + def visit(self, node: AST_init.CastingDispatch, scope: Scope) -> AST_result.Node: + + expr = self.visit(node.expr, scope) + if not expr.static_type.conforms_to(node.type): + self.cool_error(node.lineno, node.index).add_type_error(node.type, 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) + for tupl, exp in zip(func.params, params): + if not exp.static_type.conforms_to(tupl[1]): + self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + self.cool_error(node.lineno, node.index).add_attribute_error(node.type, node.id ) + + return expr, node.type, node.id, params, static_type + + @visitor.when(AST_init.Dispatch) + @visitor.result(AST_result.Dispatch) + def visit(self, node: AST_init.Dispatch, scope: Scope) -> AST_result.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) + for tupl, exp in zip(func.params, params): + if not exp.static_type.conforms_to(tupl[1]): + self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + self.cool_error(node.lineno, node.index).add_attribute_error(expr.static_type.name, node.id ) + + return expr, node.id, params, static_type + + @visitor.when(AST_init.StaticDispatch) + @visitor.result(AST_result.StaticDispatch) + def visit(self, node: AST_init.StaticDispatch, scope: Scope) -> AST_result.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) + for tupl, exp in zip(func.params, params): + if not exp.static_type.conforms_to(tupl[1]): + self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + + static_type = func.return_type + except SemanticError: + self.cool_error(node.lineno, node.index).add_attribute_error(self.current_type.name, node.id ) + + return node.id, params, static_type + + @visitor.when(AST_init.Assing) + @visitor.result(AST_result.Assing) + def visit(self, node: AST_init.Assing, scope: Scope) -> AST_result.Node: + try: + v = scope.find_variable(node.id) + static_type = v.type + except SemanticError: + self.cool_error(node.lineno, node.index).add_name_error(node.id) + static_type = ErrorType() + + expr = self.visit(node.expr, scope) + self.type_checking(static_type, expr.static_type, node) + + return node.id, expr, self.casting_error_type(static_type, expr.static_type) + + @visitor.when(AST_init.IfThenElse) + @visitor.result(AST_result.IfThenElse) + def visit(self, node: AST_init.IfThenElse, scope: Scope) -> AST_result.Node: + cond = self.visit(node.condition, scope) + self.type_checking(Bool(), cond.static_type, node) + + then_expr = self.visit(node.then_expr, scope) + else_expr = self.visit(node.else_expr, scope) + + return cond, then_expr, else_expr, self.parent_common(then_expr.static_type, else_expr.static_type) + + @visitor.when(AST_init.While) + @visitor.result(AST_result.While) + def visit(self, node: AST_init.While, scope: Scope) -> AST_result.Node: + cond = self.visit(node.condition, scope) + self.type_checking(Bool(), cond.static_type, node) + + return cond, self.visit(node.loop_expr, scope), Object() + + @visitor.when(AST_init.Block) + @visitor.result(AST_result.Block) + def visit(self, node: AST_init.Block, scope: Scope) -> AST_result.Node: + block_list= [] + for b in node.expr_list: + block_list.append(self.visit(b, scope)) + + return block_list, block_list[-1].static_type + + @visitor.when(AST_init.LetIn) + @visitor.result(AST_result.LetIn) + def visit(self, node: AST_init.LetIn, scope: Scope) -> AST_result.Node: + new_scope = scope.create_child() + + assing_list = [] + for name, atype, expr in node.assing_list: + exp = self.visit(expr, new_scope) + self.type_checking(atype, exp.static_type, node) + 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 + + @visitor.when(AST_init.Case) + @visitor.result(AST_result.Case) + def visit(self, node: AST_init.Case, scope: Scope) -> AST_result.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() + 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 = self.parent_common(static_type, exp.static_type) + case_list.append((name, atype, exp)) + + return expr_cond, case_list, static_type + + @visitor.when(AST_init.Sum) + @visitor.result(AST_result.Sum) + def visit(self, node: AST_init.Sum, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Int() + + @visitor.when(AST_init.Rest) + @visitor.result(AST_result.Rest) + def visit(self, node: AST_init.Rest, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Int() + + @visitor.when(AST_init.Mult) + @visitor.result(AST_result.Mult) + def visit(self, node: AST_init.Mult, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Int() + + @visitor.when(AST_init.Div) + @visitor.result(AST_result.Div) + def visit(self, node: AST_init.Div, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Int() + + @visitor.when(AST_init.Less) + @visitor.result(AST_result.Less) + def visit(self, node: AST_init.Less, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Bool() + + @visitor.when(AST_init.LessOrEquals) + @visitor.result(AST_result.LessOrEquals) + def visit(self, node: AST_init.LessOrEquals, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + self.type_checking(Int(), left.static_type, node) + + right = self.visit(node.right, scope) + self.type_checking(Int(), right.static_type, node) + + return left, right, Bool() + + @visitor.when(AST_init.Equals) + @visitor.result(AST_result.Equals) + def visit(self, node: AST_init.Equals, scope: Scope) -> AST_result.Node: + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + list_type = [ Str, Int, Bool] + if type(left.static_type) in list_type or type(right.static_type) in list_type: + if left.static_type == right.static_type: + self.cool_error(node.lineno, node.index).add_type_error(left.static_type.name, right.static_type.name) + + return left, right, Bool() + + @visitor.when(AST_init.Void) + @visitor.result(AST_result.Void) + def visit(self, node: AST_init.Void, scope: Scope) -> AST_result.Node: + return self.visit(node.item, scope), Bool() + + @visitor.when(AST_init.New) + @visitor.result(AST_result.New) + def visit(self, node: AST_init.New, scope: Scope) -> AST_result.Node: + return node.item, node.item + + @visitor.when(AST_init.Complement) + @visitor.result(AST_result.Complement) + def visit(self, node: AST_init.Complement, scope: Scope) -> AST_result.Node: + expr = self.visit(node.item, scope) + self.type_checking(Int(), expr.static_type, node) + return expr, Int() + + @visitor.when(AST_init.Neg) + @visitor.result(AST_result.Neg) + def visit(self, node: AST_init.Neg, scope: Scope) -> AST_result.Node: + expr = self.visit(node.item, scope) + self.type_checking(Bool(), expr.static_type) + return expr, Bool() + + @visitor.when(AST_init.Id) + @visitor.result(AST_result.Id) + def visit(self, node: AST_init.Id, scope: Scope) -> AST_result.Node: + try: + v = scope.find_variable(node.item) + return node.item, v.type + except SemanticError: + self.cool_error(node.lineno, node.index).add_name_error(node.item) + return node.item, ErrorType() + + @visitor.when(AST_init.Int) + @visitor.result(AST_result.Int) + def visit(self, node: AST_init.Int, scope: Scope) -> AST_result.Node: + return node.item, Int() + + @visitor.when(AST_init.Bool) + @visitor.result(AST_result.Bool) + def visit(self, node: AST_init.Bool, scope: Scope) -> AST_result.Node: + return node.item, Bool() + + @visitor.when(AST_init.Str) + @visitor.result(AST_result.Str) + def visit(self, node: AST_init.Str, scope: Scope) -> AST_result.Node: + return node.item, Str() diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py new file mode 100755 index 000000000..50e6b15d0 --- /dev/null +++ b/src/cool_compiler/semantic/tools.py @@ -0,0 +1,98 @@ +from cool_compiler.semantic.visitor import result +from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object +from .scope import Scope + +def defVisitClass(*func): + class Visit(VisitBase): + def visit(self, node,*args, **kw): + error_handler = self.gclss.get_se_handler(node) + result = [] + for f in func: + result.append(f(self, node, error_handler,*args, **kw)) + return tuple(result) + return Visit + +class VisitBase: + def __init__(self, global_class) -> None: + self.gclss : VisitorBase = global_class + + def visit(self, *args, **kw): + pass + + def get_type(self, type_name, error_handler): + find_result = find_type(type_name, self.gclss.global_types) + return find_result.get_value( if_fail_do= error_handler().add_semantic_error ) + + def visit_all(self, list_node, *args): + result = [] + for n in list_node: + result.append(self.gclss.visit(n, *args)) + + return result + +class VisitorBase: + def __init__(self, error) -> None: + self.cool_error = error + self.current_type : Type = None + + def get_se_handler(self, node): + return self.cool_error.get_handler(node.lineno, node.index) + + def type_checking(self, tbase : Type, ttype : Type): + if tbase.is_self_type : tbase = self.current_type + if ttype.is_self_type : ttype = self.current_type + + if not ttype.conforms_to(tbase): + return False + + return True + + def visit(self, *args, **kw): + pass + + +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(self, t1: Type, t2: Type): + while True: + if None in (t1,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/visitor.py b/src/cool_compiler/semantic/visitor.py new file mode 100755 index 000000000..fe418399c --- /dev/null +++ b/src/cool_compiler/semantic/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) + 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/semantic_ast.py b/src/cool_compiler/semantic_ast.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/cool_compiler/table_regex.py b/src/cool_compiler/table_regex.py deleted file mode 100644 index 50cceda59..000000000 --- a/src/cool_compiler/table_regex.py +++ /dev/null @@ -1,24 +0,0 @@ -from enum import Enum - -class TokenType(Enum): - pass - -class Token: - def __init__(self, lex, ttype : TokenType, pos : tuple) : - self.lex = lex - self.type = ttype - self.pos = pos - -class RegexTable: - - def __call__(self): - return self.symbol_table() + self.keyword_table() + self.identifier_table() - - def symbol_table(self): - pass - - def identifier_table(self): - pass - - def keyword_table(self): - pass \ 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..0cb7b5d51 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/bool.py @@ -0,0 +1,13 @@ +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.__class__) + + @property + def is_shield(self): + return True \ 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..d95a4f8a5 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/int.py @@ -0,0 +1,11 @@ +from ..cool_type_build_in_manager import build_in_type +from ..type import Type + +@build_in_type +class Int(Type): + def __init__(self): + super().__init__("Int") + + @property + def is_shield(self): + return True \ 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..a55d371fe --- /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 +from ..type import Type +from ..tools import type_body_def +from . import * + +@build_in_type +class Object(Type): + def __init__(self): + super().__init__("Object") + 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..ec86583da --- /dev/null +++ b/src/cool_compiler/types/build_in_types/self.py @@ -0,0 +1,15 @@ +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 \ 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..42377a4d4 --- /dev/null +++ b/src/cool_compiler/types/build_in_types/str.py @@ -0,0 +1,24 @@ +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 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..c430039c9 --- /dev/null +++ b/src/cool_compiler/types/cool_type_build_in_manager.py @@ -0,0 +1,31 @@ +from .tools import SemanticError +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.__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 __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..110828041 --- /dev/null +++ b/src/cool_compiler/types/type.py @@ -0,0 +1,122 @@ +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 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): + 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}') + + 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/makefile b/src/makefile old mode 100644 new mode 100755 index 25a1ef33f..8d32826f7 --- a/src/makefile +++ b/src/makefile @@ -1,7 +1,7 @@ .PHONY: clean main: - python -m cool_compiler string3.cl + python -m cool_compiler assignment1.cl clean: rm -rf build/* diff --git a/src/mixed2.cl b/src/mixed2.cl deleted file mode 100644 index 9c4b6917b..000000000 --- a/src/mixed2.cl +++ /dev/null @@ -1,20 +0,0 @@ -"kjas\"lnnsdj /0 flj\trdsaf" -@.$.@ -@*%*@ -"alkjfldajf""dasfadsf - -(* -#1 STR_CONST "kjas\"lnnsdj\nfljrdsaf" -#2 '@' -#2 '.' -#2 ERROR "$" -#2 '.' -#2 '@' -#3 '@' -#3 '*' -#3 ERROR "%" -#3 '*' -#3 '@' -#4 STR_CONST "alkjfldajf" -#4 ERROR "Unterminated string constant" -*) \ No newline at end of file diff --git a/src/string1.cl b/src/string1.cl deleted file mode 100644 index 6c3c00833..000000000 --- a/src/string1.cl +++ /dev/null @@ -1,6 +0,0 @@ -(* A non-escaped newline character may not appear in a string *) - -"This \ -is OK" -"This is not -OK" \ No newline at end of file diff --git a/src/string3.cl b/src/string3.cl deleted file mode 100644 index 78abc4972e218bca373ba1750c99a3450cef4ea3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234 zcmX|4yAH!34D8HToS2dhRoZ?*=Jpd<90*B>0}_xSe_!a!lI8Q=*(aJadZZi|KVhQ- zK4j?NGc6u@9^rRpGmYcJ^ifl$K@ Mi{IIrdU_-I0>Lp*mH+?% 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 From 9fe9ca98b96d90bcf181372240883549448d8490 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 7 Oct 2021 21:41:08 -0400 Subject: [PATCH 08/91] ready for reinit dev --- src/assignment1.cl | 15 - src/cool_compiler/__main__.py | 4 +- src/cool_compiler/semantic/.DS_Store | Bin 6148 -> 6148 bytes src/cool_compiler/semantic/__init__.py | 4 +- .../semantic/create_type/__init__.py | 8 - .../semantic/create_type/main.py | 79 ----- .../semantic/create_type/node__.py | 13 - .../semantic/create_type/node_atoms.py | 53 ---- .../semantic/create_type/node_binary.py | 40 --- .../semantic/create_type/node_case.py | 20 -- .../semantic/create_type/node_class.py | 39 --- .../semantic/create_type/node_defattr.py | 25 -- .../semantic/create_type/node_deffunc.py | 26 -- .../semantic/create_type/node_dispatch.py | 51 ---- .../semantic/create_type/node_let.py | 23 -- .../semantic/create_type/node_program.py | 19 -- .../semantic/create_type/node_statements.py | 49 --- src/cool_compiler/semantic/tools.py | 34 ++- .../{ => v0_parser_return}/factory_node.py | 2 +- .../factory_return_ast.py | 0 .../v1_create_type/create_type_ast.py | 146 +++++++++ .../v1_create_type/create_type_visitor.py | 281 ++++++++++++++++++ src/cool_compiler/semantic/visitor.py | 2 +- src/makefile | 2 +- src/test.cl | 11 + 25 files changed, 464 insertions(+), 482 deletions(-) delete mode 100755 src/assignment1.cl delete mode 100755 src/cool_compiler/semantic/create_type/__init__.py delete mode 100755 src/cool_compiler/semantic/create_type/main.py delete mode 100755 src/cool_compiler/semantic/create_type/node__.py delete mode 100755 src/cool_compiler/semantic/create_type/node_atoms.py delete mode 100755 src/cool_compiler/semantic/create_type/node_binary.py delete mode 100755 src/cool_compiler/semantic/create_type/node_case.py delete mode 100755 src/cool_compiler/semantic/create_type/node_class.py delete mode 100755 src/cool_compiler/semantic/create_type/node_defattr.py delete mode 100755 src/cool_compiler/semantic/create_type/node_deffunc.py delete mode 100755 src/cool_compiler/semantic/create_type/node_dispatch.py delete mode 100755 src/cool_compiler/semantic/create_type/node_let.py delete mode 100755 src/cool_compiler/semantic/create_type/node_program.py delete mode 100755 src/cool_compiler/semantic/create_type/node_statements.py rename src/cool_compiler/semantic/{ => v0_parser_return}/factory_node.py (98%) rename src/cool_compiler/semantic/{ => v0_parser_return}/factory_return_ast.py (100%) create mode 100644 src/cool_compiler/semantic/v1_create_type/create_type_ast.py create mode 100644 src/cool_compiler/semantic/v1_create_type/create_type_visitor.py create mode 100755 src/test.cl diff --git a/src/assignment1.cl b/src/assignment1.cl deleted file mode 100755 index 29da0f082..000000000 --- a/src/assignment1.cl +++ /dev/null @@ -1,15 +0,0 @@ -"lkjdsafkljdsalfj\u0000dsafdsaf\u0000djafslkjdsalf\nsdajf\" lkjfdsasdkjfl"123 -adsfasklj# -LKldsajf iNhERITS -"lkdsajf" - -(* -#1 STR_CONST "lkjdsafkljdsalfju0000dsafdsafu0000djafslkjdsalf\nsdajf\" lkjfdsasdkjfl" -#1 INT_CONST 123 -#2 OBJECTID adsfasklj -#2 ERROR "#" -#3 TYPEID LKldsajf -#3 INHERITS -#4 STR_CONST "lkdsajf" -*) - diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 71d9b5fc7..213eed299 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -25,11 +25,11 @@ if errors.any(): sys.exit(1) visitorList = [ CreateType ] - + for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - + diff --git a/src/cool_compiler/semantic/.DS_Store b/src/cool_compiler/semantic/.DS_Store index 5359494b5f2614eedd1b0c588b55e236d72530a8..6397e4c0a010e4f40c4b2f87fe9d1d72c69ee646 100644 GIT binary patch delta 74 zcmZoMXfc=|&e%4wP;8=}q9`K+0|O8XFfimXlrUs6Bs0V_Bu{*(&d9iNeFXc&56YX_ bIRrQu+crM@&ODi4M3)t$;lO5Fk;BXYvFQ_p delta 105 zcmZoMXfc=|&e%S&P;8=}q9_vs0|O%ig8&0V2}3GFJdmtpD42LqeX@ZFivl-8GD8ti xI1yQrAvL8qIVUMUKZjvsPXzmBb`Aj!#`cW|zcWwf7tv*8*z72Bn0aCY3jiB|8sq=~ diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py index 5949b98c0..23a8d3bbd 100755 --- a/src/cool_compiler/semantic/__init__.py +++ b/src/cool_compiler/semantic/__init__.py @@ -1,2 +1,2 @@ -from .factory_node import CoolFactory -from .create_type import CoolCreateType as CreateType \ No newline at end of file +from .v0_parser_return.factory_node import CoolFactory +from .v1_create_type.create_type_visitor import CoolCreateType as CreateType \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/__init__.py b/src/cool_compiler/semantic/create_type/__init__.py deleted file mode 100755 index 2ba994f35..000000000 --- a/src/cool_compiler/semantic/create_type/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .main import CoolCreateType - -from .main import Program, CoolClass, AtrDef, FuncDef -from .main import StaticDispatch, CastingDispatch, Dispatch -from .main import Assing, IfThenElse, While, Block, LetIn, Case -from .main import Sum, Rest, Div, Mult, Less, LessOrEquals, Equals -from .main import New, Void, Neg, Complement, Id, Int, Str, Bool - diff --git a/src/cool_compiler/semantic/create_type/main.py b/src/cool_compiler/semantic/create_type/main.py deleted file mode 100755 index acea5f7d7..000000000 --- a/src/cool_compiler/semantic/create_type/main.py +++ /dev/null @@ -1,79 +0,0 @@ -from .. import visitor -from ..__dependency import Type -from ..tools import VisitorBase -from .node_program import Program, VisitProgram, AST_Program -from .node_class import CoolClass, VisitCoolClass, AST_CoolClass -from .node_defattr import AtrDef, VisitAttrDef, AST_AtrDef -from .node_deffunc import FuncDef, VisitFuncDef, AST_FuncDef - -from .node_dispatch import CastingDispatch, VisitCastingDispatch, AST_CastingDispatch -from .node_dispatch import Dispatch, VisitDispatch, AST_Dispatch -from .node_dispatch import StaticDispatch, VisitStaticDispatch, AST_StaticDispatch - -from .node_statements import Assing, VisitAssing, AST_Assing -from .node_statements import IfThenElse, VisitIfThenElse, AST_IfThenElse -from .node_statements import While, VisitWhile, AST_While -from .node_statements import Block, VisitBlock, AST_Block -from .node_let import LetIn, VisitLetIn, AST_LetIn -from .node_case import Case, VisitCase, AST_Case - -from .node_binary import Sum, AST_Sum, VisitBinary -from .node_binary import Rest, AST_Rest -from .node_binary import Div, AST_Div -from .node_binary import Mult, AST_Mult -from .node_binary import Less, AST_Less -from .node_binary import LessOrEquals, AST_LessOrEquals -from .node_binary import Equals, AST_Equals - -from .node_atoms import Void, AST_Void, VisitAtomic -from .node_atoms import Neg, AST_Neg -from .node_atoms import Complement, AST_Complement -from .node_atoms import New, AST_New, VisitNew -from .node_atoms import Id, AST_Id, VisitEqualAtomic -from .node_atoms import Int, AST_Int -from .node_atoms import Str, AST_Str -from .node_atoms import Bool, AST_Bool - - -class CoolCreateType(VisitorBase): - @visitor.add(node_type= AST_Program, accion_class= VisitProgram, result= Program) - #class def - @visitor.add(node_type= AST_CoolClass, accion_class= VisitCoolClass, result= CoolClass) - @visitor.add(node_type= AST_AtrDef, accion_class= VisitAttrDef, result= AtrDef) - @visitor.add(node_type= AST_FuncDef, accion_class= VisitFuncDef, result= FuncDef) - # expr dispatch - @visitor.add(node_type= AST_CastingDispatch, accion_class= VisitCastingDispatch, result= CastingDispatch) - @visitor.add(node_type= AST_Dispatch, accion_class= VisitDispatch, result= Dispatch) - @visitor.add(node_type= AST_StaticDispatch, accion_class= VisitStaticDispatch, result= StaticDispatch) - # expr statement - @visitor.add(node_type= AST_Assing, accion_class= VisitAssing, result= Assing) - @visitor.add(node_type= AST_IfThenElse, accion_class= VisitIfThenElse, result= IfThenElse) - @visitor.add(node_type= AST_While, accion_class= VisitWhile, result= While) - @visitor.add(node_type= AST_Block, accion_class= VisitBlock, result= Block) - @visitor.add(node_type= AST_LetIn, accion_class= VisitLetIn, result= LetIn) - @visitor.add(node_type= AST_Case, accion_class= VisitCase, result= Case) - # expr binary - @visitor.add(node_type= AST_Sum, accion_class= VisitBinary, result= Sum) - @visitor.add(node_type= AST_Rest, accion_class= VisitBinary, result= Rest) - @visitor.add(node_type= AST_Div, accion_class= VisitBinary, result= Div) - @visitor.add(node_type= AST_Mult, accion_class= VisitBinary, result= Mult) - @visitor.add(node_type= AST_Less, accion_class= VisitBinary, result= Less) - @visitor.add(node_type= AST_LessOrEquals, accion_class= VisitBinary, result= LessOrEquals) - @visitor.add(node_type= AST_Equals, accion_class= VisitBinary, result= Equals) - # expr atomic - @visitor.add(node_type= AST_New, accion_class= VisitNew, result= New) - @visitor.add(node_type= AST_Neg, accion_class= VisitAtomic, result= Neg) - @visitor.add(node_type= AST_Complement, accion_class= VisitAtomic, result= Complement) - @visitor.add(node_type= AST_Void, accion_class= VisitAtomic, result= Void) - @visitor.add(node_type= AST_Id, accion_class= VisitEqualAtomic, result= Id) - @visitor.add(node_type= AST_Int, accion_class= VisitEqualAtomic, result= Int) - @visitor.add(node_type= AST_Str, accion_class= VisitEqualAtomic, result= Str) - @visitor.add(node_type= AST_Bool, accion_class= VisitEqualAtomic, result= Bool) - - def __init__(self, errors) -> None: - super().__init__(errors) - self.global_types = {} - - @visitor.on("node") - def visit(node): - pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node__.py b/src/cool_compiler/semantic/create_type/node__.py deleted file mode 100755 index 99346437a..000000000 --- a/src/cool_compiler/semantic/create_type/node__.py +++ /dev/null @@ -1,13 +0,0 @@ -class Node: - def get_pos_to_error(self, lineno, index): - self.lineno = lineno - self.index = index - -class Feature(Node): - pass - -class Expresion(Node): - pass - -class Statement(Expresion): - pass diff --git a/src/cool_compiler/semantic/create_type/node_atoms.py b/src/cool_compiler/semantic/create_type/node_atoms.py deleted file mode 100755 index 2d0ebff8a..000000000 --- a/src/cool_compiler/semantic/create_type/node_atoms.py +++ /dev/null @@ -1,53 +0,0 @@ -from .node__ import Expresion -from ..tools import defVisitClass -from ..factory_return_ast import Void as AST_Void -from ..factory_return_ast import New as AST_New -from ..factory_return_ast import Complement as AST_Complement -from ..factory_return_ast import Neg as AST_Neg -from ..factory_return_ast import Id as AST_Id -from ..factory_return_ast import Int as AST_Int -from ..factory_return_ast import Str as AST_Str -from ..factory_return_ast import Bool as AST_Bool - -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 - -VisitAtomic = defVisitClass( - lambda self, node, error: self.gclss.visit(node.item), -) - -VisitNew = defVisitClass( - lambda self, node, error: self.get_type(node.item, error), -) - -VisitEqualAtomic = defVisitClass( - lambda self, node, error: node.item, -) - - - diff --git a/src/cool_compiler/semantic/create_type/node_binary.py b/src/cool_compiler/semantic/create_type/node_binary.py deleted file mode 100755 index d70e994cb..000000000 --- a/src/cool_compiler/semantic/create_type/node_binary.py +++ /dev/null @@ -1,40 +0,0 @@ -from .node__ import Expresion -from ..tools import defVisitClass -from ..factory_return_ast import Sum as AST_Sum -from ..factory_return_ast import Rest as AST_Rest -from ..factory_return_ast import Div as AST_Div -from ..factory_return_ast import Mult as AST_Mult -from ..factory_return_ast import Less as AST_Less -from ..factory_return_ast import LessOrEquals as AST_LessOrEquals -from ..factory_return_ast import Equals as AST_Equals - -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 - -VisitBinary = defVisitClass( - lambda self, node, error: self.gclss.visit(node.left), - lambda self, node, error: self.gclss.visit(node.right), -) \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_case.py b/src/cool_compiler/semantic/create_type/node_case.py deleted file mode 100755 index 1e68c74ff..000000000 --- a/src/cool_compiler/semantic/create_type/node_case.py +++ /dev/null @@ -1,20 +0,0 @@ -from .node__ import Statement -from ..tools import VisitBase -from ..factory_return_ast import Case as AST_Case - -class Case(Statement): - def __init__(self, expr, case_list) -> None: - self.case_list = case_list - self.expr = expr - -class VisitCase(VisitBase): - def visit(self, node : AST_Case) : - error_handler = self.gclss.get_se_handler(node) - - case_list = [] - for name, atype, expr in node.case_list: - rtype = self.get_type(atype, error_handler) - case_list.append((name, rtype, self.gclss.visit(expr))) - - return self.gclss.visit(node.expr), case_list - diff --git a/src/cool_compiler/semantic/create_type/node_class.py b/src/cool_compiler/semantic/create_type/node_class.py deleted file mode 100755 index d0a4949aa..000000000 --- a/src/cool_compiler/semantic/create_type/node_class.py +++ /dev/null @@ -1,39 +0,0 @@ -from .node__ import Node -from ..__dependency import Type, Object, SemanticError, ErrorType -from ..tools import VisitBase, find_type -from ..factory_return_ast import CoolClass as AST_CoolClass - -class CoolClass(Node): - def __init__(self, typee, parent_typee, feature_list) -> None: - self.type : Type = typee - self.parent_type : Type = parent_typee - self.feature_list = feature_list - -class VisitCoolClass(VisitBase): - def visit(self, node : AST_CoolClass) : - self.gclss.current_type = self.gclss.global_types[node.name] - error_handler = self.gclss.get_se_handler(node) - - parent_type = self.get_parent_type(node, error_handler) - try: self.gclss.current_type.set_parent(parent_type) - except SemanticError: pass - - feature_list = self.visit_all(node.feature_list) - - return self.gclss.current_type, parent_type, feature_list - - - def get_parent_type(self, node : AST_CoolClass, error_handler): - if node.parent is None: return Object() - - find_result = find_type(node.parent, self.gclss.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.gclss.current_type.name: - error_handler().add_semantic_error( f"class {self.gclss.current_type.name} can't be inherited from {parent_type.name}" ) - return ErrorType() - - return parent_type - - - \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_defattr.py b/src/cool_compiler/semantic/create_type/node_defattr.py deleted file mode 100755 index 92d03c68e..000000000 --- a/src/cool_compiler/semantic/create_type/node_defattr.py +++ /dev/null @@ -1,25 +0,0 @@ -from .node__ import Feature -from ..__dependency import Type, Object, SemanticError, ErrorType -from ..tools import VisitBase, find_type -from ..factory_return_ast import AtrDef as AST_AtrDef - -class AtrDef(Feature): - def __init__(self, name, atype, expr) -> None: - self.name = name - self.type = atype - self.expr = expr - -class VisitAttrDef(VisitBase): - def visit(self, node : AST_AtrDef) : - error_handler = self.gclss.get_se_handler(node) - - atype = self.get_type(node.type, error_handler) - self.gclss.current_type.define_attribute(node.name, atype) - - expr = self.gclss.visit(node.expr) - return node.name, atype, expr - - - - - \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_deffunc.py b/src/cool_compiler/semantic/create_type/node_deffunc.py deleted file mode 100755 index 292a72e0c..000000000 --- a/src/cool_compiler/semantic/create_type/node_deffunc.py +++ /dev/null @@ -1,26 +0,0 @@ -from .node__ import Feature -from ..__dependency import Type, Object, SemanticError, ErrorType -from ..tools import VisitBase, find_type -from ..factory_return_ast import FuncDef as AST_FuncDef - -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 VisitFuncDef(VisitBase): - def visit(self, node : AST_FuncDef) : - error_handler = self.gclss.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)) - - self.gclss.current_type.define_method(node.name, params, return_type) - expr = self.gclss.visit(node.expr) - return node.name, params, return_type, expr \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_dispatch.py b/src/cool_compiler/semantic/create_type/node_dispatch.py deleted file mode 100755 index 319bec5ed..000000000 --- a/src/cool_compiler/semantic/create_type/node_dispatch.py +++ /dev/null @@ -1,51 +0,0 @@ -from .node__ import Expresion -from ..tools import defVisitClass -from ..factory_return_ast import CastingDispatch as AST_CastingDispatch -from ..factory_return_ast import StaticDispatch as AST_StaticDispatch -from ..factory_return_ast import Dispatch as AST_Dispatch - - -class CastingDispatch(Expresion): - def __init__(self, expr, atype, idf, params) -> None: - self.expr = expr - self.type = atype - self.id = idf - self.params = params - -VisitCastingDispatch = defVisitClass( - lambda self, node, error: self.gclss.visit(node.expr), - lambda self, node, error: self.get_type(node.type, error), - lambda self, node, error: node.id, - lambda self, node, error: self.visit_all(node.params), -) -############################################################################## - -class Dispatch(Expresion): - def __init__(self, expr, idf, params) -> None: - self.expr = expr - self.id = idf - self.params = params - -VisitDispatch = defVisitClass( - lambda self, node, error: self.gclss.visit(node.expr), - lambda self, node, error: node.id, - lambda self, node, error: self.visit_all(node.params), -) - -############################################################################### -class StaticDispatch(Expresion): - def __init__(self, idf, params) -> None: - self.id = idf - self.params = params - -VisitStaticDispatch = defVisitClass( - lambda self, node, error: node.id, - lambda self, node, error: self.visit_all(node.params), -) - - - - - - - diff --git a/src/cool_compiler/semantic/create_type/node_let.py b/src/cool_compiler/semantic/create_type/node_let.py deleted file mode 100755 index acd9e178a..000000000 --- a/src/cool_compiler/semantic/create_type/node_let.py +++ /dev/null @@ -1,23 +0,0 @@ -from .node__ import Statement -from ..tools import VisitBase -from ..factory_return_ast import LetIn as AST_LetIn - -class LetIn(Statement): - def __init__(self, assing_list, expr) -> None: - self.assing_list = assing_list - self.expr = expr - -class VisitLetIn(VisitBase): - def visit(self, node : AST_LetIn) : - error_handler = self.gclss.get_se_handler(node) - - assing_list = [] - for name, atype, expr in node.assing_list: - rtype = self.get_type(atype, error_handler) - assing_list.append((name, rtype, self.gclss.visit(expr))) - - return assing_list, self.gclss.visit(node.expr) - - - - \ No newline at end of file diff --git a/src/cool_compiler/semantic/create_type/node_program.py b/src/cool_compiler/semantic/create_type/node_program.py deleted file mode 100755 index 94ec98624..000000000 --- a/src/cool_compiler/semantic/create_type/node_program.py +++ /dev/null @@ -1,19 +0,0 @@ -from .node__ import Node -from ..__dependency import Type -from ..tools import VisitBase -from ..factory_return_ast import Program as AST_Program - -class Program(Node): - def __init__(self, class_list) -> None: - self.class_list = class_list - -class VisitProgram(VisitBase): - def visit(self, node : AST_Program) : - for name, lineno, index in node.names_list: - if name in self.gclss.global_types: - self.gclss.cool_error(lineno, index) - self.gclss.cool_error.add_semantic_error(f"{name} is already defined") - else: self.gclss.global_types[name] = Type(name) - - class_list = self.visit_all(node.class_list) - return class_list, diff --git a/src/cool_compiler/semantic/create_type/node_statements.py b/src/cool_compiler/semantic/create_type/node_statements.py deleted file mode 100755 index 5ec8dd626..000000000 --- a/src/cool_compiler/semantic/create_type/node_statements.py +++ /dev/null @@ -1,49 +0,0 @@ -from .node__ import Statement -from ..tools import defVisitClass -from ..factory_return_ast import Assing as AST_Assing -from ..factory_return_ast import IfThenElse as AST_IfThenElse -from ..factory_return_ast import While as AST_While -from ..factory_return_ast import Block as AST_Block - -class Assing(Statement): - def __init__(self, name, expr) -> None: - self.id = name - self.expr = expr - -VisitAssing = defVisitClass( - lambda self, node, error: node.id, - lambda self, node, error: self.gclss.visit(node.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 - -VisitIfThenElse = defVisitClass( - lambda self, node, error: self.gclss.visit(node.condition), - lambda self, node, error: self.gclss.visit(node.then_expr), - lambda self, node, error: self.gclss.visit(node.else_expr), -) - -############################################################################### -class While(Statement): - def __init__(self, condition, loop_expr) -> None: - self.condition = condition - self.loop_expr = loop_expr - -VisitWhile = defVisitClass( - lambda self, node, error: self.gclss.visit(node.condition), - lambda self, node, error: self.gclss.visit(node.loop_expr), -) - -############################################################################### -class Block(Statement): - def __init__(self, expr_list) -> None: - self.expr_list = expr_list - -VisitBlock = defVisitClass( - lambda self, node, error: self.visit_all(node.expr_list), -) \ No newline at end of file diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py index 50e6b15d0..a7827a774 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -13,31 +13,39 @@ def visit(self, node,*args, **kw): return Visit class VisitBase: - def __init__(self, global_class) -> None: - self.gclss : VisitorBase = global_class - - def visit(self, *args, **kw): - pass - def get_type(self, type_name, error_handler): - find_result = find_type(type_name, self.gclss.global_types) + find_result = find_type(type_name, self.global_types) return find_result.get_value( if_fail_do= error_handler().add_semantic_error ) def visit_all(self, list_node, *args): result = [] for n in list_node: - result.append(self.gclss.visit(n, *args)) + 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 + class VisitorBase: def __init__(self, error) -> None: self.cool_error = error self.current_type : Type = None - def get_se_handler(self, node): - return self.cool_error.get_handler(node.lineno, node.index) - def type_checking(self, tbase : Type, ttype : Type): if tbase.is_self_type : tbase = self.current_type if ttype.is_self_type : ttype = self.current_type @@ -46,10 +54,6 @@ def type_checking(self, tbase : Type, ttype : Type): return False return True - - def visit(self, *args, **kw): - pass - class Result: def __init__(self, succ, result, error) -> None: diff --git a/src/cool_compiler/semantic/factory_node.py b/src/cool_compiler/semantic/v0_parser_return/factory_node.py similarity index 98% rename from src/cool_compiler/semantic/factory_node.py rename to src/cool_compiler/semantic/v0_parser_return/factory_node.py index 71d89f231..ff7af5597 100755 --- a/src/cool_compiler/semantic/factory_node.py +++ b/src/cool_compiler/semantic/v0_parser_return/factory_node.py @@ -1,4 +1,4 @@ -from .__dependency import factory, decored, Nodes +from ..__dependency import factory, decored, Nodes from .factory_return_ast import * @factory diff --git a/src/cool_compiler/semantic/factory_return_ast.py b/src/cool_compiler/semantic/v0_parser_return/factory_return_ast.py similarity index 100% rename from src/cool_compiler/semantic/factory_return_ast.py rename to src/cool_compiler/semantic/v0_parser_return/factory_return_ast.py 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..e787cc656 --- /dev/null +++ b/src/cool_compiler/semantic/v1_create_type/create_type_ast.py @@ -0,0 +1,146 @@ +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..28e5c8d76 --- /dev/null +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -0,0 +1,281 @@ +from .. import visitor +from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str +from ..v0_parser_return import factory_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: + self.cool_error = errors + self.current_type : Type = None + self.global_types = {} + + 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 + + + @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: self.current_type.set_parent(parent_type) + except SemanticError: pass + + 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) + self.current_type.define_attribute(node.name, atype) + + 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)) + + self.current_type.define_method(node.name, params, return_type) + 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, 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): + 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: + 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 = [] + for name, atype, expr in node.case_list: + rtype = self.get_type(atype, error_handler) + case_list.append((name, rtype, self.visit(expr))) + + 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 Int(), + + @visitor.when(AST.Bool) + @visitor.result(ASTR.Bool) + def visit(self, node: AST.Bool): + return Bool(), + + @visitor.when(AST.Str) + @visitor.result(ASTR.Str) + def visit(self, node: AST.Str): + return Str(), diff --git a/src/cool_compiler/semantic/visitor.py b/src/cool_compiler/semantic/visitor.py index fe418399c..f96015194 100755 --- a/src/cool_compiler/semantic/visitor.py +++ b/src/cool_compiler/semantic/visitor.py @@ -62,7 +62,7 @@ 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_index = self.__argspec(fn).args.index(param_name) + 1 self.param_name = param_name self.targets = {} diff --git a/src/makefile b/src/makefile index 8d32826f7..b999fcf4e 100755 --- a/src/makefile +++ b/src/makefile @@ -1,7 +1,7 @@ .PHONY: clean main: - python -m cool_compiler assignment1.cl + python -m cool_compiler test.cl clean: rm -rf build/* diff --git a/src/test.cl b/src/test.cl new file mode 100755 index 000000000..bf94eb194 --- /dev/null +++ b/src/test.cl @@ -0,0 +1,11 @@ +--The static types of the two sub-expressions must be Int. + +class A { }; +class B inherits A { }; +class C inherits B { }; + +class Main inherits IO { + main(): IO { out_string("Hello World!")}; + test: Int <- let x: Int <- 1 * 2 / 3 - 4 + new A.type_name().concat(new B.type_name().concat(new C.type_name())).length() + in x <- x + new A.type_name().concat(new B.type_name().concat(new C.type_name())); +}; \ No newline at end of file From 7df3c47786f47128b52723ed276b6245cdb73134 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 7 Oct 2021 21:46:31 -0400 Subject: [PATCH 09/91] add dependency --- poetry.lock | 24 ++++++------------------ pyproject.toml | 7 +++---- requirements.txt | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 24 deletions(-) mode change 100755 => 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock index ee30530e7..19f8bab93 100755 --- a/poetry.lock +++ b/poetry.lock @@ -58,14 +58,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["pre-commit", "tox"] -[[package]] -name = "ply" -version = "3.11" -description = "Python Lex & Yacc" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "py" version = "1.10.0" @@ -84,7 +76,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.2" +version = "6.2.5" description = "pytest: simple powerful testing with Python" category = "main" optional = false @@ -96,7 +88,7 @@ attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0.0a1" +pluggy = ">=0.12,<2.0" py = ">=1.8.2" toml = "*" @@ -135,8 +127,8 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [metadata] lock-version = "1.1" -python-versions = "3.8.5" -content-hash = "27b884dfe56b92705f08ba9a9cf886bc788e356820b4779be6dcb1847ab3f0b3" +python-versions = "^3.9" +content-hash = "5edf913efffb65061b83385f4e01535f97f8abfbe3aab973cca6f020cce77903" [metadata.files] atomicwrites = [ @@ -163,10 +155,6 @@ pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] -ply = [ - {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, - {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, -] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, @@ -176,8 +164,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, - {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] pytest-ordering = [ {file = "pytest-ordering-0.6.tar.gz", hash = "sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6"}, diff --git a/pyproject.toml b/pyproject.toml old mode 100755 new mode 100644 index 538c6512c..cc0a71b70 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,14 @@ [tool.poetry] -name = "cmp" +name = "cool-compiler-2021" version = "0.1.0" description = "" authors = ["dany"] [tool.poetry.dependencies] -python = "3.8.5" -pytest = "^6.2.2" +python = "^3.9" +pytest = "^6.2.5" pytest-ordering = "^0.6" sly = "^0.4" -ply = "^3.11" [tool.poetry.dev-dependencies] diff --git a/requirements.txt b/requirements.txt index 9eb0cad1a..4bcbc1bd3 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,36 @@ -pytest -pytest-ordering +atomicwrites==1.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.4.0" \ + --hash=sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197 \ + --hash=sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a +attrs==20.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ + --hash=sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6 \ + --hash=sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700 +colorama==0.4.4; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0" \ + --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ + --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b +iniconfig==1.1.1; python_version >= "3.6" \ + --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ + --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 +packaging==20.9; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ + --hash=sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a \ + --hash=sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5 +pluggy==0.13.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ + --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d \ + --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 +py==1.10.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ + --hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a \ + --hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 +pyparsing==2.4.7; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ + --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ + --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 +pytest-ordering==0.6 \ + --hash=sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6 \ + --hash=sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2 \ + --hash=sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6 +pytest==6.2.5; python_version >= "3.6" \ + --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134 \ + --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 +sly==0.4 \ + --hash=sha256:e5f2266a231322cc17519fbc3a3ba1c6335fed5a9a55abe0e598a35aea0ac32a +toml==0.10.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6" \ + --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ + --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f From 0e126ae11ae69ba1545c9df135d26233cd566b9b Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Sat, 23 Oct 2021 13:08:10 -0400 Subject: [PATCH 10/91] refactor(semantic-checking): rename and refactor import --- src/cool_compiler/semantic/__init__.py | 2 +- src/cool_compiler/semantic/__main__.py | 2 -- src/cool_compiler/semantic/tools.py | 2 +- .../{factory_return_ast.py => factory_parser_return_ast.py} | 0 .../{factory_node.py => factory_parser_return_visitor.py} | 2 +- .../semantic/v1_create_type/create_type_visitor.py | 2 +- src/cool_compiler/semantic/{ => v2_semantic_checking}/scope.py | 0 7 files changed, 4 insertions(+), 6 deletions(-) delete mode 100755 src/cool_compiler/semantic/__main__.py rename src/cool_compiler/semantic/v0_parser_return/{factory_return_ast.py => factory_parser_return_ast.py} (100%) rename src/cool_compiler/semantic/v0_parser_return/{factory_node.py => factory_parser_return_visitor.py} (99%) rename src/cool_compiler/semantic/{ => v2_semantic_checking}/scope.py (100%) diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py index 23a8d3bbd..18ec75f81 100755 --- a/src/cool_compiler/semantic/__init__.py +++ b/src/cool_compiler/semantic/__init__.py @@ -1,2 +1,2 @@ -from .v0_parser_return.factory_node import CoolFactory +from .v0_parser_return.factory_parser_return_visitor import CoolFactory from .v1_create_type.create_type_visitor import CoolCreateType as CreateType \ No newline at end of file diff --git a/src/cool_compiler/semantic/__main__.py b/src/cool_compiler/semantic/__main__.py deleted file mode 100755 index 76c5c7dc3..000000000 --- a/src/cool_compiler/semantic/__main__.py +++ /dev/null @@ -1,2 +0,0 @@ -def semantic_checking(ast): - pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py index a7827a774..5ef41be05 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -1,6 +1,6 @@ from cool_compiler.semantic.visitor import result from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object -from .scope import Scope +from .v2_semantic_checking.scope import Scope def defVisitClass(*func): class Visit(VisitBase): diff --git a/src/cool_compiler/semantic/v0_parser_return/factory_return_ast.py b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_ast.py similarity index 100% rename from src/cool_compiler/semantic/v0_parser_return/factory_return_ast.py rename to src/cool_compiler/semantic/v0_parser_return/factory_parser_return_ast.py diff --git a/src/cool_compiler/semantic/v0_parser_return/factory_node.py b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py similarity index 99% rename from src/cool_compiler/semantic/v0_parser_return/factory_node.py rename to src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py index ff7af5597..98b65d251 100755 --- a/src/cool_compiler/semantic/v0_parser_return/factory_node.py +++ b/src/cool_compiler/semantic/v0_parser_return/factory_parser_return_visitor.py @@ -1,5 +1,5 @@ from ..__dependency import factory, decored, Nodes -from .factory_return_ast import * +from .factory_parser_return_ast import * @factory class CoolFactory: 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 index 28e5c8d76..03656fb7c 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -1,6 +1,6 @@ from .. import visitor from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str -from ..v0_parser_return import factory_return_ast as AST +from ..v0_parser_return import factory_parser_return_ast as AST from . import create_type_ast as ASTR from ..tools import VisitBase, find_type diff --git a/src/cool_compiler/semantic/scope.py b/src/cool_compiler/semantic/v2_semantic_checking/scope.py similarity index 100% rename from src/cool_compiler/semantic/scope.py rename to src/cool_compiler/semantic/v2_semantic_checking/scope.py From d0f30f93a0c62a5ffc0a7108a6c5d1f4e259e5d9 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Sat, 23 Oct 2021 13:52:32 -0400 Subject: [PATCH 11/91] feat(semantic-checking): replaces visitor --- src/cool_compiler/__main__.py | 2 +- src/cool_compiler/semantic/__init__.py | 3 +- .../semantic/semantic_checking/__init__.py | 8 - .../semantic/semantic_checking/main.py | 77 ------ .../semantic/semantic_checking/node__.py | 16 -- .../semantic/semantic_checking/node_class.py | 27 --- .../semantic_checking/node_program.py | 12 - src/cool_compiler/semantic/tools.py | 29 +-- .../v1_create_type/create_type_ast.py | 1 - .../v1_create_type/create_type_visitor.py | 3 +- .../semantic_checking_ast.py} | 11 +- .../semantic_checking_visitor.py} | 221 ++++++++++-------- 12 files changed, 137 insertions(+), 273 deletions(-) delete mode 100755 src/cool_compiler/semantic/semantic_checking/__init__.py delete mode 100755 src/cool_compiler/semantic/semantic_checking/main.py delete mode 100755 src/cool_compiler/semantic/semantic_checking/node__.py delete mode 100755 src/cool_compiler/semantic/semantic_checking/node_class.py delete mode 100755 src/cool_compiler/semantic/semantic_checking/node_program.py rename src/cool_compiler/semantic/{semantic_checking/ast2_semantic_checking_return.py => v2_semantic_checking/semantic_checking_ast.py} (97%) mode change 100755 => 100644 rename src/cool_compiler/semantic/{semantic_checking/v2_semantic_checking.py => v2_semantic_checking/semantic_checking_visitor.py} (62%) mode change 100755 => 100644 diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 213eed299..86f359349 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -24,7 +24,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType ] + visitorList = [ CreateType, SemanticChecking ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/semantic/__init__.py b/src/cool_compiler/semantic/__init__.py index 18ec75f81..fd4d3a5af 100755 --- a/src/cool_compiler/semantic/__init__.py +++ b/src/cool_compiler/semantic/__init__.py @@ -1,2 +1,3 @@ from .v0_parser_return.factory_parser_return_visitor import CoolFactory -from .v1_create_type.create_type_visitor import CoolCreateType as CreateType \ No newline at end of file +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/semantic_checking/__init__.py b/src/cool_compiler/semantic/semantic_checking/__init__.py deleted file mode 100755 index 2ba994f35..000000000 --- a/src/cool_compiler/semantic/semantic_checking/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .main import CoolCreateType - -from .main import Program, CoolClass, AtrDef, FuncDef -from .main import StaticDispatch, CastingDispatch, Dispatch -from .main import Assing, IfThenElse, While, Block, LetIn, Case -from .main import Sum, Rest, Div, Mult, Less, LessOrEquals, Equals -from .main import New, Void, Neg, Complement, Id, Int, Str, Bool - diff --git a/src/cool_compiler/semantic/semantic_checking/main.py b/src/cool_compiler/semantic/semantic_checking/main.py deleted file mode 100755 index 5b922325c..000000000 --- a/src/cool_compiler/semantic/semantic_checking/main.py +++ /dev/null @@ -1,77 +0,0 @@ -from .. import visitor -from ..__dependency import Type -from ..tools import VisitorBase, -from .node_program import Program, VisitProgram, AST_Program -from .node_class import CoolClass, VisitCoolClass, AST_CoolClass -from .node_defattr import AtrDef, VisitAttrDef, AST_AtrDef -from .node_deffunc import FuncDef, VisitFuncDef, AST_FuncDef - -from .node_dispatch import CastingDispatch, VisitCastingDispatch, AST_CastingDispatch -from .node_dispatch import Dispatch, VisitDispatch, AST_Dispatch -from .node_dispatch import StaticDispatch, VisitStaticDispatch, AST_StaticDispatch - -from .node_statements import Assing, VisitAssing, AST_Assing -from .node_statements import IfThenElse, VisitIfThenElse, AST_IfThenElse -from .node_statements import While, VisitWhile, AST_While -from .node_statements import Block, VisitBlock, AST_Block -from .node_let import LetIn, VisitLetIn, AST_LetIn -from .node_case import Case, VisitCase, AST_Case - -from .node_binary import Sum, AST_Sum, VisitBinary -from .node_binary import Rest, AST_Rest -from .node_binary import Div, AST_Div -from .node_binary import Mult, AST_Mult -from .node_binary import Less, AST_Less -from .node_binary import LessOrEquals, AST_LessOrEquals -from .node_binary import Equals, AST_Equals - -from .node_atoms import Void, AST_Void, VisitAtomic -from .node_atoms import Neg, AST_Neg -from .node_atoms import Complement, AST_Complement -from .node_atoms import New, AST_New, VisitNew -from .node_atoms import Id, AST_Id, VisitEqualAtomic -from .node_atoms import Int, AST_Int -from .node_atoms import Str, AST_Str -from .node_atoms import Bool, AST_Bool - -class CoolSemanticChecking(VisitorBase): - @visitor.add(node_type= AST_Program, accion_class= VisitProgram, result= Program) - #class def - @visitor.add(node_type= AST_CoolClass, accion_class= VisitCoolClass, result= CoolClass) - @visitor.add(node_type= AST_AtrDef, accion_class= VisitAttrDef, result= AtrDef) - @visitor.add(node_type= AST_FuncDef, accion_class= VisitFuncDef, result= FuncDef) - # expr dispatch - @visitor.add(node_type= AST_CastingDispatch, accion_class= VisitCastingDispatch, result= CastingDispatch) - @visitor.add(node_type= AST_Dispatch, accion_class= VisitDispatch, result= Dispatch) - @visitor.add(node_type= AST_StaticDispatch, accion_class= VisitStaticDispatch, result= StaticDispatch) - # expr statement - @visitor.add(node_type= AST_Assing, accion_class= VisitAssing, result= Assing) - @visitor.add(node_type= AST_IfThenElse, accion_class= VisitIfThenElse, result= IfThenElse) - @visitor.add(node_type= AST_While, accion_class= VisitWhile, result= While) - @visitor.add(node_type= AST_Block, accion_class= VisitBlock, result= Block) - @visitor.add(node_type= AST_LetIn, accion_class= VisitLetIn, result= LetIn) - @visitor.add(node_type= AST_Case, accion_class= VisitCase, result= Case) - # expr binary - @visitor.add(node_type= AST_Sum, accion_class= VisitBinary, result= Sum) - @visitor.add(node_type= AST_Rest, accion_class= VisitBinary, result= Rest) - @visitor.add(node_type= AST_Div, accion_class= VisitBinary, result= Div) - @visitor.add(node_type= AST_Mult, accion_class= VisitBinary, result= Mult) - @visitor.add(node_type= AST_Less, accion_class= VisitBinary, result= Less) - @visitor.add(node_type= AST_LessOrEquals, accion_class= VisitBinary, result= LessOrEquals) - @visitor.add(node_type= AST_Equals, accion_class= VisitBinary, result= Equals) - # expr atomic - @visitor.add(node_type= AST_New, accion_class= VisitNew, result= New) - @visitor.add(node_type= AST_Neg, accion_class= VisitAtomic, result= Neg) - @visitor.add(node_type= AST_Complement, accion_class= VisitAtomic, result= Complement) - @visitor.add(node_type= AST_Void, accion_class= VisitAtomic, result= Void) - @visitor.add(node_type= AST_Id, accion_class= VisitEqualAtomic, result= Id) - @visitor.add(node_type= AST_Int, accion_class= VisitEqualAtomic, result= Int) - @visitor.add(node_type= AST_Str, accion_class= VisitEqualAtomic, result= Str) - @visitor.add(node_type= AST_Bool, accion_class= VisitEqualAtomic, result= Bool) - - def __init__(self, errors) -> None: - super().__init__(errors) - - @visitor.on("node") - def visit(node, scope): - pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/node__.py b/src/cool_compiler/semantic/semantic_checking/node__.py deleted file mode 100755 index db5d9b67c..000000000 --- a/src/cool_compiler/semantic/semantic_checking/node__.py +++ /dev/null @@ -1,16 +0,0 @@ -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 Feature(Node): - pass - -class Expresion(Node): - pass - -class Statement(Expresion): - pass diff --git a/src/cool_compiler/semantic/semantic_checking/node_class.py b/src/cool_compiler/semantic/semantic_checking/node_class.py deleted file mode 100755 index 0f342dd83..000000000 --- a/src/cool_compiler/semantic/semantic_checking/node_class.py +++ /dev/null @@ -1,27 +0,0 @@ -from .node__ import Node -from ..tools import VisitBase -from ..scope import Scope -from ..create_type import CoolClass as AST_CoolClass - -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 VisitCoolClass(VisitBase): - def visit(self, node: AST_CoolClass, scope : Scope): - cls_scope : Scope = scope.create_child() - self.gclss.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.gclss.current_type.name} has circular inheritance") - - cls_scope.define_variable('self', self.gclss.current_type) - for name, atype in node.type.ite_attributes: - if not cls_scope.is_local(name): - cls_scope.define_variable(name, atype) - - feature_list = self.visit_all(node.feature_list, cls_scope) - return node.type, node.parent_type, feature_list \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/node_program.py b/src/cool_compiler/semantic/semantic_checking/node_program.py deleted file mode 100755 index 90108f5e9..000000000 --- a/src/cool_compiler/semantic/semantic_checking/node_program.py +++ /dev/null @@ -1,12 +0,0 @@ -from .node__ import Node -from ..tools import defVisitClass -from ..scope import Scope -from ..create_type import Program as AST_Program - -class Program(Node): - def __init__(self, class_list) -> None: - self.class_list = class_list - -VisitProgram = defVisitClass( - lambda self, node, error, scope = Scope() : self.gclss.visit_all(node.class_list, scope) -) \ No newline at end of file diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py index 5ef41be05..95b5cbca1 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -2,17 +2,11 @@ from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object from .v2_semantic_checking.scope import Scope -def defVisitClass(*func): - class Visit(VisitBase): - def visit(self, node,*args, **kw): - error_handler = self.gclss.get_se_handler(node) - result = [] - for f in func: - result.append(f(self, node, error_handler,*args, **kw)) - return tuple(result) - return Visit - 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_semantic_error ) @@ -39,22 +33,17 @@ def get_parent_type(self, node, error_handler): return ErrorType() return parent_type - - -class VisitorBase: - def __init__(self, error) -> None: - self.cool_error = error - self.current_type : Type = None - def type_checking(self, tbase : Type, ttype : Type): - if tbase.is_self_type : tbase = self.current_type - if ttype.is_self_type : ttype = self.current_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 ttype.conforms_to(tbase): + if not t_type.conforms_to(t_base): return False return True + class Result: def __init__(self, succ, result, error) -> None: self.succ = succ 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 index e787cc656..152258a7f 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_ast.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_ast.py @@ -19,7 +19,6 @@ def __init__(self, typee, parent_type, feature_list) -> None: class Feature(Node): pass - class AtrDef(Feature): def __init__(self, name, atype, expr) -> None: self.name = name 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 index 03656fb7c..740244651 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -6,8 +6,7 @@ class CoolCreateType(VisitBase): def __init__(self, errors) -> None: - self.cool_error = errors - self.current_type : Type = None + super().__init__(errors) self.global_types = {} def get_parent_type(self, node, error_handler): diff --git a/src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py old mode 100755 new mode 100644 similarity index 97% rename from src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py rename to src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py index 4e4672d73..6d24d97ff --- a/src/cool_compiler/semantic/semantic_checking/ast2_semantic_checking_return.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_ast.py @@ -7,9 +7,10 @@ def get_pos_to_error(self, lineno, index): 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 @@ -155,6 +156,4 @@ class Str(Atomic): pass class Bool(Atomic): - pass - - + pass \ No newline at end of file diff --git a/src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py old mode 100755 new mode 100644 similarity index 62% rename from src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py rename to src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py index 5bd204088..ea73eec6b --- a/src/cool_compiler/semantic/semantic_checking/v2_semantic_checking.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -1,27 +1,44 @@ -from typing import SupportsComplex -from .ASTs import ast1_create_type_return as AST_init -from .ASTs import ast2_semantic_checking_return as AST_result -from . import visitor +from ..tools import VisitBase, find_type +from .. import visitor +from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str +from ..v1_create_type import create_type_ast as AST +from . import semantic_checking_ast as ASTR from .scope import Scope -from .__dependency import Type, SemanticError, ErrorType, Int, Bool, Object, Str -from .tools import VisitorBase, type_checking, find_variable, parent_common -from .semantic_checking_funcs import * - -class SemanticChecking(VisitorBase): - def __init__(self, error) -> None: - super().__init__(error) - self.casting_error_type = lambda a,b : a if not type(a) is ErrorType else b + +class CoolSemanticChecking(VisitBase): + def __init__(self, errors) -> None: + super().__init__(errors) @visitor.on("node") - def visit(self, node, scope) -> AST_result.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() + 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_init.AtrDef) - @visitor.result(AST_result.AtrDef) - def visit(self, node: AST_init.AtrDef, scope: Scope) -> AST_result.Node: + @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: @@ -36,19 +53,19 @@ def visit(self, node: AST_init.AtrDef, scope: Scope) -> AST_result.Node: error_handler().add_semantic_error(f"can't save {expr.static_type.name} into {node.type}") return node.name, node.type, expr - - @visitor.when(AST_init.FuncDef) - @visitor.result(AST_result.FuncDef) - def visit(self, node: AST_init.FuncDef, scope : Scope) -> AST_result.Node: + + @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) - for pn, fn in zip(node.params, func.params): - name, tparams = pn - _, tbase_params = fn - if not self.type_checking(tbase_params, tparams): + 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): @@ -57,19 +74,19 @@ def visit(self, node: AST_init.FuncDef, scope : Scope) -> AST_result.Node: pass new_scope : Scope = scope.create_child() - for param, ptype in node.params: - new_scope.define_variable(param, ptype) + for param, p_type in node.params: + new_scope.define_variable(param, p_type) expr = self.visit(node.expr, new_scope) - if not type_checking(node.return_type, expr.static_type): + if not self.type_checking(node.return_type, expr.static_type): self.cool_error(node.lineno, node.index).add_type_error(node.return_type.name, expr.static_type.name ) return node.name, node.params, node.return_type, expr - - @visitor.when(AST_init.CastingDispatch) - @visitor.result(AST_result.CastingDispatch) - def visit(self, node: AST_init.CastingDispatch, scope: Scope) -> AST_result.Node: + + @visitor.when(AST.CastingDispatch) + @visitor.result(ASTR.CastingDispatch) + def visit(self, node: AST.CastingDispatch, scope: Scope) -> ASTR.Node: expr = self.visit(node.expr, scope) if not expr.static_type.conforms_to(node.type): @@ -92,9 +109,9 @@ def visit(self, node: AST_init.CastingDispatch, scope: Scope) -> AST_result.Node return expr, node.type, node.id, params, static_type - @visitor.when(AST_init.Dispatch) - @visitor.result(AST_result.Dispatch) - def visit(self, node: AST_init.Dispatch, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Dispatch) + @visitor.result(ASTR.Dispatch) + def visit(self, node: AST.Dispatch, scope: Scope) -> ASTR.Node: expr = self.visit(node.expr, scope) params = [] @@ -114,9 +131,9 @@ def visit(self, node: AST_init.Dispatch, scope: Scope) -> AST_result.Node: return expr, node.id, params, static_type - @visitor.when(AST_init.StaticDispatch) - @visitor.result(AST_result.StaticDispatch) - def visit(self, node: AST_init.StaticDispatch, scope: Scope) -> AST_result.Node: + @visitor.when(AST.StaticDispatch) + @visitor.result(ASTR.StaticDispatch) + def visit(self, node: AST.StaticDispatch, scope: Scope) -> ASTR.Node: params = [] for p in node.params: params.append(self.visit(p,scope)) @@ -134,9 +151,9 @@ def visit(self, node: AST_init.StaticDispatch, scope: Scope) -> AST_result.Node: return node.id, params, static_type - @visitor.when(AST_init.Assing) - @visitor.result(AST_result.Assing) - def visit(self, node: AST_init.Assing, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Assing) + @visitor.result(ASTR.Assing) + def visit(self, node: AST.Assing, scope: Scope) -> ASTR.Node: try: v = scope.find_variable(node.id) static_type = v.type @@ -149,9 +166,9 @@ def visit(self, node: AST_init.Assing, scope: Scope) -> AST_result.Node: return node.id, expr, self.casting_error_type(static_type, expr.static_type) - @visitor.when(AST_init.IfThenElse) - @visitor.result(AST_result.IfThenElse) - def visit(self, node: AST_init.IfThenElse, scope: Scope) -> AST_result.Node: + @visitor.when(AST.IfThenElse) + @visitor.result(ASTR.IfThenElse) + def visit(self, node: AST.IfThenElse, scope: Scope) -> ASTR.Node: cond = self.visit(node.condition, scope) self.type_checking(Bool(), cond.static_type, node) @@ -160,26 +177,26 @@ def visit(self, node: AST_init.IfThenElse, scope: Scope) -> AST_result.Node: return cond, then_expr, else_expr, self.parent_common(then_expr.static_type, else_expr.static_type) - @visitor.when(AST_init.While) - @visitor.result(AST_result.While) - def visit(self, node: AST_init.While, scope: Scope) -> AST_result.Node: + @visitor.when(AST.While) + @visitor.result(ASTR.While) + def visit(self, node: AST.While, scope: Scope) -> ASTR.Node: cond = self.visit(node.condition, scope) self.type_checking(Bool(), cond.static_type, node) return cond, self.visit(node.loop_expr, scope), Object() - @visitor.when(AST_init.Block) - @visitor.result(AST_result.Block) - def visit(self, node: AST_init.Block, scope: Scope) -> AST_result.Node: + @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 - @visitor.when(AST_init.LetIn) - @visitor.result(AST_result.LetIn) - def visit(self, node: AST_init.LetIn, scope: Scope) -> AST_result.Node: + @visitor.when(AST.LetIn) + @visitor.result(ASTR.LetIn) + def visit(self, node: AST.LetIn, scope: Scope) -> ASTR.Node: new_scope = scope.create_child() assing_list = [] @@ -192,9 +209,9 @@ def visit(self, node: AST_init.LetIn, scope: Scope) -> AST_result.Node: expr = self.visit(node.expr, new_scope) return assing_list, expr, expr.static_type - @visitor.when(AST_init.Case) - @visitor.result(AST_result.Case) - def visit(self, node: AST_init.Case, scope: Scope) -> AST_result.Node: + @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 @@ -210,9 +227,9 @@ def visit(self, node: AST_init.Case, scope: Scope) -> AST_result.Node: return expr_cond, case_list, static_type - @visitor.when(AST_init.Sum) - @visitor.result(AST_result.Sum) - def visit(self, node: AST_init.Sum, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Sum) + @visitor.result(ASTR.Sum) + def visit(self, node: AST.Sum, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -221,9 +238,9 @@ def visit(self, node: AST_init.Sum, scope: Scope) -> AST_result.Node: return left, right, Int() - @visitor.when(AST_init.Rest) - @visitor.result(AST_result.Rest) - def visit(self, node: AST_init.Rest, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Rest) + @visitor.result(ASTR.Rest) + def visit(self, node: AST.Rest, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -232,9 +249,9 @@ def visit(self, node: AST_init.Rest, scope: Scope) -> AST_result.Node: return left, right, Int() - @visitor.when(AST_init.Mult) - @visitor.result(AST_result.Mult) - def visit(self, node: AST_init.Mult, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Mult) + @visitor.result(ASTR.Mult) + def visit(self, node: AST.Mult, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -243,9 +260,9 @@ def visit(self, node: AST_init.Mult, scope: Scope) -> AST_result.Node: return left, right, Int() - @visitor.when(AST_init.Div) - @visitor.result(AST_result.Div) - def visit(self, node: AST_init.Div, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Div) + @visitor.result(ASTR.Div) + def visit(self, node: AST.Div, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -254,9 +271,9 @@ def visit(self, node: AST_init.Div, scope: Scope) -> AST_result.Node: return left, right, Int() - @visitor.when(AST_init.Less) - @visitor.result(AST_result.Less) - def visit(self, node: AST_init.Less, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Less) + @visitor.result(ASTR.Less) + def visit(self, node: AST.Less, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -265,9 +282,9 @@ def visit(self, node: AST_init.Less, scope: Scope) -> AST_result.Node: return left, right, Bool() - @visitor.when(AST_init.LessOrEquals) - @visitor.result(AST_result.LessOrEquals) - def visit(self, node: AST_init.LessOrEquals, scope: Scope) -> AST_result.Node: + @visitor.when(AST.LessOrEquals) + @visitor.result(ASTR.LessOrEquals) + def visit(self, node: AST.LessOrEquals, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) self.type_checking(Int(), left.static_type, node) @@ -276,9 +293,9 @@ def visit(self, node: AST_init.LessOrEquals, scope: Scope) -> AST_result.Node: return left, right, Bool() - @visitor.when(AST_init.Equals) - @visitor.result(AST_result.Equals) - def visit(self, node: AST_init.Equals, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Equals) + @visitor.result(ASTR.Equals) + def visit(self, node: AST.Equals, scope: Scope) -> ASTR.Node: left = self.visit(node.left, scope) right = self.visit(node.right, scope) list_type = [ Str, Int, Bool] @@ -288,33 +305,33 @@ def visit(self, node: AST_init.Equals, scope: Scope) -> AST_result.Node: return left, right, Bool() - @visitor.when(AST_init.Void) - @visitor.result(AST_result.Void) - def visit(self, node: AST_init.Void, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Void) + @visitor.result(ASTR.Void) + def visit(self, node: AST.Void, scope: Scope) -> ASTR.Node: return self.visit(node.item, scope), Bool() - @visitor.when(AST_init.New) - @visitor.result(AST_result.New) - def visit(self, node: AST_init.New, scope: Scope) -> AST_result.Node: + @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_init.Complement) - @visitor.result(AST_result.Complement) - def visit(self, node: AST_init.Complement, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Complement) + @visitor.result(ASTR.Complement) + def visit(self, node: AST.Complement, scope: Scope) -> ASTR.Node: expr = self.visit(node.item, scope) self.type_checking(Int(), expr.static_type, node) return expr, Int() - @visitor.when(AST_init.Neg) - @visitor.result(AST_result.Neg) - def visit(self, node: AST_init.Neg, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Neg) + @visitor.result(ASTR.Neg) + def visit(self, node: AST.Neg, scope: Scope) -> ASTR.Node: expr = self.visit(node.item, scope) self.type_checking(Bool(), expr.static_type) return expr, Bool() - @visitor.when(AST_init.Id) - @visitor.result(AST_result.Id) - def visit(self, node: AST_init.Id, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Id) + @visitor.result(ASTR.Id) + def visit(self, node: AST.Id, scope: Scope) -> ASTR.Node: try: v = scope.find_variable(node.item) return node.item, v.type @@ -322,17 +339,17 @@ def visit(self, node: AST_init.Id, scope: Scope) -> AST_result.Node: self.cool_error(node.lineno, node.index).add_name_error(node.item) return node.item, ErrorType() - @visitor.when(AST_init.Int) - @visitor.result(AST_result.Int) - def visit(self, node: AST_init.Int, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Int) + @visitor.result(ASTR.Int) + def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: return node.item, Int() - @visitor.when(AST_init.Bool) - @visitor.result(AST_result.Bool) - def visit(self, node: AST_init.Bool, scope: Scope) -> AST_result.Node: + @visitor.when(AST.Bool) + @visitor.result(ASTR.Bool) + def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: return node.item, Bool() - @visitor.when(AST_init.Str) - @visitor.result(AST_result.Str) - def visit(self, node: AST_init.Str, scope: Scope) -> AST_result.Node: - return node.item, Str() + @visitor.when(AST.Str) + @visitor.result(ASTR.Str) + def visit(self, node: AST.Str, scope: Scope) -> ASTR.Node: + return node.item, Str() \ No newline at end of file From 1e0c6e013ad4879ca5c4d433ac0cc597ff44ff2b Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Mon, 25 Oct 2021 21:44:26 -0400 Subject: [PATCH 12/91] feat(semantic): finish checking --- src/cool_compiler/error/error.py | 7 +- src/cool_compiler/parser/cool_parser.py | 6 +- src/cool_compiler/semantic/__dependency.py | 1 + src/cool_compiler/semantic/tools.py | 9 +- .../v1_create_type/create_type_visitor.py | 46 ++++-- .../semantic_checking_visitor.py | 154 ++++++++++++------ src/cool_compiler/types/type.py | 9 + 7 files changed, 166 insertions(+), 66 deletions(-) diff --git a/src/cool_compiler/error/error.py b/src/cool_compiler/error/error.py index 18568ad70..48fc9c26f 100755 --- a/src/cool_compiler/error/error.py +++ b/src/cool_compiler/error/error.py @@ -1,3 +1,6 @@ +from cool_compiler.types.build_in_types import self + + class CoolError: def __init__(self, code : str) -> None: self._list = [] @@ -26,7 +29,7 @@ def find_column(self, index): def __add(self, etype, text): self._list.append(f'{self.pos} - {etype}: {text}') - def get_handler(self, lineno, index): + def get_handler(self, lineno, index) -> self: l = lineno + 0 i = index + 0 return lambda : self.__call__(l,i) @@ -40,7 +43,7 @@ def add_syntactic(self, text): def add_name_error(self, text): self.__add("NameError", text) - def add_type_error(self, basee, ttype): + def add_type_error(self, basee, ttype = ''): self.__add("TypeError", f'{basee} {ttype}') def add_attribute_error(self, ttype, attr): diff --git a/src/cool_compiler/parser/cool_parser.py b/src/cool_compiler/parser/cool_parser.py index 31a5e87ae..50eae631f 100755 --- a/src/cool_compiler/parser/cool_parser.py +++ b/src/cool_compiler/parser/cool_parser.py @@ -12,9 +12,9 @@ class CoolParser(Parser): ('left', '+', '-'), ('left', '*', '/'), ('left', "ISVOID"), - ('left', '.'), - ('left', '@'), ('left', '~'), + ('left', '@'), + ('left', '.'), ('right', 'IN'), ) def __init__(self, factory, errors): @@ -189,7 +189,7 @@ def let_assign(self, prod): @_('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.expr, prod.case_list) + return self.factory( NodesName.Case, prod.case_list, prod.expr) @_('ID ":" TYPE LOGICAR expr ";" case_list') def case_list(self, prod): diff --git a/src/cool_compiler/semantic/__dependency.py b/src/cool_compiler/semantic/__dependency.py index 09c1f85e6..806761518 100755 --- a/src/cool_compiler/semantic/__dependency.py +++ b/src/cool_compiler/semantic/__dependency.py @@ -10,3 +10,4 @@ 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/tools.py b/src/cool_compiler/semantic/tools.py index 95b5cbca1..84b124a44 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -1,5 +1,5 @@ from cool_compiler.semantic.visitor import result -from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object +from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object, CoolError from .v2_semantic_checking.scope import Scope class VisitBase: @@ -9,7 +9,7 @@ def __init__(self, error) -> 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_semantic_error ) + return find_result.get_value( if_fail_do= error_handler().add_type_error ) def visit_all(self, list_node, *args): result = [] @@ -73,9 +73,10 @@ def find_type(name, global_types) -> Result: except SemanticError as se: return Result.fail( se.text, neutro = ErrorType() ) -def parent_common(self, t1: Type, t2: Type): +def parent_common(t1: Type, t2: Type): while True: - if None in (t1,t2): return Object() + 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 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 index 740244651..58041aa05 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -1,5 +1,6 @@ +from os import confstr from .. import visitor -from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str +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 @@ -7,13 +8,14 @@ class CoolCreateType(VisitBase): def __init__(self, errors) -> None: super().__init__(errors) - self.global_types = {} + 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_semantic_error ) + 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}" ) @@ -21,7 +23,6 @@ def get_parent_type(self, node, error_handler): return parent_type - @visitor.on("node") def visit(node): pass @@ -42,12 +43,19 @@ def visit(self, node : AST.Program) : @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: self.current_type.set_parent(parent_type) - except SemanticError: pass - + 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 @@ -58,7 +66,9 @@ def visit(self, node : AST.AtrDef) : error_handler = self.get_se_handler(node) atype = self.get_type(node.type, error_handler) - self.current_type.define_attribute(node.name, atype) + 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 @@ -75,7 +85,10 @@ def visit(self, node : AST.FuncDef) : param_type = self.get_type(ptype, error_handler) params.append((name, param_type)) - self.current_type.define_method(node.name, params, return_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 @@ -85,7 +98,7 @@ def visit(self, node: AST.CastingDispatch): error = self.get_se_handler(node) return tuple([ self.visit(node.expr), - self.get_type(node, error), + self.get_type(node.type, error), node.id, self.visit_all(node.params) ]) @@ -110,6 +123,10 @@ def visit(self, node: AST.StaticDispatch): @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) @@ -155,6 +172,8 @@ def visit(self, node : AST.LetIn) : 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))) @@ -166,9 +185,14 @@ 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: - rtype = self.get_type(atype, error_handler) + 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 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 index ea73eec6b..fbe849544 100644 --- a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -1,4 +1,5 @@ -from ..tools import VisitBase, find_type +from os import error +from ..tools import VisitBase, find_type, parent_common from .. import visitor from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str from ..v1_create_type import create_type_ast as AST @@ -49,8 +50,8 @@ def visit(self, node: AST.AtrDef, scope: Scope) -> ASTR.Node: pass expr = self.visit(node.expr, scope) - if not self.type_checking(node.type, expr.static_type): - error_handler().add_semantic_error(f"can't save {expr.static_type.name} into {node.type}") + 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 @@ -62,6 +63,9 @@ def visit(self, node: AST.FuncDef, scope : Scope) -> ASTR.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 @@ -78,19 +82,19 @@ def visit(self, node: AST.FuncDef, scope : Scope) -> ASTR.Node: 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): - self.cool_error(node.lineno, node.index).add_type_error(node.return_type.name, expr.static_type.name ) + 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 expr.static_type.conforms_to(node.type): - self.cool_error(node.lineno, node.index).add_type_error(node.type, expr.static_type.name ) + 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: @@ -99,19 +103,23 @@ def visit(self, node: AST.CastingDispatch, scope: Scope) -> ASTR.Node: 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 exp.static_type.conforms_to(tupl[1]): - self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + 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: - self.cool_error(node.lineno, node.index).add_attribute_error(node.type, node.id ) + error_handler().add_attribute_error(node.type.name, node.id ) - return expr, node.type, node.id, params, static_type + return expr, node.type, node.id, params, expr.static_type if static_type.is_self_type else static_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 = [] @@ -121,19 +129,25 @@ def visit(self, node: AST.Dispatch, scope: Scope) -> ASTR.Node: 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 exp.static_type.conforms_to(tupl[1]): - self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + 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: - self.cool_error(node.lineno, node.index).add_attribute_error(expr.static_type.name, node.id ) + error_handler().add_attribute_error(expr.static_type.name, node.id ) - return expr, node.id, params, static_type + return expr, node.id, params, expr.static_type if static_type.is_self_type else static_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)) @@ -141,47 +155,57 @@ def visit(self, node: AST.StaticDispatch, scope: Scope) -> ASTR.Node: 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 exp.static_type.conforms_to(tupl[1]): - self.cool_error(node.lineno, node.index).add_type_error(tupl[1].name, exp.static_type.name ) + 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: - self.cool_error(node.lineno, node.index).add_attribute_error(self.current_type.name, node.id ) + error_handler().add_attribute_error(self.current_type.name, node.id ) return node.id, params, static_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: - self.cool_error(node.lineno, node.index).add_name_error(node.id) + error_handler().add_name_error(node.id) static_type = ErrorType() expr = self.visit(node.expr, scope) - self.type_checking(static_type, expr.static_type, node) + 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, self.casting_error_type(static_type, expr.static_type) + return node.id, expr, expr.static_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) - self.type_checking(Bool(), cond.static_type, node) + if not self.type_checking(Bool(), 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, self.parent_common(then_expr.static_type, else_expr.static_type) + return cond, then_expr, else_expr, parent_common(then_expr.static_type, else_expr.static_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) - self.type_checking(Bool(), cond.static_type, node) + if not self.type_checking(Bool(), cond.static_type): + error_handler().add_type_error("Bool", cond.static_type.name) return cond, self.visit(node.loop_expr, scope), Object() @@ -197,12 +221,17 @@ def visit(self, node: AST.Block, scope: Scope) -> ASTR.Node: @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() assing_list = [] for name, atype, expr in node.assing_list: - exp = self.visit(expr, new_scope) - self.type_checking(atype, exp.static_type, node) + 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) @@ -222,7 +251,7 @@ def visit(self, node: AST.Case, scope: Scope) -> ASTR.Node: exp = self.visit(expr, new_scope) if static_type is None: static_type = exp.static_type - else: static_type = self.parent_common(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 @@ -230,78 +259,103 @@ def visit(self, node: AST.Case, scope: Scope) -> ASTR.Node: @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Int() @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Int() @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Int() @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Int() @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Bool() @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) - self.type_checking(Int(), left.static_type, node) + if not self.type_checking(Int(), left.static_type): + error_handler().add_type_error("Int", left.static_type.name) right = self.visit(node.right, scope) - self.type_checking(Int(), right.static_type, node) + if not self.type_checking(Int(), right.static_type): + error_handler().add_type_error("Int", right.static_type.name) return left, right, Bool() @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 = [ Str, Int, Bool] + if type(left.static_type) in list_type or type(right.static_type) in list_type: - if left.static_type == right.static_type: - self.cool_error(node.lineno, node.index).add_type_error(left.static_type.name, right.static_type.name) + if not left.static_type == right.static_type: + error_handler().add_type_error(left.static_type.name, right.static_type.name) return left, right, Bool() @@ -318,26 +372,34 @@ def visit(self, node: AST.New, scope: Scope) -> ASTR.Node: @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) - self.type_checking(Int(), expr.static_type, node) + if not self.type_checking(Int(), expr.static_type): + error_handler().add_type_error("Int", expr.static_type.name) return expr, Int() @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) - self.type_checking(Bool(), expr.static_type) + if not self.type_checking(Bool(), expr.static_type): + error_handler().add_type_error("Bool", expr.static_type.name) return expr, Bool() @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 SemanticError: - self.cool_error(node.lineno, node.index).add_name_error(node.item) - return node.item, ErrorType() + 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) diff --git a/src/cool_compiler/types/type.py b/src/cool_compiler/types/type.py index 110828041..0c9942e26 100755 --- a/src/cool_compiler/types/type.py +++ b/src/cool_compiler/types/type.py @@ -59,6 +59,8 @@ def get_attribute(self, name:str) -> Attribute: 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: @@ -84,6 +86,12 @@ 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 @@ -117,6 +125,7 @@ def __str__(self): def __repr__(self): return str(self) + \ No newline at end of file From 00162bb98651af0163c56f5e7f04884098da1812 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 17 Nov 2021 20:29:45 -0500 Subject: [PATCH 13/91] add md off teacher --- .DS_Store | Bin 6148 -> 6148 bytes doc/content/chap0.pmd | 307 ++++++++ doc/content/chap1.pmd | 292 +++++++ doc/content/chap2.pmd | 716 +++++++++++++++++ doc/content/chap3.pmd | 1043 +++++++++++++++++++++++++ doc/content/chap4.pmd | 596 ++++++++++++++ doc/content/chap5.pmd | 808 +++++++++++++++++++ doc/content/chap6.pmd | 446 +++++++++++ doc/content/chap7.pmd | 441 +++++++++++ doc/content/chap8.pmd | 1711 +++++++++++++++++++++++++++++++++++++++++ src/test.cl | 18 +- 11 files changed, 6375 insertions(+), 3 deletions(-) create mode 100644 doc/content/chap0.pmd create mode 100644 doc/content/chap1.pmd create mode 100644 doc/content/chap2.pmd create mode 100644 doc/content/chap3.pmd create mode 100644 doc/content/chap4.pmd create mode 100644 doc/content/chap5.pmd create mode 100644 doc/content/chap6.pmd create mode 100644 doc/content/chap7.pmd create mode 100644 doc/content/chap8.pmd diff --git a/.DS_Store b/.DS_Store index feca8613504bcd7430524202412f605a970dd548..85f438282170bd10ff0a3653a78a778c93f1ecd1 100644 GIT binary patch delta 353 zcmZoMXfc=|#>B)qF;R?_gMop8V`8F+EEA9c0?a_n$iN`LP+X9dlb;0SolGj&n7Ev= z9wfuekiwA9kepPGESr;ATw-8woso%|g_Vt+gM*8Miq2I zNG!=ng0e&M^K;81l9=$!yp;TMr~3TTyp&?F zLBS9i4h~KZ&UgWd>S{xCV;u!!3)5O1g=$M9104kuW3$>?P7ZNZLtD>;+{&uzn%cUV zK=%UyBhYtXzz?Ni)GQza>c6t!qP(2^ymX)lNHsGAjHu~2vtvy31U0|YPvDIgYL*v!lPi)FI`^H!$K>>T_YK$V*nnZGkn X<`+@q1Sv`Ysh@1Zqr5prWCb$-F<=f= 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.pmd b/doc/content/chap7.pmd new file mode 100644 index 000000000..678260d88 --- /dev/null +++ b/doc/content/chap7.pmd @@ -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.pmd b/doc/content/chap8.pmd new file mode 100644 index 000000000..24f4185b8 --- /dev/null +++ b/doc/content/chap8.pmd @@ -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/src/test.cl b/src/test.cl index bf94eb194..da79bbfe6 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,11 +1,23 @@ ---The static types of the two sub-expressions must be Int. +-- Missing type class A { }; class B inherits A { }; class C inherits B { }; +class D inherits B { }; +class E inherits B { }; +class F inherits A { }; class Main inherits IO { main(): IO { out_string("Hello World!")}; - test: Int <- let x: Int <- 1 * 2 / 3 - 4 + new A.type_name().concat(new B.type_name().concat(new C.type_name())).length() - in x <- x + new A.type_name().concat(new B.type_name().concat(new C.type_name())); + + b: B <- case "true" of + i: Int => New C; + b: Bool => New D; + s: String => New E; + esac; + + test: A <- case 0 of + b: Bool => new F; + i: Ball => new E; + esac; }; \ No newline at end of file From 0d81684262e1fda2004baa193bc1ee3ebe03ffe4 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 12 Jan 2022 19:34:52 -0500 Subject: [PATCH 14/91] reafctor semantic --- src/cool_compiler/__main__.py | 6 +- src/cool_compiler/cmp/visitor.py | 62 +++++----- src/cool_compiler/parser/cool_parser.py | 3 +- src/cool_compiler/semantic/ast_print.py | 2 +- src/cool_compiler/semantic/tools.py | 2 +- .../v1_create_type/create_type_visitor.py | 2 +- .../semantic/v2_semantic_checking/scope.py | 4 +- .../semantic_checking_visitor.py | 106 +++++++++--------- src/cool_compiler/semantic/visitor.py | 92 --------------- .../types/build_in_types/object.py | 4 +- .../types/build_in_types/self.py | 5 +- .../types/cool_type_build_in_manager.py | 10 ++ src/cool_compiler/types/type.py | 5 + 13 files changed, 126 insertions(+), 177 deletions(-) delete mode 100755 src/cool_compiler/semantic/visitor.py diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 86f359349..c721fcc94 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -4,6 +4,7 @@ from .parser import CoolParser from .semantic import * from .types import CoolTypeBuildInManager +from .codegen import CILGenerate path = "" if len(sys.argv) > 1: @@ -14,7 +15,8 @@ text = _file.read() errors = CoolError(text) lexer = CoolLexer(errors) - CoolTypeBuildInManager() + type_manager = CoolTypeBuildInManager() + type_manager.all_inherence_of_object() parser = CoolParser(CoolFactory(errors), errors) @@ -24,7 +26,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking ] + visitorList = [ CreateType, SemanticChecking, CILGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/cmp/visitor.py b/src/cool_compiler/cmp/visitor.py index 964842836..f96015194 100755 --- a/src/cool_compiler/cmp/visitor.py +++ b/src/cool_compiler/cmp/visitor.py @@ -1,29 +1,24 @@ -# 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 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) @@ -31,9 +26,26 @@ def f(fn): return f -def when(param_type): +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): - frame = inspect.currentframe().f_back + 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): @@ -50,7 +62,7 @@ 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_index = self.__argspec(fn).args.index(param_name) + 1 self.param_name = param_name self.targets = {} diff --git a/src/cool_compiler/parser/cool_parser.py b/src/cool_compiler/parser/cool_parser.py index 50eae631f..1365ed49a 100755 --- a/src/cool_compiler/parser/cool_parser.py +++ b/src/cool_compiler/parser/cool_parser.py @@ -14,8 +14,9 @@ class CoolParser(Parser): ('left', "ISVOID"), ('left', '~'), ('left', '@'), - ('left', '.'), ('right', 'IN'), + ('left', '.'), + ) def __init__(self, factory, errors): self.factory = factory diff --git a/src/cool_compiler/semantic/ast_print.py b/src/cool_compiler/semantic/ast_print.py index 643c33754..0e179bbc9 100755 --- a/src/cool_compiler/semantic/ast_print.py +++ b/src/cool_compiler/semantic/ast_print.py @@ -1,6 +1,6 @@ from .ASTs import ast0_factory_return as AST_init from .ASTs import ast1_create_type_return as AST_result -from . import visitor +from ..cmp import visitor class ASTPrint: def __init__(self, error) -> None: diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py index 84b124a44..1a648f6f5 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -1,4 +1,4 @@ -from cool_compiler.semantic.visitor import result +from cool_compiler.cmp.visitor import result from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object, CoolError from .v2_semantic_checking.scope import Scope 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 index 58041aa05..9bf38ea46 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -1,5 +1,5 @@ from os import confstr -from .. import visitor +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 diff --git a/src/cool_compiler/semantic/v2_semantic_checking/scope.py b/src/cool_compiler/semantic/v2_semantic_checking/scope.py index a8269368f..c7e46b95a 100755 --- a/src/cool_compiler/semantic/v2_semantic_checking/scope.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/scope.py @@ -11,6 +11,7 @@ def __str__(self): class Scope: def __init__(self, parent=None): + self.name = "Program" self.locals = [] self.parent = parent self.children = [] @@ -19,8 +20,9 @@ def __init__(self, parent=None): def __len__(self): return len(self.locals) - def create_child(self,): + def create_child(self, name=None): child = Scope(self) + child.name = name self.children.append(child) return child 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 index fbe849544..f3f406f71 100644 --- a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -1,11 +1,17 @@ -from os import error -from ..tools import VisitBase, find_type, parent_common -from .. import visitor -from ..__dependency import Type, SemanticError, Object, ErrorType, Int, Bool, Str +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 .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) @@ -22,7 +28,7 @@ def visit(self, node : AST.Program, scope = Scope()) : @visitor.when(AST.CoolClass) @visitor.result(ASTR.CoolClass) def visit(self, node : AST.CoolClass, scope: Scope) : - cls_scope : Scope = scope.create_child() + cls_scope : Scope = scope.create_child(f"Class {node.type.name}") self.current_type = node.type error_handler = self.get_se_handler(node) @@ -77,7 +83,7 @@ def visit(self, node: AST.FuncDef, scope : Scope) -> ASTR.Node: except SemanticError as se: pass - new_scope : Scope = scope.create_child() + new_scope : Scope = scope.create_child(f"Func {node.name}") for param, p_type in node.params: new_scope.define_variable(param, p_type) @@ -114,7 +120,7 @@ def visit(self, node: AST.CastingDispatch, scope: Scope) -> ASTR.Node: except SemanticError: error_handler().add_attribute_error(node.type.name, node.id ) - return expr, node.type, node.id, params, expr.static_type if static_type.is_self_type else static_type + 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) @@ -141,13 +147,12 @@ def visit(self, node: AST.Dispatch, scope: Scope) -> ASTR.Node: except SemanticError: error_handler().add_attribute_error(expr.static_type.name, node.id ) - return expr, node.id, params, expr.static_type if static_type.is_self_type else static_type + 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)) @@ -167,7 +172,7 @@ def visit(self, node: AST.StaticDispatch, scope: Scope) -> ASTR.Node: except SemanticError: error_handler().add_attribute_error(self.current_type.name, node.id ) - return node.id, params, static_type + return node.id, params, static_type.real_type(self.current_type) @visitor.when(AST.Assing) @visitor.result(ASTR.Assing) @@ -184,27 +189,27 @@ def visit(self, node: AST.Assing, scope: Scope) -> ASTR.Node: 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 + 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(Bool(), cond.static_type): + 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) + 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(Bool(), cond.static_type): + 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() @@ -216,18 +221,19 @@ def visit(self, node: AST.Block, scope: Scope) -> ASTR.Node: for b in node.expr_list: block_list.append(self.visit(b, scope)) - return block_list, block_list[-1].static_type + 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() + 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 @@ -236,7 +242,7 @@ def visit(self, node: AST.LetIn, scope: Scope) -> ASTR.Node: new_scope.define_variable(name,atype) expr = self.visit(node.expr, new_scope) - return assing_list, expr, expr.static_type + return assing_list, expr, expr.static_type.real_type(self.current_type) @visitor.when(AST.Case) @visitor.result(ASTR.Case) @@ -246,7 +252,7 @@ def visit(self, node: AST.Case, scope: Scope) -> ASTR.Node: static_type = None case_list = [] for name, atype , expr in node.case_list: - new_scope = scope.create_child() + new_scope = scope.create_child(f'Case {name}') new_scope.define_variable(name, atype) exp = self.visit(expr, new_scope) @@ -254,21 +260,21 @@ def visit(self, node: AST.Case, scope: Scope) -> ASTR.Node: else: static_type = parent_common(static_type, exp.static_type) case_list.append((name, atype, exp)) - return expr_cond, case_list, static_type + 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Int() + return left, right, CoolInt @visitor.when(AST.Rest) @visitor.result(ASTR.Rest) @@ -276,14 +282,14 @@ 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Int() + return left, right, CoolInt @visitor.when(AST.Mult) @visitor.result(ASTR.Mult) @@ -291,14 +297,14 @@ 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Int() + return left, right, CoolInt @visitor.when(AST.Div) @visitor.result(ASTR.Div) @@ -306,14 +312,14 @@ 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Int() + return left, right, CoolInt @visitor.when(AST.Less) @visitor.result(ASTR.Less) @@ -321,14 +327,14 @@ 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Bool() + return left, right, CoolBool @visitor.when(AST.LessOrEquals) @visitor.result(ASTR.LessOrEquals) @@ -336,14 +342,14 @@ 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(Int(), left.static_type): + 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(Int(), right.static_type): + if not self.type_checking(CoolInt, right.static_type): error_handler().add_type_error("Int", right.static_type.name) - return left, right, Bool() + return left, right, CoolBool @visitor.when(AST.Equals) @visitor.result(ASTR.Equals) @@ -351,18 +357,18 @@ 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 = [ Str, Int, Bool] - - if type(left.static_type) in list_type or type(right.static_type) in list_type: + 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, Bool() + 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), Bool() + return self.visit(node.item, scope), CoolBool @visitor.when(AST.New) @visitor.result(ASTR.New) @@ -374,24 +380,24 @@ def visit(self, node: AST.New, scope: Scope) -> ASTR.Node: 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(Int(), expr.static_type): + if not self.type_checking(CoolInt, expr.static_type): error_handler().add_type_error("Int", expr.static_type.name) - return expr, Int() + 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(Bool(), expr.static_type): + if not self.type_checking(CoolBool, expr.static_type): error_handler().add_type_error("Bool", expr.static_type.name) - return expr, Bool() + 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 @@ -404,14 +410,14 @@ def visit(self, node: AST.Id, scope: Scope) -> ASTR.Node: @visitor.when(AST.Int) @visitor.result(ASTR.Int) def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: - return node.item, Int() + 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, Bool() + 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, Str() \ No newline at end of file + return node.item, CoolStr \ No newline at end of file diff --git a/src/cool_compiler/semantic/visitor.py b/src/cool_compiler/semantic/visitor.py deleted file mode 100755 index f96015194..000000000 --- a/src/cool_compiler/semantic/visitor.py +++ /dev/null @@ -1,92 +0,0 @@ -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/types/build_in_types/object.py b/src/cool_compiler/types/build_in_types/object.py index a55d371fe..ff9921a7f 100755 --- a/src/cool_compiler/types/build_in_types/object.py +++ b/src/cool_compiler/types/build_in_types/object.py @@ -1,4 +1,4 @@ -from ..cool_type_build_in_manager import build_in_type +from ..cool_type_build_in_manager import build_in_type, OBJECT_NAME from ..type import Type from ..tools import type_body_def from . import * @@ -6,7 +6,7 @@ @build_in_type class Object(Type): def __init__(self): - super().__init__("Object") + super().__init__(OBJECT_NAME) type_body_def(self) def copy(self): diff --git a/src/cool_compiler/types/build_in_types/self.py b/src/cool_compiler/types/build_in_types/self.py index ec86583da..433be9786 100755 --- a/src/cool_compiler/types/build_in_types/self.py +++ b/src/cool_compiler/types/build_in_types/self.py @@ -12,4 +12,7 @@ def is_shield(self): @property def is_self_type(self): - return True \ No newline at end of file + return True + + def real_type(self, possible): + return possible \ No newline at end of file diff --git a/src/cool_compiler/types/cool_type_build_in_manager.py b/src/cool_compiler/types/cool_type_build_in_manager.py index c430039c9..4bd48be1d 100755 --- a/src/cool_compiler/types/cool_type_build_in_manager.py +++ b/src/cool_compiler/types/cool_type_build_in_manager.py @@ -1,5 +1,8 @@ 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 @@ -21,6 +24,13 @@ 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__() diff --git a/src/cool_compiler/types/type.py b/src/cool_compiler/types/type.py index 0c9942e26..63c3ba0d2 100755 --- a/src/cool_compiler/types/type.py +++ b/src/cool_compiler/types/type.py @@ -1,6 +1,7 @@ from collections import OrderedDict from .tools import * + class Type: def __init__(self, name:str): self.name = name @@ -26,6 +27,10 @@ def is_error_type(self): 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) From 7ca899890b800d4acc87e23a9f1ef87adcca1827 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 12 Jan 2022 21:05:38 -0500 Subject: [PATCH 15/91] good path to codegenerate --- src/cool_compiler/codegen/__init__.py | 1 + src/cool_compiler/codegen/__main__.py | 0 src/cool_compiler/codegen/pipeline.py | 2 - .../v0_type_data_code/type_data_code_ast.py | 117 ++++++++++++++++++ .../type_data_code_visitor.py | 81 ++++++++++++ 5 files changed, 199 insertions(+), 2 deletions(-) delete mode 100755 src/cool_compiler/codegen/__main__.py delete mode 100755 src/cool_compiler/codegen/pipeline.py create mode 100644 src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py create mode 100644 src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py diff --git a/src/cool_compiler/codegen/__init__.py b/src/cool_compiler/codegen/__init__.py index e69de29bb..fb6b00869 100755 --- a/src/cool_compiler/codegen/__init__.py +++ b/src/cool_compiler/codegen/__init__.py @@ -0,0 +1 @@ +from .v0_type_data_code.type_data_code_visitor import CILGenerate \ No newline at end of file diff --git a/src/cool_compiler/codegen/__main__.py b/src/cool_compiler/codegen/__main__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/cool_compiler/codegen/pipeline.py b/src/cool_compiler/codegen/pipeline.py deleted file mode 100755 index f898d0ce3..000000000 --- a/src/cool_compiler/codegen/pipeline.py +++ /dev/null @@ -1,2 +0,0 @@ -def run_code_generator(ast): - pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py new file mode 100644 index 000000000..e07476e8b --- /dev/null +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -0,0 +1,117 @@ +result = '@result' +self_name = 'self' +super_value = '' + + +class Node: + def get_pos_to_error(self, lineno, index): + self.lineno = lineno + self.index = index + +class Program(Node): + def __init__(self, types = {}, data = {}, functions = {}) -> None: + self.types = types + self.data = data + self.functions = functions + +class Type(Node): + def __init__(self, name) -> None: + self.name = name + self.attributes = [] + self.method_list = [] + self.methods = {} + + def attr_push(self, name): + if not name in self.attributes: + self.attributes.append(name) + + def method_push(self, name, f): + try: self.methods[name] + except KeyError: + self.method_list.append(name) + self.methods[name] = f + +class Data(Node): + def __init__(self, name, value) -> None: + self.name = name + self.value = value + +class String(Data): + pass + +class Int(Data): + pass + +class Bool(Data): + pass + +class Function(Node): + def __init__(self, name) -> None: + self.name = name + self.param = [] + self.local = [] + self.expr = [] + + def param_push(self, name, save = False): + index = 0 + while f'name@{index}' in self.param: + index += 1 + if save: self.param.append(f'name@{index}') + return f'name@{index}' + + def local_push(self, name): + self.local.append(name) + + def expr_push(self, expr): + self.expr.append(expr) + +class Expression(Node): + 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 = super_value + 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 + + +class Assign(Expression): + pass + +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 Return(Expression): + pass + +class Arg(Expression): + pass + +class Call(Expression): + pass + +class VCall(Expression): + pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py new file mode 100644 index 000000000..dcda0f6da --- /dev/null +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -0,0 +1,81 @@ +from cool_compiler.types.type import Type +from ...cmp import visitor +from ...semantic.v2_semantic_checking import semantic_checking_ast as AST +from . import type_data_code_ast as ASTR +from .type_data_code_ast import result, super_value, instance_to + +def parent_list(node: AST.CoolClass): + parent_list = [] + parent = node.type + while True: + if parent is None: break + parent_list.append(parent) + parent = parent.parent + + parent_list.reverse() + return parent_list + +class CILGenerate: + def __init__(self, errors) -> None: + self.errors = errors + + @visitor.on('node') + def visit(node): + pass + + @visitor.when(AST.Program) + def visit(self, node: AST.Program): + self.program = ASTR.Program() + for cls in node.class_list: + self.visit(cls) + + return self.program + + @visitor.when(AST.CoolClass) + def visit(self, node: AST.CoolClass): + self.currentType = ASTR.Type(node.type.name) + self.currentClass = node.type + + for parent in parent_list(node): + for attr in parent.attributes: + self.currentType.attr_push(attr.name) + for func in parent.methods: + self.currentType.method_push(func.name, f'{parent.name}@{func.name}') + + for feat in node.feature_list: + self.visit(feat) + + @visitor.when(AST.FuncDef) + def visit(self, node: AST.FuncDef): + self.currentFunc = ASTR.Function(f'{self.currentType.name}@{node.name}') + self.program.functions[self.currentFunc.name] = self.currentFunc + + self.currentFunc.param_push('self') + for name, t_params in node.params: + self.currentFunc.param_push(name) + + expr_list = self.visit(node.expr, result) + self.currentFunc.local_push(result) + cond = expr_list[-1].try_set_value(result) + + expr_list.append(ASTR.Return(result if cond else 'self')) + + @visitor.when(AST.CastingDispatch) + def visit(self, node: AST.CastingDispatch): + instance_expr_list = self.visit(node.expr) + instance_name = self.currentFunc.local_push(f'instance_to_{node.type.name}_{node.id}') + instance_expr_list[-1].set_value(instance_name) + + arg_list = [instance_name] + for i, param in enumerate(node.params): + param_expr_list = self.visit(param) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.type.name}_{node.id}') + param_expr_list[-1].set_value(param_name) + arg_list.append(param_name) + instance_expr_list += param_expr_list + + for arg in 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 \ No newline at end of file From 4b4766b48e26364c74c8f09249b014c355dfacd0 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 16 Feb 2022 21:55:27 -0500 Subject: [PATCH 16/91] firts cil --- doc/content/{chap7.pmd => chap7.md} | 0 doc/content/{chap8.pmd => chap8.md} | 0 poetry.lock | 88 ++++++++++----- pyproject.toml | 1 + requirements.txt | 47 ++------ src/cool_compiler/__main__.py | 3 +- .../v0_type_data_code/type_data_code_ast.py | 103 ++++++++++++++++-- .../type_data_code_visitor.py | 67 ++++++++++-- src/test.cl | 24 +--- 9 files changed, 226 insertions(+), 107 deletions(-) rename doc/content/{chap7.pmd => chap7.md} (100%) rename doc/content/{chap8.pmd => chap8.md} (100%) mode change 100755 => 100644 requirements.txt diff --git a/doc/content/chap7.pmd b/doc/content/chap7.md similarity index 100% rename from doc/content/chap7.pmd rename to doc/content/chap7.md diff --git a/doc/content/chap8.pmd b/doc/content/chap8.md similarity index 100% rename from doc/content/chap8.pmd rename to doc/content/chap8.md diff --git a/poetry.lock b/poetry.lock index 19f8bab93..98624851e 100755 --- a/poetry.lock +++ b/poetry.lock @@ -8,17 +8,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "20.3.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "colorama" @@ -36,43 +36,55 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "numpy" +version = "1.22.1" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + [[package]] name = "packaging" -version = "20.9" +version = "21.3" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pluggy" -version = "0.13.1" +version = "1.0.0" description = "plugin and hook calling mechanisms for python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.extras] dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] [[package]] name = "py" -version = "1.10.0" +version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pyparsing" -version = "2.4.7" +version = "3.0.7" description = "Python parsing module" category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" @@ -128,7 +140,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "5edf913efffb65061b83385f4e01535f97f8abfbe3aab973cca6f020cce77903" +content-hash = "b3eb6d7ea01ecc1c54bd394afe7d9d6eb51828c19dd729c7b45ffcb45a3abf3e" [metadata.files] atomicwrites = [ @@ -136,8 +148,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, - {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -147,21 +159,45 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +numpy = [ + {file = "numpy-1.22.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d62d6b0870b53799204515145935608cdeb4cebb95a26800b6750e48884cc5b"}, + {file = "numpy-1.22.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:831f2df87bd3afdfc77829bc94bd997a7c212663889d56518359c827d7113b1f"}, + {file = "numpy-1.22.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8d1563060e77096367952fb44fca595f2b2f477156de389ce7c0ade3aef29e21"}, + {file = "numpy-1.22.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69958735d5e01f7b38226a6c6e7187d72b7e4d42b6b496aca5860b611ca0c193"}, + {file = "numpy-1.22.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45a7dfbf9ed8d68fd39763940591db7637cf8817c5bce1a44f7b56c97cbe211e"}, + {file = "numpy-1.22.1-cp310-cp310-win_amd64.whl", hash = "sha256:7e957ca8112c689b728037cea9c9567c27cf912741fabda9efc2c7d33d29dfa1"}, + {file = "numpy-1.22.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:800dfeaffb2219d49377da1371d710d7952c9533b57f3d51b15e61c4269a1b5b"}, + {file = "numpy-1.22.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65f5e257987601fdfc63f1d02fca4d1c44a2b85b802f03bd6abc2b0b14648dd2"}, + {file = "numpy-1.22.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:632e062569b0fe05654b15ef0e91a53c0a95d08ffe698b66f6ba0f927ad267c2"}, + {file = "numpy-1.22.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d245a2bf79188d3f361137608c3cd12ed79076badd743dc660750a9f3074f7c"}, + {file = "numpy-1.22.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b4018a19d2ad9606ce9089f3d52206a41b23de5dfe8dc947d2ec49ce45d015"}, + {file = "numpy-1.22.1-cp38-cp38-win32.whl", hash = "sha256:f8ad59e6e341f38266f1549c7c2ec70ea0e3d1effb62a44e5c3dba41c55f0187"}, + {file = "numpy-1.22.1-cp38-cp38-win_amd64.whl", hash = "sha256:60f19c61b589d44fbbab8ff126640ae712e163299c2dd422bfe4edc7ec51aa9b"}, + {file = "numpy-1.22.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2db01d9838a497ba2aa9a87515aeaf458f42351d72d4e7f3b8ddbd1eba9479f2"}, + {file = "numpy-1.22.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bcd19dab43b852b03868796f533b5f5561e6c0e3048415e675bec8d2e9d286c1"}, + {file = "numpy-1.22.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78bfbdf809fc236490e7e65715bbd98377b122f329457fffde206299e163e7f3"}, + {file = "numpy-1.22.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c51124df17f012c3b757380782ae46eee85213a3215e51477e559739f57d9bf6"}, + {file = "numpy-1.22.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88d54b7b516f0ca38a69590557814de2dd638d7d4ed04864826acaac5ebb8f01"}, + {file = "numpy-1.22.1-cp39-cp39-win32.whl", hash = "sha256:b5ec9a5eaf391761c61fd873363ef3560a3614e9b4ead17347e4deda4358bca4"}, + {file = "numpy-1.22.1-cp39-cp39-win_amd64.whl", hash = "sha256:4ac4d7c9f8ea2a79d721ebfcce81705fc3cd61a10b731354f1049eb8c99521e8"}, + {file = "numpy-1.22.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e60ef82c358ded965fdd3132b5738eade055f48067ac8a5a8ac75acc00cad31f"}, + {file = "numpy-1.22.1.zip", hash = "sha256:e348ccf5bc5235fc405ab19d53bec215bb373300e5523c7b476cc0da8a5e9973"}, +] packaging = [ - {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, - {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] py = [ - {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, - {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, diff --git a/pyproject.toml b/pyproject.toml index cc0a71b70..1a49722ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ python = "^3.9" pytest = "^6.2.5" pytest-ordering = "^0.6" sly = "^0.4" +numpy = "^1.22.1" [tool.poetry.dev-dependencies] diff --git a/requirements.txt b/requirements.txt old mode 100755 new mode 100644 index 4bcbc1bd3..013670a18 --- a/requirements.txt +++ b/requirements.txt @@ -1,36 +1,11 @@ -atomicwrites==1.4.0; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.4.0" \ - --hash=sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197 \ - --hash=sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a -attrs==20.3.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ - --hash=sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6 \ - --hash=sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700 -colorama==0.4.4; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0" \ - --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ - --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b -iniconfig==1.1.1; python_version >= "3.6" \ - --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ - --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 -packaging==20.9; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ - --hash=sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a \ - --hash=sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5 -pluggy==0.13.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ - --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d \ - --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 -py==1.10.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ - --hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a \ - --hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 -pyparsing==2.4.7; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \ - --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ - --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 -pytest-ordering==0.6 \ - --hash=sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6 \ - --hash=sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2 \ - --hash=sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6 -pytest==6.2.5; python_version >= "3.6" \ - --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134 \ - --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 -sly==0.4 \ - --hash=sha256:e5f2266a231322cc17519fbc3a3ba1c6335fed5a9a55abe0e598a35aea0ac32a -toml==0.10.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6" \ - --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ - --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f +attrs @ file:///Users/dany/Library/Caches/pypoetry/artifacts/52/ae/a5/4a6ce9001a7aff209cf585904d049b7697203ce2255c73f2318b9ee39b/attrs-20.3.0-py2.py3-none-any.whl +iniconfig @ file:///Users/dany/Library/Caches/pypoetry/artifacts/1d/67/0c/79706e7a41ef01be0b1a38aa3b4ddc9bd800a95ccd8d8dc7de4e090623/iniconfig-1.1.1-py2.py3-none-any.whl +numpy @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5a/1f/3b/b802d219fbe7847bdfd579c618b07d2fc25c6eb960b9943dd1ae35635d/numpy-1.22.1-cp310-cp310-macosx_11_0_arm64.whl +packaging @ file:///Users/dany/Library/Caches/pypoetry/artifacts/49/ac/9b/fe8c98d6e71c0a3bbd2124fa7390ece04a29f1ff457bc73c8860d994fa/packaging-20.9-py2.py3-none-any.whl +pluggy @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5c/74/60/0a66715d8599e4bd0cf44f05ca11f99f9a3674820bd68856704692b818/pluggy-0.13.1-py2.py3-none-any.whl +py @ file:///Users/dany/Library/Caches/pypoetry/artifacts/56/47/ba/83cd275e2a70e4b5358d0e580cb41f3f84031c5a2d690714ba00b0e112/py-1.10.0-py2.py3-none-any.whl +pyparsing @ file:///Users/dany/Library/Caches/pypoetry/artifacts/99/c8/f8/0954d73c6d7d441bc4ed58326f3f13cdc63bfedf6e46e0d16eddd10c58/pyparsing-2.4.7-py2.py3-none-any.whl +pytest @ file:///Users/dany/Library/Caches/pypoetry/artifacts/d3/5c/6c/ecc815bbb070306dcb67bef0ec365f599b0f4b6ce85fc620f675c77231/pytest-6.2.5-py3-none-any.whl +pytest-ordering @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5a/35/4a/047f280bf7fcc4bcf8c1807667b4484d34dfdd366358d2803160045c71/pytest_ordering-0.6-py3-none-any.whl +sly @ file:///Users/dany/Library/Caches/pypoetry/artifacts/55/b5/e7/aaa630b234bb48bde56d4bcbcf27d7b7ac4d8ee2f49024202c26f68170/sly-0.4.tar.gz +toml @ file:///Users/dany/Library/Caches/pypoetry/artifacts/51/ac/24/674da558495229c57c3d2333cb23e24aac7aadf723ced29e2cc41a9e6e/toml-0.10.2-py2.py3-none-any.whl diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index c721fcc94..968c4b174 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -32,6 +32,5 @@ ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - - + print(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index e07476e8b..f3d2720b6 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -1,3 +1,6 @@ +from cool_compiler.semantic.v0_parser_return.factory_parser_return_ast import AtrDef + + result = '@result' self_name = 'self' super_value = '' @@ -9,14 +12,48 @@ def get_pos_to_error(self, lineno, index): self.index = index class Program(Node): - def __init__(self, types = {}, data = {}, functions = {}) -> None: - self.types = types - self.data = data - self.functions = functions + 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 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 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(Node): def __init__(self, name) -> None: - self.name = name + self.name = name self.attributes = [] self.method_list = [] self.methods = {} @@ -26,16 +63,31 @@ def attr_push(self, name): self.attributes.append(name) def method_push(self, name, f): - try: self.methods[name] + 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) + '\n' + + for func in self.method_list: + result += '\tfunction ' + str(func) + ' '*(15 - len(str(func))) + '-> ' + str(self.methods[func]) + '\n' + + return result + '}' + class Data(Node): def __init__(self, name, value) -> None: self.name = name self.value = value + def __str__(self) -> str: + return f'\tdata {self.name}: {self.value}' + class String(Data): pass @@ -54,16 +106,31 @@ def __init__(self, name) -> None: def param_push(self, name, save = False): index = 0 - while f'name@{index}' in self.param: + while f'{name}@{index}' in self.param: index += 1 - if save: self.param.append(f'name@{index}') - return f'name@{index}' + if save: self.param.append(f'{name}@{index}') + return f'{name}@{index}' def local_push(self, name): self.local.append(name) + return 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(Node): def __init__(self, x = None, y = None, z = None) -> None: @@ -73,7 +140,7 @@ def __init__(self, x = None, y = None, z = None) -> None: def try_set_value(self, name): if self.x == super_value: - self.x = super_value + self.x = name return True return False @@ -82,6 +149,19 @@ def set_value(self, name): raise Exception("The expression is'nt set expression") self.x = name + 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): pass @@ -114,4 +194,7 @@ class Call(Expression): pass class VCall(Expression): + pass + +class Load(Expression): pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index dcda0f6da..33d0f8b8a 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -2,7 +2,7 @@ from ...cmp import visitor from ...semantic.v2_semantic_checking import semantic_checking_ast as AST from . import type_data_code_ast as ASTR -from .type_data_code_ast import result, super_value, instance_to +from .type_data_code_ast import result, super_value def parent_list(node: AST.CoolClass): parent_list = [] @@ -21,7 +21,7 @@ def __init__(self, errors) -> None: @visitor.on('node') def visit(node): - pass + return [ASTR.Sum(super_value, 'a', 'b')] @visitor.when(AST.Program) def visit(self, node: AST.Program): @@ -35,6 +35,7 @@ def visit(self, node: AST.Program): def visit(self, node: AST.CoolClass): self.currentType = ASTR.Type(node.type.name) self.currentClass = node.type + self.program.add_type(self.currentType) for parent in parent_list(node): for attr in parent.attributes: @@ -48,34 +49,76 @@ def visit(self, node: AST.CoolClass): @visitor.when(AST.FuncDef) def visit(self, node: AST.FuncDef): self.currentFunc = ASTR.Function(f'{self.currentType.name}@{node.name}') - self.program.functions[self.currentFunc.name] = self.currentFunc + self.program.add_func(self.currentFunc) - self.currentFunc.param_push('self') + self.currentFunc.param.append('self') for name, t_params in node.params: - self.currentFunc.param_push(name) + self.currentFunc.param_push(name, True) - expr_list = self.visit(node.expr, result) + expr_list = self.visit(node.expr) self.currentFunc.local_push(result) cond = expr_list[-1].try_set_value(result) expr_list.append(ASTR.Return(result if cond else 'self')) + self.currentFunc.expr = expr_list + @visitor.when(AST.CastingDispatch) def visit(self, node: AST.CastingDispatch): instance_expr_list = self.visit(node.expr) - instance_name = self.currentFunc.local_push(f'instance_to_{node.type.name}_{node.id}') + instance_name = self.currentFunc.local_push(f'instance_{node.type.name}_to_{node.id}') instance_expr_list[-1].set_value(instance_name) arg_list = [instance_name] for i, param in enumerate(node.params): - param_expr_list = self.visit(param) - param_name = self.currentFunc.local_push(f'param_{i}_to_{node.type.name}_{node.id}') - param_expr_list[-1].set_value(param_name) + instance_expr_list += self.visit(param) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}') + instance_expr_list[-1].set_value(param_name) arg_list.append(param_name) - instance_expr_list += param_expr_list for arg in 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 \ No newline at end of file + return instance_expr_list + + @visitor.when(AST.Dispatch) + def visit(self, node: AST.Dispatch): + instance_expr_list = self.visit(node.expr) + instance_name = self.currentFunc.local_push(f'instance_to_call_{node.id}') + instance_expr_list[-1].set_value(instance_name) + + arg_list = [instance_name] + + for i, param in enumerate(node.params): + instance_expr_list += self.visit(param) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}') + instance_expr_list[-1].set_value(param_name) + arg_list.append(param_name) + + for arg in 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.StaticDispatch) + def visit(self, node: AST.StaticDispatch): + arg_list = ['self'] + param_expr_list = [] + for i, param in enumerate(node.params): + param_expr_list += self.visit(param) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}') + param_expr_list[-1].set_value(param_name) + arg_list.append(param_name) + + for arg in arg_list: + param_expr_list.append(ASTR.Arg(arg)) + + param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) + return param_expr_list + + @visitor.when(AST.Str) + def visit(self, node: AST.Str): + name = self.program.add_data('string', node.item.name) + return [ASTR.Load(super_value, name)] \ No newline at end of file diff --git a/src/test.cl b/src/test.cl index da79bbfe6..b41b36c81 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,23 +1,5 @@ --- Missing type - -class A { }; -class B inherits A { }; -class C inherits B { }; -class D inherits B { }; -class E inherits B { }; -class F inherits A { }; - class Main inherits IO { - main(): IO { out_string("Hello World!")}; - - b: B <- case "true" of - i: Int => New C; - b: Bool => New D; - s: String => New E; - esac; - - test: A <- case 0 of - b: Bool => new F; - i: Ball => new E; - esac; + main(): IO { + out_string("Hello, World.\n") + }; }; \ No newline at end of file From 50150827acdbf3bae095b520aa2ad027d3727b5d Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 17 Feb 2022 17:51:38 -0500 Subject: [PATCH 17/91] delete numpy --- .DS_Store | Bin 6148 -> 6148 bytes a.txt | 10 ++++++++++ poetry.lock | 34 +--------------------------------- pyproject.toml | 1 - requirements.txt | 11 +++++------ 5 files changed, 16 insertions(+), 40 deletions(-) create mode 100644 a.txt diff --git a/.DS_Store b/.DS_Store index 85f438282170bd10ff0a3653a78a778c93f1ecd1..746e853144291f3e7f4f27db1b66479fae9a9009 100644 GIT binary patch delta 49 zcmZoMXfc@J&&aYdU^gQp%Vr)XZbo5dhGK>yhUBu~qP(2^ymSTz2FA^b%y(Hfvvd6A F2LM6g4H^Id delta 32 ocmZoMXfc@J&&a$nU^gQp^JX3 Date: Thu, 17 Feb 2022 20:34:16 -0500 Subject: [PATCH 18/91] reedit req --- src/cool_compiler/__main__.py | 2 +- src/requirements.txt | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/requirements.txt diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 968c4b174..58c218209 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -32,5 +32,5 @@ ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - print(ast) + # print(ast) diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 000000000..26e4129a5 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1,9 @@ +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 From c3229a0ab184aedde3cef8734fc28c471bdc56ee Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Sun, 20 Feb 2022 10:31:32 -0500 Subject: [PATCH 19/91] casi term --- Pipfile | 12 ++ Pipfile.lock | 28 +++ a.txt | 10 - poetry.lock | 185 ------------------ pyproject.toml | 17 -- requirements.txt | 19 +- src/cool_compiler/__main__.py | 2 +- .../v0_type_data_code/type_data_code_ast.py | 3 + .../type_data_code_visitor.py | 28 +++ src/requirements.txt | 9 - 10 files changed, 81 insertions(+), 232 deletions(-) create mode 100644 Pipfile create mode 100644 Pipfile.lock delete mode 100644 a.txt delete mode 100755 poetry.lock delete mode 100644 pyproject.toml delete mode 100644 src/requirements.txt 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/a.txt b/a.txt deleted file mode 100644 index edea821c0..000000000 --- a/a.txt +++ /dev/null @@ -1,10 +0,0 @@ -attrs @ file:///Users/dany/Library/Caches/pypoetry/artifacts/52/ae/a5/4a6ce9001a7aff209cf585904d049b7697203ce2255c73f2318b9ee39b/attrs-20.3.0-py2.py3-none-any.whl -iniconfig @ file:///Users/dany/Library/Caches/pypoetry/artifacts/1d/67/0c/79706e7a41ef01be0b1a38aa3b4ddc9bd800a95ccd8d8dc7de4e090623/iniconfig-1.1.1-py2.py3-none-any.whl -packaging @ file:///Users/dany/Library/Caches/pypoetry/artifacts/49/ac/9b/fe8c98d6e71c0a3bbd2124fa7390ece04a29f1ff457bc73c8860d994fa/packaging-20.9-py2.py3-none-any.whl -pluggy @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5c/74/60/0a66715d8599e4bd0cf44f05ca11f99f9a3674820bd68856704692b818/pluggy-0.13.1-py2.py3-none-any.whl -py @ file:///Users/dany/Library/Caches/pypoetry/artifacts/56/47/ba/83cd275e2a70e4b5358d0e580cb41f3f84031c5a2d690714ba00b0e112/py-1.10.0-py2.py3-none-any.whl -pyparsing @ file:///Users/dany/Library/Caches/pypoetry/artifacts/99/c8/f8/0954d73c6d7d441bc4ed58326f3f13cdc63bfedf6e46e0d16eddd10c58/pyparsing-2.4.7-py2.py3-none-any.whl -pytest @ file:///Users/dany/Library/Caches/pypoetry/artifacts/d3/5c/6c/ecc815bbb070306dcb67bef0ec365f599b0f4b6ce85fc620f675c77231/pytest-6.2.5-py3-none-any.whl -pytest-ordering @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5a/35/4a/047f280bf7fcc4bcf8c1807667b4484d34dfdd366358d2803160045c71/pytest_ordering-0.6-py3-none-any.whl -sly @ file:///Users/dany/Library/Caches/pypoetry/artifacts/55/b5/e7/aaa630b234bb48bde56d4bcbcf27d7b7ac4d8ee2f49024202c26f68170/sly-0.4.tar.gz -toml @ file:///Users/dany/Library/Caches/pypoetry/artifacts/51/ac/24/674da558495229c57c3d2333cb23e24aac7aadf723ced29e2cc41a9e6e/toml-0.10.2-py2.py3-none-any.whl diff --git a/poetry.lock b/poetry.lock deleted file mode 100755 index 039ecb307..000000000 --- a/poetry.lock +++ /dev/null @@ -1,185 +0,0 @@ -[[package]] -name = "atomicwrites" -version = "1.4.0" -description = "Atomic file writes." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "attrs" -version = "21.4.0" -description = "Classes Without Boilerplate" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] - -[[package]] -name = "colorama" -version = "0.4.4" -description = "Cross-platform colored terminal text." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "packaging" -version = "21.3" -description = "Core utilities for Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - -[[package]] -name = "pluggy" -version = "1.0.0" -description = "plugin and hook calling mechanisms for python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pyparsing" -version = "3.0.7" -description = "Python parsing module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-ordering" -version = "0.6" -description = "pytest plugin to run your tests in a specific order" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -pytest = "*" - -[[package]] -name = "sly" -version = "0.4" -description = "SLY - Sly Lex Yacc" -category = "main" -optional = false -python-versions = "*" - -[package.extras] -test = ["pytest", "regex"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "main" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[metadata] -lock-version = "1.1" -python-versions = "^3.9" -content-hash = "5edf913efffb65061b83385f4e01535f97f8abfbe3aab973cca6f020cce77903" - -[metadata.files] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] -colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pyparsing = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, -] -pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] -pytest-ordering = [ - {file = "pytest-ordering-0.6.tar.gz", hash = "sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6"}, - {file = "pytest_ordering-0.6-py2-none-any.whl", hash = "sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2"}, - {file = "pytest_ordering-0.6-py3-none-any.whl", hash = "sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6"}, -] -sly = [ - {file = "sly-0.4.tar.gz", hash = "sha256:e5f2266a231322cc17519fbc3a3ba1c6335fed5a9a55abe0e598a35aea0ac32a"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index cc0a71b70..000000000 --- a/pyproject.toml +++ /dev/null @@ -1,17 +0,0 @@ -[tool.poetry] -name = "cool-compiler-2021" -version = "0.1.0" -description = "" -authors = ["dany"] - -[tool.poetry.dependencies] -python = "^3.9" -pytest = "^6.2.5" -pytest-ordering = "^0.6" -sly = "^0.4" - -[tool.poetry.dev-dependencies] - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index 275e45537..26e4129a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,9 @@ -attrs @ file:///Users/dany/Library/Caches/pypoetry/artifacts/c4/ee/75/fcd6c2f4c5a1d60b1bcd97014702ca01b3f032fd927d88780b38708409/attrs-21.4.0-py2.py3-none-any.whl -iniconfig @ file:///Users/dany/Library/Caches/pypoetry/artifacts/1d/67/0c/79706e7a41ef01be0b1a38aa3b4ddc9bd800a95ccd8d8dc7de4e090623/iniconfig-1.1.1-py2.py3-none-any.whl -packaging @ file:///Users/dany/Library/Caches/pypoetry/artifacts/d3/1f/90/3f2473250ebd055fe7f0856810677783949fc0d2e5f25bbb4dc00ad0a9/packaging-21.3-py3-none-any.whl -pluggy @ file:///Users/dany/Library/Caches/pypoetry/artifacts/49/3e/55/309ec3705ba3309d817d531002c0a02f643d06c5d5a889ce43236130d5/pluggy-1.0.0-py2.py3-none-any.whl -py @ file:///Users/dany/Library/Caches/pypoetry/artifacts/71/fb/64/bfdc833c2055a893883f33deaac35ef2cbdd95d58031cfc69a630f32bf/py-1.11.0-py2.py3-none-any.whl -pyparsing @ file:///Users/dany/Library/Caches/pypoetry/artifacts/dd/d9/cf/3501b38e834b80f9ba80633358cced32539bea5dc1e786f4c2b1d2f682/pyparsing-3.0.7-py3-none-any.whl -pytest @ file:///Users/dany/Library/Caches/pypoetry/artifacts/d3/5c/6c/ecc815bbb070306dcb67bef0ec365f599b0f4b6ce85fc620f675c77231/pytest-6.2.5-py3-none-any.whl -pytest-ordering @ file:///Users/dany/Library/Caches/pypoetry/artifacts/5a/35/4a/047f280bf7fcc4bcf8c1807667b4484d34dfdd366358d2803160045c71/pytest_ordering-0.6-py3-none-any.whl -sly @ file:///Users/dany/Library/Caches/pypoetry/artifacts/55/b5/e7/aaa630b234bb48bde56d4bcbcf27d7b7ac4d8ee2f49024202c26f68170/sly-0.4.tar.gz -toml @ file:///Users/dany/Library/Caches/pypoetry/artifacts/51/ac/24/674da558495229c57c3d2333cb23e24aac7aadf723ced29e2cc41a9e6e/toml-0.10.2-py2.py3-none-any.whl +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/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 58c218209..968c4b174 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -32,5 +32,5 @@ ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - # print(ast) + print(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index f3d2720b6..051913501 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -197,4 +197,7 @@ class VCall(Expression): pass class Load(Expression): + pass + +class ALLOCATE(Expression): pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 33d0f8b8a..dbd0eff84 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -35,6 +35,7 @@ def visit(self, node: AST.Program): def visit(self, node: AST.CoolClass): self.currentType = ASTR.Type(node.type.name) self.currentClass = node.type + self.new_type_func = ASTR.Function(f'new@ctr@{node.type.name}') self.program.add_type(self.currentType) for parent in parent_list(node): @@ -42,10 +43,37 @@ def visit(self, node: AST.CoolClass): self.currentType.attr_push(attr.name) for func in parent.methods: self.currentType.method_push(func.name, f'{parent.name}@{func.name}') + + self.new_type_func.local_push('instance') + self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) for feat in node.feature_list: self.visit(feat) + + if node.type.name == 'Main': + self.new_type_func.local_push(result) + self.new_type_func.expr_push(ASTR.Arg('instance')) + self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main@Main')) + self.new_type_func.expr_push(ASTR.Return(0)) + else: + return_name = self.new_type_func.param_push(result, True) + self.new_type_func.expr_push(ASTR.Assign(return_name, 'instance')) + + self.program.add_func(self.new_type_func) + @visitor.when(AST.AtrDef) + def visit(self, node: AST.AtrDef): + if not node.expr is None: + save_current_func = self.currentFunc + self.currentFunc = self.new_type_func + attr_name = self.new_type_func.param_push(node.name) + exp_list = self.visit(node.expr) + exp_list[-1].set_value(attr_name) + exp_list.append(ASTR.SetAttr('instance', node.name, attr_name)) + self.new_type_func.expr += exp_list + self.currentFunc = save_current_func + + @visitor.when(AST.FuncDef) def visit(self, node: AST.FuncDef): self.currentFunc = ASTR.Function(f'{self.currentType.name}@{node.name}') diff --git a/src/requirements.txt b/src/requirements.txt deleted file mode 100644 index 26e4129a5..000000000 --- a/src/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -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 From e2a957e2d15a8ba27e8cd10b02965952827e78a0 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Mon, 21 Feb 2022 20:59:57 -0500 Subject: [PATCH 20/91] write v4 --- .../v0_type_data_code/type_data_code_ast.py | 85 ++++++- .../type_data_code_visitor.py | 222 +++++++++++++++++- .../v1_create_type/create_type_visitor.py | 6 +- 3 files changed, 294 insertions(+), 19 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 051913501..d3909b62c 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -35,6 +35,11 @@ def __str__(self) -> str: result += str(self.functions[func]) + '\n' return result + def try_add_data(self, name, value): + try: + _ = self.data[name] + except KeyError: + self.data[name] = value def add_data(self, name, value): index = 0 @@ -100,20 +105,41 @@ class Bool(Data): class Function(Node): def __init__(self, name) -> None: self.name = name + self.var_dir = {} self.param = [] self.local = [] self.expr = [] - def param_push(self, name, save = False): + def get_name(self, name): index = 0 - while f'{name}@{index}' in self.param: - index += 1 - if save: self.param.append(f'{name}@{index}') - return f'{name}@{index}' - - def local_push(self, name): + while True: + try: + _ = self.var_dir[f'{name}@{index}'] + index += 1 + except KeyError: + return f'{name}@{index}' + + def force_local(self,name): + self.var_dir[name] = name self.local.append(name) return name + + def force_parma(self,name): + self.var_dir[name] = name + self.param.append(name) + return name + + def param_push(self, name): + new_name = self.get_name(name) + self.var_dir[name] = new_name + self.param.append(new_name) + return new_name + + def local_push(self, name): + new_name = self.get_name(name) + self.var_dir[name] = new_name + self.local.append(new_name) + return new_name def expr_push(self, expr): self.expr.append(expr) @@ -184,6 +210,24 @@ class Div(Expression): class Mult(Expression): pass +class Less(Expression): + pass + +class LessOrEqual(Expression): + pass + +class CmpInt(Expression): + pass + +class CmpStr(Expression): + pass + +class CmpRef(Expression): + pass + +class CheckType(Expression): + pass + class Return(Expression): pass @@ -200,4 +244,29 @@ class Load(Expression): pass class ALLOCATE(Expression): - pass \ No newline at end of file + pass + +class NegAssing(Expression): + pass + +class IfGoTo(Exception): + pass + +class GoTo(Expression): + pass + +class Label(Expression): + pass + +class TypeOf(Expression): + pass + +class New(Expression): + pass + +class Neg(Expression): + pass + +class Complemnet(Expression): + pass + diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index dbd0eff84..6ff5895b6 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -1,9 +1,16 @@ +from cool_compiler.types.cool_type_build_in_manager import CoolTypeBuildInManager from cool_compiler.types.type import Type from ...cmp import visitor from ...semantic.v2_semantic_checking import semantic_checking_ast as AST from . import type_data_code_ast as ASTR from .type_data_code_ast import result, super_value + +CoolInt = CoolTypeBuildInManager().find("Int") +CoolBool = CoolTypeBuildInManager().find("Bool") +CoolStr = CoolTypeBuildInManager().find("String") + + def parent_list(node: AST.CoolClass): parent_list = [] parent = node.type @@ -15,9 +22,20 @@ def parent_list(node: AST.CoolClass): parent_list.reverse() return parent_list +def new_name(name, _dict): + index = 0 + while True: + try: + _ = _dict[f'{name}@{index}'] + index += 1 + except KeyError: + _dict[f'{name}@{index}'] = 1 + return f'{name}@{index}' + class CILGenerate: def __init__(self, errors) -> None: self.errors = errors + self.label_list = {} @visitor.on('node') def visit(node): @@ -44,20 +62,19 @@ def visit(self, node: AST.CoolClass): for func in parent.methods: self.currentType.method_push(func.name, f'{parent.name}@{func.name}') - self.new_type_func.local_push('instance') + self.new_type_func.force_local('instance') self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) for feat in node.feature_list: self.visit(feat) if node.type.name == 'Main': - self.new_type_func.local_push(result) + self.new_type_func.force_local(result) self.new_type_func.expr_push(ASTR.Arg('instance')) self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main@Main')) self.new_type_func.expr_push(ASTR.Return(0)) else: - return_name = self.new_type_func.param_push(result, True) - self.new_type_func.expr_push(ASTR.Assign(return_name, 'instance')) + self.new_type_func.expr_push(ASTR.Return('instance')) self.program.add_func(self.new_type_func) @@ -79,12 +96,12 @@ def visit(self, node: AST.FuncDef): self.currentFunc = ASTR.Function(f'{self.currentType.name}@{node.name}') self.program.add_func(self.currentFunc) - self.currentFunc.param.append('self') + self.currentFunc.force_parma('self') for name, t_params in node.params: - self.currentFunc.param_push(name, True) + self.currentFunc.param_push(name) expr_list = self.visit(node.expr) - self.currentFunc.local_push(result) + self.currentFunc.force_local(result) cond = expr_list[-1].try_set_value(result) expr_list.append(ASTR.Return(result if cond else 'self')) @@ -146,7 +163,196 @@ def visit(self, node: AST.StaticDispatch): param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) return param_expr_list + + @visitor.when(AST.Assing) + def visit(self, node: AST.Assing): + exp_list = self.visit(node.expr) + result_local = self.currentFunc.local_push(f'result@assing@{node.id}') + exp_list[-1].set_value(result_local) + + try: + result_name = self.currentFunc.var_dir[node.id] + exp_list.append(ASTR.Assign(result_name, result_local)) + except: + result_name = node.id + exp_list.append(ASTR.SetAttr('self', self.currentType.name, result_local)) + + exp_list.append(ASTR.Assign(super_value, result_name)) + return exp_list + + @visitor.when(AST.IfThenElse) + def visit(self, node: AST.IfThenElse): + cond_result = self.currentFunc.local_push(f'cond@if_else') + + expr_list = self.visit(node.condition) + expr_list[-1].set_value(cond_result) + result_if = self.currentFunc.local_push('result@if') + + label_then = new_name(f'then@{self.currentFunc.name}') + label_fin = new_name(f'fin@{self.currentFunc.name}') + expr_list.append(ASTR.IfGoTo(cond_result, label_then)) + + else_list = self.visit(node.else_expr) + else_list[-1].set_value(result_if) + expr_list += else_list + [ASTR.GoTo(label_fin), ASTR.Label(label_then)] + + then_list = self.visit(node.then_expr) + then_list[-1].set_value(result_if) + + expr_list += then_list + [ASTR.Label(label_fin)] + + return expr_list + [ASTR.Assign(super_value, result_if)] + + @visitor.when(AST.While) + def visit(self, node: AST.While): + while_cond = new_name('while@cond', self.label_list) + while_back = new_name('while@back', self.label_list) + + result_list = [ASTR.GoTo(while_cond), ASTR.Label(while_back)] + result_list += self.visit(node.loop_expr) + result_list += [ASTR.Label(while_cond)] + + cond_local = self.currentFunc.local_push('cond@while') + result_list += self.visit(node.condition) + result_list[-1].set_value(cond_local) + result_list.append(ASTR.IfGoTo(cond_local, while_back)) + + return result_list + [ASTR.Assign(super_value, 'self')] + + @visitor.when(AST.Block) + def visit(self, node: AST.Block): + result_list = [] + _len = len(node.expr_list) - 1 + for i, expr in enumerate(node.expr_list): + if i == _len: result_step = super_value + else: result_step = self.currentFunc.local_push('step@block') + result_list += self.visit(expr) + result_list[-1].set_value(result_step) + + return result_list + + @visitor.when(AST.LetIn) + def visit(self, node: AST.LetIn): + result_list = [] + for name, _, expr in node.assing_list: + local_name = self.currentFunc.local_push(f'let_in@{name}') + if not expr is None: + result_list += self.visit(expr) + result_list[-1].set_value(local_name) + + return result_list + self.visit(node.expr) + + @visitor.when(AST.Case) + def visit(self, node: AST.Case): + expr_cond_list = self.visit(node.expr) + case_cond_name = self.currentFunc.local_push('case@expr') + expr_cond_list[-1].set_value(case_cond_name) + case_cond_type = self.currentFunc.local_push('case@type') + expr_cond_list.append(ASTR.TypeOf(case_cond_type, case_cond_name)) + + case_result = self.currentFunc.local_push('case@result') + case_fin_label = new_name('case@fin', self.label_list) + expr_list = [] + for name, atype , expr in node.case_list: + # get type for iter + # compare type + # self.program.try_add_data(f'type@{atype.name}', atype.name) + case_label = new_name('case@step@label', self.label_list) + local_cmp = self.currentFunc.local_push('case@cmp') + expr_cond_list.append(ASTR.IfGoTo(local_cmp, case_label)) + + expr_list += [ASTR.Label(case_label)] + expr_list += self.visit(expr) + expr_list[-1].set_value(case_result) + expr_list += [ASTR.GoTo(case_fin_label)] + + return (expr_cond_list + + expr_list + + [ASTR.Label(case_fin_label), ASTR.Assign(super_value, case_result)]) + + def binary_op(self, name, node, astr_node): + op_1 = self.currentFunc.local_push(f'{name}@_a') + op_2 = self.currentFunc.local_push(f'{name}@_b') + + result_list = self.visit(node.left) + result_list[-1].set_value(op_1) + result_list += self.visit(node.right) + result_list[-1].set_value(op_2) + + return result_list + [astr_node(super_value, op_1, op_2)] + + @visitor.when(AST.Sum) + def visit(self, node: AST.Sum): + return self.binary_op('sum', node, ASTR.Sum) + + @visitor.when(AST.Rest) + def visit(self, node: AST.Rest): + return self.binary_op('rest', node, ASTR.Rest) + + @visitor.when(AST.Mult) + def visit(self, node: AST.Mult): + return self.binary_op('factor', node, ASTR.Mult) + + @visitor.when(AST.Div) + def visit(self, node: AST.Div): + return self.binary_op('div', node, ASTR.Div) + + @visitor.when(AST.Less) + def visit(self, node: AST.Less): + return self.binary_op('less', node, ASTR.Less) + + @visitor.when(AST.LessOrEquals) + def visit(self, node: AST.LessOrEquals): + return self.binary_op('le', node, ASTR.LessOrEqual) + + @visitor.when(AST.Equals) + def visit(self, node: AST.Equals): + if node.static_type in [CoolInt, CoolBool]: + return self.binary_op('int_eq', node, ASTR.CmpInt) + if node.static_type == CoolStr: + return self.binary_op('str_eq', node, ASTR.CmpStr) + + return self.binary_op('req_eq', node, ASTR.CmpRef) + + @visitor.when(AST.New) + def visit(self, node: AST.New): + return [ASTR.New(super_value, node.item.name)] + + def unary_op(self, name, node, astr_node): + op = self.currentFunc.local_push(f'{name}@_unary') + result_list = self.visit(node.item) + result_list[-1].set_value(op) + + return result_list + [astr_node(super_value, op)] + + @visitor.when(AST.Complement) + def visit(self, node: AST.Complement): + return self.unary_op('compl', node, ASTR.Complemnet) + + @visitor.when(AST.Neg) + def visit(self, node: AST.Neg): + return self.unary_op('neg', node, ASTR.Neg) + + @visitor.when(AST.Void) + def visit(self, node: AST.Void): + op_1 = self.currentFunc.local_push('void@_op') + null = self.currentFunc.local_push('void@_null') + unary_list = self.unary_op('void', node, ASTR.Complemnet) + unary_list[-1].set_value(op_1) + + return ( + [ASTR.Load(null, "NULL")] + + unary_list + + [ASTR.CmpRef(super_value, null, op_1)] + ) + + # @visitor.when(AST.Id) + # def visit(self, node: AST.Id): + # try: + + + @visitor.when(AST.Str) def visit(self, node: AST.Str): - name = self.program.add_data('string', node.item.name) + name = self.program.add_data('string', node.item) return [ASTR.Load(super_value, name)] \ No newline at end of file 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 index 9bf38ea46..f4b68d77b 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -291,14 +291,14 @@ def visit(self, node: AST.Id): @visitor.when(AST.Int) @visitor.result(ASTR.Int) def visit(self, node: AST.Int): - return Int(), + return node.item, @visitor.when(AST.Bool) @visitor.result(ASTR.Bool) def visit(self, node: AST.Bool): - return Bool(), + return node.item, @visitor.when(AST.Str) @visitor.result(ASTR.Str) def visit(self, node: AST.Str): - return Str(), + return node.item, From d804a9828e255272782b1f017ea4f68d01bfebb5 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Tue, 22 Feb 2022 10:08:26 -0500 Subject: [PATCH 21/91] codemips --- src/.vscode/launch.json | 14 +++++ src/cool_compiler/.vscode/launch.json | 15 +++++ src/cool_compiler/__main__.py | 12 ++-- .../codegen/v0_type_data_code/mipsgenerate.py | 57 +++++++++++++++++++ .../v0_type_data_code/type_data_code_ast.py | 5 +- src/cool_compiler/error/error.py | 2 +- src/cool_compiler/pr.py | 2 + src/test.py | 1 + 8 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 src/.vscode/launch.json create mode 100644 src/cool_compiler/.vscode/launch.json create mode 100644 src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py create mode 100644 src/cool_compiler/pr.py create mode 100644 src/test.py 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/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/__main__.py b/src/cool_compiler/__main__.py index 968c4b174..de7ce95c6 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -6,9 +6,8 @@ from .types import CoolTypeBuildInManager from .codegen import CILGenerate -path = "" -if len(sys.argv) > 1: - path = sys.argv[1] +path = "test.cl" + with open(path, 'r') as _file: @@ -29,8 +28,11 @@ visitorList = [ CreateType, SemanticChecking, CILGenerate ] for visitorClass in visitorList: - ast = visitorClass(errors).visit(ast) + ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - + print(ast) + print(type(ast)) + print((ast.types['Main'].method_list)) + #print(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py b/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py new file mode 100644 index 000000000..3c1bb2ed8 --- /dev/null +++ b/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py @@ -0,0 +1,57 @@ +from cool_compiler.types.type import Type +from ...cmp import visitor +from ...semantic.v2_semantic_checking import semantic_checking_ast as AST +from . import type_data_code_ast as ASTR +from .type_data_code_ast import result, super_value + + +class MipsGenerate: + def __init__(self, errors) -> None: + self.errors = errors + self.data =[] + self.text=[] + + + + @visitor.on('node') + def visit(node): + pass + + @visitor.when(ASTR.Program) + def visit(self, node: ASTR.Program): + self.Program = node + for Function in node.functions: + Function.visit(node) + pass + + @visitor.when(ASTR.Local) + def visit(self, node: ASTR.Local): + s ="" + s = str(node.x) + ":" + " .word" + " 11" + self.data.append(s) + pass + + @visitor.when(ASTR.Data) + def visit (self , node:ASTR.Data) : + pass + + + @visitor.when(ASTR.ALLOCATE) + def visit (self,node : ASTR.ALLOCATE): + + + pass + + + @visitor.when(ASTR.Arg) + def visit (self,node : ASTR.Arg): + pass + + + + @visitor.when(ASTR.Call) + def visit (self,node : ASTR.Call): + pass + + + diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 051913501..f2312d8da 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -200,4 +200,7 @@ class Load(Expression): pass class ALLOCATE(Expression): - pass \ No newline at end of file + pass + +class Local(Expression): + pass diff --git a/src/cool_compiler/error/error.py b/src/cool_compiler/error/error.py index 48fc9c26f..4ad9b7749 100755 --- a/src/cool_compiler/error/error.py +++ b/src/cool_compiler/error/error.py @@ -1,4 +1,4 @@ -from cool_compiler.types.build_in_types import self +from cool_compiler.types.build_in_types import self class CoolError: diff --git a/src/cool_compiler/pr.py b/src/cool_compiler/pr.py new file mode 100644 index 000000000..19262e696 --- /dev/null +++ b/src/cool_compiler/pr.py @@ -0,0 +1,2 @@ +a = 5 +print(a) \ No newline at end of file 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 From abfce9af4dafe29449596945f45985aa89534090 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 10:14:40 -0500 Subject: [PATCH 22/91] merger with aldo --- .../v2_semantic_checking => cmp}/scope.py | 2 +- .../v0_type_data_code/type_data_code_ast.py | 27 ++- .../type_data_code_visitor.py | 216 ++++++++++-------- src/cool_compiler/semantic/tools.py | 2 +- .../semantic_checking_visitor.py | 2 +- 5 files changed, 139 insertions(+), 110 deletions(-) rename src/cool_compiler/{semantic/v2_semantic_checking => cmp}/scope.py (95%) diff --git a/src/cool_compiler/semantic/v2_semantic_checking/scope.py b/src/cool_compiler/cmp/scope.py similarity index 95% rename from src/cool_compiler/semantic/v2_semantic_checking/scope.py rename to src/cool_compiler/cmp/scope.py index c7e46b95a..3dd5cf985 100755 --- a/src/cool_compiler/semantic/v2_semantic_checking/scope.py +++ b/src/cool_compiler/cmp/scope.py @@ -31,7 +31,7 @@ def define_variable(self, vname, vtype): self.locals.append(info) return info - def find_variable(self, vname, index=None): + 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) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index d3909b62c..2ee19c0b0 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -60,13 +60,16 @@ class Type(Node): def __init__(self, name) -> None: self.name = name self.attributes = [] + self.attr = {} self.method_list = [] self.methods = {} - def attr_push(self, name): + 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] @@ -78,7 +81,7 @@ def __str__(self) -> str: result = f'type {self.name}: ' + '{\n' for att in self.attributes: - result += '\tattribute ' + str(att) + '\n' + result += '\tattribute ' + str(att) + ' '*(15 - len(str(att))) + '-> ' + str(self.attr[func]) + '\n' for func in self.method_list: result += '\tfunction ' + str(func) + ' '*(15 - len(str(func))) + '-> ' + str(self.methods[func]) + '\n' @@ -119,25 +122,29 @@ def get_name(self, name): except KeyError: return f'{name}@{index}' - def force_local(self,name): - self.var_dir[name] = name + 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): - self.var_dir[name] = 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): + def param_push(self, name, scope): new_name = self.get_name(name) - self.var_dir[name] = new_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): + def local_push(self, name, scope): new_name = self.get_name(name) - self.var_dir[name] = new_name + scope.define_variable(name, new_name) + self.var_dir[new_name] = 1 self.local.append(new_name) return new_name diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 6ff5895b6..f071cfd77 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -1,3 +1,4 @@ +from cool_compiler.cmp.scope import Scope from cool_compiler.types.cool_type_build_in_manager import CoolTypeBuildInManager from cool_compiler.types.type import Type from ...cmp import visitor @@ -38,38 +39,43 @@ def __init__(self, errors) -> None: self.label_list = {} @visitor.on('node') - def visit(node): + def visit(node, scope: Scope): return [ASTR.Sum(super_value, 'a', 'b')] @visitor.when(AST.Program) - def visit(self, node: AST.Program): + def visit(self, node: AST.Program, scope: Scope = None): self.program = ASTR.Program() + scope = Scope() for cls in node.class_list: - self.visit(cls) + self.visit(cls, scope) return self.program @visitor.when(AST.CoolClass) - def visit(self, node: AST.CoolClass): + def visit(self, node: AST.CoolClass, scope: Scope): + self.class_scope = scope.create_child(node.type.name) + self.new_class_scope = scope.create_child(f'new_{node.type.name}') + self.currentType = ASTR.Type(node.type.name) self.currentClass = node.type self.new_type_func = ASTR.Function(f'new@ctr@{node.type.name}') + self.program.add_type(self.currentType) for parent in parent_list(node): for attr in parent.attributes: - self.currentType.attr_push(attr.name) + 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.new_type_func.force_local('instance') + self.new_type_func.force_local('instance', self.new_class_scope) self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) for feat in node.feature_list: - self.visit(feat) + self.visit(feat, self.class_scope) if node.type.name == 'Main': - self.new_type_func.force_local(result) + self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main@Main')) self.new_type_func.expr_push(ASTR.Return(0)) @@ -79,29 +85,30 @@ def visit(self, node: AST.CoolClass): self.program.add_func(self.new_type_func) @visitor.when(AST.AtrDef) - def visit(self, node: AST.AtrDef): + def visit(self, node: AST.AtrDef, scope: Scope): if not node.expr is None: save_current_func = self.currentFunc self.currentFunc = self.new_type_func - attr_name = self.new_type_func.param_push(node.name) - exp_list = self.visit(node.expr) + attr_name = self.new_type_func.local_push(node.name, self.new_class_scope) + exp_list = self.visit(node.expr, self.new_class_scope) exp_list[-1].set_value(attr_name) - exp_list.append(ASTR.SetAttr('instance', node.name, attr_name)) + exp_list.append(ASTR.SetAttr('instance', self.currentType.attr[node.name], attr_name)) self.new_type_func.expr += exp_list self.currentFunc = save_current_func @visitor.when(AST.FuncDef) - def visit(self, node: 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') + self.currentFunc.force_parma('self', func_scope) for name, t_params in node.params: - self.currentFunc.param_push(name) - - expr_list = self.visit(node.expr) - self.currentFunc.force_local(result) + self.currentFunc.param_push(name, func_scope) + + expr_list = self.visit(node.expr, func_scope) + self.currentFunc.force_local(result, func_scope) cond = expr_list[-1].try_set_value(result) expr_list.append(ASTR.Return(result if cond else 'self')) @@ -109,15 +116,15 @@ def visit(self, node: AST.FuncDef): self.currentFunc.expr = expr_list @visitor.when(AST.CastingDispatch) - def visit(self, node: AST.CastingDispatch): - instance_expr_list = self.visit(node.expr) - instance_name = self.currentFunc.local_push(f'instance_{node.type.name}_to_{node.id}') + def visit(self, node: AST.CastingDispatch, scope: Scope): + 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) arg_list = [instance_name] for i, param in enumerate(node.params): - instance_expr_list += self.visit(param) - param_name = self.currentFunc.local_push(f'param_{i}_to_{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) arg_list.append(param_name) @@ -128,16 +135,16 @@ def visit(self, node: AST.CastingDispatch): return instance_expr_list @visitor.when(AST.Dispatch) - def visit(self, node: AST.Dispatch): - instance_expr_list = self.visit(node.expr) - instance_name = self.currentFunc.local_push(f'instance_to_call_{node.id}') + def visit(self, node: AST.Dispatch, scope: Scope): + instance_expr_list = self.visit(node.expr, scope) + instance_name = self.currentFunc.local_push(f'instance_to_call_{node.id}', scope) instance_expr_list[-1].set_value(instance_name) arg_list = [instance_name] for i, param in enumerate(node.params): - instance_expr_list += self.visit(param) - param_name = self.currentFunc.local_push(f'param_{i}_to_{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) arg_list.append(param_name) @@ -148,12 +155,12 @@ def visit(self, node: AST.Dispatch): return instance_expr_list @visitor.when(AST.StaticDispatch) - def visit(self, node: AST.StaticDispatch): + def visit(self, node: AST.StaticDispatch, scope: Scope): arg_list = ['self'] param_expr_list = [] for i, param in enumerate(node.params): - param_expr_list += self.visit(param) - param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}') + param_expr_list += self.visit(param, scope) + param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) param_expr_list[-1].set_value(param_name) arg_list.append(param_name) @@ -165,85 +172,86 @@ def visit(self, node: AST.StaticDispatch): @visitor.when(AST.Assing) - def visit(self, node: AST.Assing): - exp_list = self.visit(node.expr) - result_local = self.currentFunc.local_push(f'result@assing@{node.id}') + def visit(self, node: AST.Assing, scope: Scope): + exp_list = self.visit(node.expr, scope) + result_local = self.currentFunc.local_push(f'result@assing@{node.id}', scope) exp_list[-1].set_value(result_local) + + var = scope.find_variable(node.id) + if not var is None: + exp_list.append(ASTR.Assign(var.type, result_local)) + exp_list.append(ASTR.Assign(super_value, var.type)) + else: + exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.id], result_local)) + exp_list.append(ASTR.GetAttr(super_value , 'self', self.currentType.attr[node.id])) - try: - result_name = self.currentFunc.var_dir[node.id] - exp_list.append(ASTR.Assign(result_name, result_local)) - except: - result_name = node.id - exp_list.append(ASTR.SetAttr('self', self.currentType.name, result_local)) - - exp_list.append(ASTR.Assign(super_value, result_name)) return exp_list @visitor.when(AST.IfThenElse) - def visit(self, node: AST.IfThenElse): - cond_result = self.currentFunc.local_push(f'cond@if_else') + def visit(self, node: AST.IfThenElse, scope: Scope): + cond_result = self.currentFunc.local_push(f'cond@if_else', scope) - expr_list = self.visit(node.condition) + expr_list = self.visit(node.condition, scope) expr_list[-1].set_value(cond_result) - result_if = self.currentFunc.local_push('result@if') + result_if = self.currentFunc.local_push('result@if', scope) label_then = new_name(f'then@{self.currentFunc.name}') label_fin = new_name(f'fin@{self.currentFunc.name}') expr_list.append(ASTR.IfGoTo(cond_result, label_then)) - else_list = self.visit(node.else_expr) + else_list = self.visit(node.else_expr, scope) else_list[-1].set_value(result_if) expr_list += else_list + [ASTR.GoTo(label_fin), ASTR.Label(label_then)] then_list = self.visit(node.then_expr) - then_list[-1].set_value(result_if) + then_list[-1].set_value(result_if, scope) expr_list += then_list + [ASTR.Label(label_fin)] return expr_list + [ASTR.Assign(super_value, result_if)] @visitor.when(AST.While) - def visit(self, node: AST.While): + def visit(self, node: AST.While, scope: Scope): while_cond = new_name('while@cond', self.label_list) while_back = new_name('while@back', self.label_list) result_list = [ASTR.GoTo(while_cond), ASTR.Label(while_back)] - result_list += self.visit(node.loop_expr) + result_list += self.visit(node.loop_expr, scope) result_list += [ASTR.Label(while_cond)] - cond_local = self.currentFunc.local_push('cond@while') - result_list += self.visit(node.condition) + cond_local = self.currentFunc.local_push('cond@while', scope) + result_list += self.visit(node.condition, scope) result_list[-1].set_value(cond_local) result_list.append(ASTR.IfGoTo(cond_local, while_back)) return result_list + [ASTR.Assign(super_value, 'self')] @visitor.when(AST.Block) - def visit(self, node: AST.Block): + def visit(self, node: AST.Block, scope: Scope): result_list = [] _len = len(node.expr_list) - 1 for i, expr in enumerate(node.expr_list): if i == _len: result_step = super_value - else: result_step = self.currentFunc.local_push('step@block') - result_list += self.visit(expr) + else: result_step = self.currentFunc.local_push('step@block', scope) + result_list += self.visit(expr, scope) result_list[-1].set_value(result_step) return result_list @visitor.when(AST.LetIn) - def visit(self, node: AST.LetIn): + def visit(self, node: AST.LetIn, scope: Scope): result_list = [] + let_scope = scope.create_child('let') for name, _, expr in node.assing_list: - local_name = self.currentFunc.local_push(f'let_in@{name}') + local_name = self.currentFunc.local_push(name, let_scope) if not expr is None: - result_list += self.visit(expr) + result_list += self.visit(expr, let_scope) result_list[-1].set_value(local_name) - return result_list + self.visit(node.expr) + return result_list + self.visit(node.expr, let_scope) @visitor.when(AST.Case) - def visit(self, node: AST.Case): + def visit(self, node: AST.Case, scope: Scope): expr_cond_list = self.visit(node.expr) case_cond_name = self.currentFunc.local_push('case@expr') expr_cond_list[-1].set_value(case_cond_name) @@ -270,74 +278,74 @@ def visit(self, node: AST.Case): + expr_list + [ASTR.Label(case_fin_label), ASTR.Assign(super_value, case_result)]) - def binary_op(self, name, node, astr_node): - op_1 = self.currentFunc.local_push(f'{name}@_a') - op_2 = self.currentFunc.local_push(f'{name}@_b') + 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 = self.visit(node.left) + result_list = self.visit(node.left, scope) result_list[-1].set_value(op_1) - result_list += self.visit(node.right) + result_list += self.visit(node.right, scope) result_list[-1].set_value(op_2) return result_list + [astr_node(super_value, op_1, op_2)] @visitor.when(AST.Sum) - def visit(self, node: AST.Sum): - return self.binary_op('sum', node, ASTR.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): - return self.binary_op('rest', node, ASTR.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): - return self.binary_op('factor', node, ASTR.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): - return self.binary_op('div', node, ASTR.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): - return self.binary_op('less', node, ASTR.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): - return self.binary_op('le', node, ASTR.LessOrEqual) + def visit(self, node: AST.LessOrEquals, scope: Scope): + return self.binary_op('le', node, ASTR.LessOrEqual, scope) @visitor.when(AST.Equals) - def visit(self, node: AST.Equals): + def visit(self, node: AST.Equals, scope: Scope): if node.static_type in [CoolInt, CoolBool]: - return self.binary_op('int_eq', node, ASTR.CmpInt) + return self.binary_op('int_eq', node, ASTR.CmpInt, scope) if node.static_type == CoolStr: - return self.binary_op('str_eq', node, ASTR.CmpStr) + return self.binary_op('str_eq', node, ASTR.CmpStr, scope) - return self.binary_op('req_eq', node, ASTR.CmpRef) + return self.binary_op('req_eq', node, ASTR.CmpRef, scope) @visitor.when(AST.New) - def visit(self, node: AST.New): + def visit(self, node: AST.New, scope: Scope): return [ASTR.New(super_value, node.item.name)] - def unary_op(self, name, node, astr_node): - op = self.currentFunc.local_push(f'{name}@_unary') - result_list = self.visit(node.item) + def unary_op(self, name, node, astr_node, scope: Scope): + op = self.currentFunc.local_push(f'{name}@_unary', scope) + result_list = self.visit(node.item, scope) result_list[-1].set_value(op) return result_list + [astr_node(super_value, op)] @visitor.when(AST.Complement) - def visit(self, node: AST.Complement): - return self.unary_op('compl', node, ASTR.Complemnet) + def visit(self, node: AST.Complement, scope: Scope): + return self.unary_op('compl', node, ASTR.Complemnet, scope) @visitor.when(AST.Neg) - def visit(self, node: AST.Neg): - return self.unary_op('neg', node, ASTR.Neg) + def visit(self, node: AST.Neg, scope: Scope): + return self.unary_op('neg', node, ASTR.Neg, scope) @visitor.when(AST.Void) - def visit(self, node: AST.Void): - op_1 = self.currentFunc.local_push('void@_op') - null = self.currentFunc.local_push('void@_null') - unary_list = self.unary_op('void', node, ASTR.Complemnet) + def visit(self, node: AST.Void, scope: Scope): + op_1 = self.currentFunc.local_push('void@_op', scope) + null = self.currentFunc.local_push('void@_null', scope) + unary_list = self.unary_op('void', node, ASTR.Complemnet, scope) unary_list[-1].set_value(op_1) return ( @@ -346,13 +354,27 @@ def visit(self, node: AST.Void): + [ASTR.CmpRef(super_value, null, op_1)] ) - # @visitor.when(AST.Id) - # def visit(self, node: AST.Id): - # try: + @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.Assign(super_value, var.type)] + else: + return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] + @visitor.when(AST.Int) + @visitor.result(ASTR.Int) + def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: + return [ASTR.Assign(super_value, node.item)] + @visitor.when(AST.Bool) + @visitor.result(ASTR.Bool) + def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: + if node.item == 'True': value = 1 + else: value = 0 + return [ASTR.Assign(super_value, value)] @visitor.when(AST.Str) - def visit(self, node: AST.Str): + def visit(self, node: AST.Str, scope: Scope): name = self.program.add_data('string', node.item) return [ASTR.Load(super_value, name)] \ No newline at end of file diff --git a/src/cool_compiler/semantic/tools.py b/src/cool_compiler/semantic/tools.py index 1a648f6f5..953075c26 100755 --- a/src/cool_compiler/semantic/tools.py +++ b/src/cool_compiler/semantic/tools.py @@ -1,6 +1,6 @@ from cool_compiler.cmp.visitor import result from .__dependency import CoolTypeBuildInManager, SemanticError, ErrorType, Type, Object, CoolError -from .v2_semantic_checking.scope import Scope +from ..cmp.scope import Scope class VisitBase: def __init__(self, error) -> None: 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 index f3f406f71..059fe3694 100644 --- a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -5,7 +5,7 @@ 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 .scope import Scope +from ...cmp.scope import Scope CoolInt = CoolTypeBuildInManager().find("Int") From 329b95522113cfd936fc90a40e7730f322fd8923 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 15:39:12 -0500 Subject: [PATCH 23/91] write mips hello work --- src/cool_compiler/__main__.py | 6 +- .../codegen/v0_type_data_code/mipsgenerate.py | 57 -------- .../v0_type_data_code/type_data_code_ast.py | 9 +- .../codegen/v1_mips_generate/mipsgenerate.py | 138 ++++++++++++++++++ .../v1_mips_generate/mipsgenerate_ast.py | 88 +++++++++++ 5 files changed, 236 insertions(+), 62 deletions(-) delete mode 100644 src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index de7ce95c6..c126e3a5d 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -1,4 +1,6 @@ import sys + +from cool_compiler.codegen.v1_mips_generate.mipsgenerate import MipsGenerate from .error import CoolError from .lexer import CoolLexer from .parser import CoolParser @@ -8,8 +10,6 @@ path = "test.cl" - - with open(path, 'r') as _file: text = _file.read() errors = CoolError(text) @@ -25,7 +25,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py b/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py deleted file mode 100644 index 3c1bb2ed8..000000000 --- a/src/cool_compiler/codegen/v0_type_data_code/mipsgenerate.py +++ /dev/null @@ -1,57 +0,0 @@ -from cool_compiler.types.type import Type -from ...cmp import visitor -from ...semantic.v2_semantic_checking import semantic_checking_ast as AST -from . import type_data_code_ast as ASTR -from .type_data_code_ast import result, super_value - - -class MipsGenerate: - def __init__(self, errors) -> None: - self.errors = errors - self.data =[] - self.text=[] - - - - @visitor.on('node') - def visit(node): - pass - - @visitor.when(ASTR.Program) - def visit(self, node: ASTR.Program): - self.Program = node - for Function in node.functions: - Function.visit(node) - pass - - @visitor.when(ASTR.Local) - def visit(self, node: ASTR.Local): - s ="" - s = str(node.x) + ":" + " .word" + " 11" - self.data.append(s) - pass - - @visitor.when(ASTR.Data) - def visit (self , node:ASTR.Data) : - pass - - - @visitor.when(ASTR.ALLOCATE) - def visit (self,node : ASTR.ALLOCATE): - - - pass - - - @visitor.when(ASTR.Arg) - def visit (self,node : ASTR.Arg): - pass - - - - @visitor.when(ASTR.Call) - def visit (self,node : ASTR.Call): - pass - - - diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 11d1a8f2c..77df3047f 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -253,8 +253,7 @@ class Load(Expression): class ALLOCATE(Expression): pass -class Local(Expression): - pass + class NegAssing(Expression): pass @@ -279,3 +278,9 @@ class Neg(Expression): class Complemnet(Expression): pass + +class Local(Expression): + pass + +class Param(Expression): + pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py new file mode 100644 index 000000000..be0ffc276 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -0,0 +1,138 @@ +from cool_compiler.types.type import Type +from ...cmp import visitor +from ..v0_type_data_code import type_data_code_ast as AST +from . import mipsgenerate_ast as ASTR +from ..v0_type_data_code.type_data_code_ast import result, super_value + +class MipsGenerate: + def __init__(self, errors) -> None: + self.func_list = ['new_ctr_Main'] + self.native_fun = { + "IO_out_string": ASTR.Out_String + } + + @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 func in self.func_list: + self.visit(self.cil_func[func]) + + return self.new_program + + @visitor.when(AST.Function) + def visit(self, node: AST.Function): + if node.name in self.native_fun: + self.new_program[node.name] = self.native_fun[node.name]() + + new_func = ASTR.Func(node.name if not node.name == 'new_ctr_Main' else 'main') + self.stack_dir = {} + self.stack_pointer = 0 + self.local_stack_pointer = 0 + + for _local in node.local: + new_func.cmd += self.visit(_local) + + new_func.cmd += self.visit(AST.Local('$ra')) + [AST.SW('$ra', "4($sp)")] + + for param in node.param: + new_func.cmd += self.visit(param) + + for expr in node.expr: + new_func.cmd += self.visit(expr) + + self.new_program.func[node.name] = new_func + + @visitor.when(AST.Param) + def visit(self, node: AST.Param): + self.stack_pointer += 4 + self.local_stack_pointer += 4 + self.stack_dir[node.x] = self.stack_pointer + + @visitor.when(AST.Local) + def visit(self, node: AST.Local): + self.stack_pointer += 4 + self.local_stack_pointer += 4 + self.stack_dir[node.x] = 0 + for key in self.stack_dir.keys(): + self.stack_dir[key] += 4 + + return [ASTR.AddI('$sp', '$sp', -4)] + + @visitor.when(AST.ALLOCATE) + def visit(self, node: AST.ALLOCATE): + memory_dir = node.x + _type = node.y + + stack_plus = self.stack_dir[memory_dir] + _len = len(self.cil_type[_type].attributes) + + return [ + ASTR.LI('$a0', _len), + ASTR.LI('$v0', 9), + ASTR.SysCall(), + ASTR.SW('$v0', f'{stack_plus}($sp)') + ] + + @visitor.when(AST.Arg) + def visit(self, node: AST.Arg): + memory_dir = node.x + + stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer + self.local_stack_pointer) + self.local_stack_pointer += 4 + + return [ + ASTR.LW('$t0', f'{stack_plus}($sp)'), + ASTR.SW('$t0', '0($sp)'), + ASTR.AddI('$sp', '$sp', -4) + ] + + @visitor.when(AST.Call) + def visit(self, node: AST.Call): + memory_dest = node.x + _type = node.y + func = node.z + + self.func_list.append(func) + stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer + self.local_stack_pointer) + self.local_stack_pointer = self.stack_pointer + + return [ + ASTR.JAL(func), + ASTR.SW('$s0', f'{stack_plus}($sp)' ) + ] + + @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 + stack_plus = self.stack_dir[memory_dest] + + return [ + ASTR.LW('$s0', f'{stack_plus}($sp)'), + ASTR.LW('$ra', f'4($sp)'), + ASTR.AddI('$sp', '$sp', stack_plus), + ASTR.JR('$ra') + ] + + @visitor.when(AST.Load) + def visit(self, node: AST.Load): + memory_dest = node.x + data_label = node.y + + stack_plus = self.stack_dir[memory_dest] + + return [ + ASTR.LW('$t0', data_label), + ASTR.SW('$t0', f'{stack_plus}($sp)') + ] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py new file mode 100644 index 000000000..a2501bb27 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -0,0 +1,88 @@ +from cProfile import label + + +class Program: + def __init__(self) -> None: + self.data = {} + self.func = {} + + def __str__(self) -> str: + result = ".data" + + for key in self.data.keys(): + result += str(self.data[key]) + '\n' + + result += '.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' + + return result + +class Data: + def __init__(self, _type, name, value) -> None: + self.type = _type + self.name = name + self.value = value + + def __str__(self) -> str: + return f'{self.name}: .{self.type} {self.value}' + +class Func: + def __init__(self, name, list_cmd= []) -> None: + self.name = name + self.cmd = list_cmd + + def __str__(self) -> str: + result = f'{self.name}:\n' + + for cmd in self.cmd: + result += str(cmd) + '\n' + + return result + +class Comment: + def __init__(self, msg) -> None: + self.msg = msg + + def __str__(self) -> str: + return self.msg + +class Load: + def __init__(self, cmd ,registry, memory_dir) -> None: + self.registry = registry + self.memory_dir = memory_dir + self.cmd = cmd + + def __str__(self) -> str: + return f'{self.cmd} {self.registry}, {self.memory_dir}' + +class Store: + def __init__(self, cmd ,registry, memory_dir) -> None: + self.registry = registry + self.memory_dir = memory_dir + self.cmd = cmd + + def __str__(self) -> str: + return f'{self.cmd} {self.registry}, {self.memory_dir}' + +class CmpNotJump: + def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + self.r_assign = r_dest + self.r_op_1 = r_src_1 + self.r_op_2 = r_src_2 + self.cmd = cmd + + def __str__(self) -> str: + return f'{self.cmd} {self.r_assign}, {self.r_op_1}, {self.r_op_2}' + +# Commands +############################ Loads ################################################## +class LW(Load): + def __init__(self, registry, memory_dir) -> None: + super().__init__('lw', registry, memory_dir) + +############################ Store ################################################## +############################ Cmp ################################################## From 21dd9d98847ca9d20d8de67702d00ca60e88950c Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 15:57:22 -0500 Subject: [PATCH 24/91] refactor v0 codegen --- src/cool_compiler/__main__.py | 4 +-- .../v0_type_data_code/type_data_code_ast.py | 31 ++++++++++++------- .../type_data_code_visitor.py | 12 +++---- src/cool_compiler/pr.py | 2 -- 4 files changed, 26 insertions(+), 23 deletions(-) delete mode 100644 src/cool_compiler/pr.py diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index c126e3a5d..8b681080e 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -25,14 +25,12 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) print(ast) - print(type(ast)) - print((ast.types['Main'].method_list)) #print(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 77df3047f..a60cfa1a3 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -5,6 +5,18 @@ self_name = 'self' super_value = '' +class StackData: + def __init__(self, x = None) -> None: + self.x = x + + def __str__(self) -> str: + return self.x + +class Local(StackData): + pass + +class Param(StackData): + pass class Node: def get_pos_to_error(self, lineno, index): @@ -43,8 +55,8 @@ def try_add_data(self, 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}') + 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] @@ -125,27 +137,27 @@ def get_name(self, name): def force_local(self,name, scope): scope.define_variable(name, name) self.var_dir[name] = 1 - self.local.append(name) + self.local.append(Local(name)) return name def force_parma(self,name, scope): self.var_dir[name] = 1 scope.define_variable(name, name) - self.param.append(name) + self.param.append(Param(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) + self.param.append(Param(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) + self.local.append(Local(new_name)) return new_name def expr_push(self, expr): @@ -257,7 +269,7 @@ class ALLOCATE(Expression): class NegAssing(Expression): pass -class IfGoTo(Exception): +class IfGoTo(Expression): pass class GoTo(Expression): @@ -279,8 +291,3 @@ class Complemnet(Expression): pass -class Local(Expression): - pass - -class Param(Expression): - pass \ No newline at end of file diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index f071cfd77..0c1729214 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -40,7 +40,7 @@ def __init__(self, errors) -> None: @visitor.on('node') def visit(node, scope: Scope): - return [ASTR.Sum(super_value, 'a', 'b')] + pass @visitor.when(AST.Program) def visit(self, node: AST.Program, scope: Scope = None): @@ -58,15 +58,15 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.currentType = ASTR.Type(node.type.name) self.currentClass = node.type - self.new_type_func = ASTR.Function(f'new@ctr@{node.type.name}') + self.new_type_func = ASTR.Function(f'new_ctr_{node.type.name}') self.program.add_type(self.currentType) for parent in parent_list(node): for attr in parent.attributes: - self.currentType.attr_push(attr.name, f'{parent.name}@{attr.name}') + 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.currentType.method_push(func.name, f'{parent.name}_{func.name}') self.new_type_func.force_local('instance', self.new_class_scope) self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) @@ -77,7 +77,7 @@ def visit(self, node: AST.CoolClass, scope: Scope): if node.type.name == 'Main': self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) - self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main@Main')) + self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main_Main')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) @@ -100,7 +100,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): @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.currentFunc = ASTR.Function(f'{self.currentType.name}_{node.name}') self.program.add_func(self.currentFunc) self.currentFunc.force_parma('self', func_scope) diff --git a/src/cool_compiler/pr.py b/src/cool_compiler/pr.py deleted file mode 100644 index 19262e696..000000000 --- a/src/cool_compiler/pr.py +++ /dev/null @@ -1,2 +0,0 @@ -a = 5 -print(a) \ No newline at end of file From 9ab245550cb7252d267a1d6816d5c53272c16d2c Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 16:07:54 -0500 Subject: [PATCH 25/91] refactor v0 codegen func name with class --- src/cool_compiler/__main__.py | 4 ++++ .../codegen/v0_type_data_code/type_data_code_visitor.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 8b681080e..6fb1eff50 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -8,6 +8,10 @@ from .types import CoolTypeBuildInManager from .codegen import CILGenerate +path = "" +if len(sys.argv) > 1: + path = sys.argv[1] + path = "test.cl" with open(path, 'r') as _file: diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 0c1729214..0c14b0dd8 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -131,7 +131,7 @@ def visit(self, node: AST.CastingDispatch, scope: Scope): for arg in arg_list: instance_expr_list.append(ASTR.Arg(arg)) - instance_expr_list.append(ASTR.VCall(super_value, node.type.name, node.id)) + instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) return instance_expr_list @visitor.when(AST.Dispatch) @@ -151,7 +151,7 @@ def visit(self, node: AST.Dispatch, scope: Scope): for arg in arg_list: instance_expr_list.append(ASTR.Arg(arg)) - instance_expr_list.append(ASTR.VCall(super_value, node.type.name, node.id)) + instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) return instance_expr_list @visitor.when(AST.StaticDispatch) @@ -167,7 +167,7 @@ def visit(self, node: AST.StaticDispatch, scope: Scope): for arg in arg_list: param_expr_list.append(ASTR.Arg(arg)) - param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) + param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, self.currentType.methods[node.id])) return param_expr_list From 77f499229b42daf3f8196ba46e618f358d7a8241 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 16:15:29 -0500 Subject: [PATCH 26/91] finsh refactor --- .../codegen/v0_type_data_code/type_data_code_ast.py | 2 +- .../codegen/v0_type_data_code/type_data_code_visitor.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index a60cfa1a3..04c3217de 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -93,7 +93,7 @@ def __str__(self) -> str: result = f'type {self.name}: ' + '{\n' for att in self.attributes: - result += '\tattribute ' + str(att) + ' '*(15 - len(str(att))) + '-> ' + str(self.attr[func]) + '\n' + 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' diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 0c14b0dd8..789c8df85 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -63,6 +63,7 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.program.add_type(self.currentType) for parent in parent_list(node): + self.currentType.attr_push('type', self.currentType.name) for attr in parent.attributes: self.currentType.attr_push(attr.name, f'{parent.name}_{attr.name}') for func in parent.methods: From 5c0efcee1a3fb7e173ef5f57acb7948b9c00e18e Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Tue, 22 Feb 2022 16:16:13 -0500 Subject: [PATCH 27/91] escribiendoast --- .../codegen/v1_mips_generate/mipsgenerate.py | 2 +- .../v1_mips_generate/mipsgenerate_ast.py | 69 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index be0ffc276..bd4190c08 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -41,7 +41,7 @@ def visit(self, node: AST.Function): for _local in node.local: new_func.cmd += self.visit(_local) - new_func.cmd += self.visit(AST.Local('$ra')) + [AST.SW('$ra', "4($sp)")] + new_func.cmd += self.visit(AST.Local('$ra')) + [ASTR.SW('$ra', "4($sp)")] for param in node.param: new_func.cmd += self.visit(param) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index a2501bb27..1a9e999a9 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -1,4 +1,5 @@ from cProfile import label +from webbrowser import Opera class Program: @@ -78,11 +79,77 @@ def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: def __str__(self) -> str: return f'{self.cmd} {self.r_assign}, {self.r_op_1}, {self.r_op_2}' -# Commands +class JumpInconditional: + def __init__(self,cmd,dest) -> None: + self.cmd=cmd + self.dest = dest + + + def __str__(self) -> str: + return f'{self.cmd} {self.dest}' + + + + +class SysCall : + def __init__(self) -> None: + pass + + def __str__(self) -> str: + return f'{"syscall"}' + +class Operation: + def __init__(self,cmd,dest,op1,op2) -> None: + self.cmd=cmd + self.dest = dest + self.op_1 = op1 + self.op_2 = op2 + + def __str__(self) -> str: + return f'{self.cmd} {self.dest}, {self.op_1}, {self.op_2}' + + +class Out_String: + def __init__(self) -> None: + pass + + def __str__(self) -> str: + s= "li $v0 , 4\n" + "lw $a0 , 4($sp)\n" + "syscall\n" + "lw $a0 , 8($sp)\n" + "jr $ra" + + ############################ Loads ################################################## class LW(Load): def __init__(self, registry, memory_dir) -> None: super().__init__('lw', registry, memory_dir) +class LI(Load): + def __init__(self, registry, memory_dir) -> None: + super().__init__('li', registry, memory_dir) + + + ############################ Store ################################################## +class SW(Store): + def __init__(self, registry, memory_dir) -> None: + super().__init__('sw', registry, memory_dir) + + + ############################ Cmp ################################################## + +########################### Jump ##################################################### +class JAL(JumpInconditional): + def __init__(self,dest) -> None: + super().__init__('jal',dest) + +class JR(JumpInconditional): + def __init__(self,dest) -> None: + super().__init__('jr',dest) + + +################################# Operator ############################################## + +class AddI(Operation): + def __init__(self,dest,op1,op2) -> None: + super().__init__('addi',dest,op1,op2) + From f98b5d5c08a69a79e08a8fff910672a36fac5e2f Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Tue, 22 Feb 2022 16:21:41 -0500 Subject: [PATCH 28/91] escrast --- src/cool_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 6fb1eff50..0f348cb58 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -29,7 +29,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate , MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) From baac6532ecd5cd3f3dea999f11fa0edcdbfa3084 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 16:40:22 -0500 Subject: [PATCH 29/91] fist misp --- .../v0_type_data_code/type_data_code_visitor.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 4 +++- .../codegen/v1_mips_generate/mipsgenerate_ast.py | 11 ++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 789c8df85..cfe1cfe4e 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -78,7 +78,7 @@ def visit(self, node: AST.CoolClass, scope: Scope): if node.type.name == 'Main': self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) - self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'main_Main')) + self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'Main_main')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index bd4190c08..deace9d40 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -49,13 +49,14 @@ def visit(self, node: AST.Function): for expr in node.expr: new_func.cmd += self.visit(expr) - self.new_program.func[node.name] = new_func + self.new_program.func[new_func.name] = new_func @visitor.when(AST.Param) def visit(self, node: AST.Param): self.stack_pointer += 4 self.local_stack_pointer += 4 self.stack_dir[node.x] = self.stack_pointer + return [] @visitor.when(AST.Local) def visit(self, node: AST.Local): @@ -130,6 +131,7 @@ def visit(self, node: AST.Load): memory_dest = node.x data_label = node.y + self.new_program.data[data_label] = ASTR.Data('word', data_label, self.cil_data[data_label].value) stack_plus = self.stack_dir[memory_dest] return [ diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 1a9e999a9..945d95048 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -1,17 +1,13 @@ -from cProfile import label -from webbrowser import Opera - - class Program: def __init__(self) -> None: self.data = {} self.func = {} def __str__(self) -> str: - result = ".data" + result = ".data\n" for key in self.data.keys(): - result += str(self.data[key]) + '\n' + result += str(self.data[key]) + '\n\n' result += '.text\n.globl main\n' result += str(self.func['main']) + '\n' @@ -29,7 +25,8 @@ def __init__(self, _type, name, value) -> None: self.value = value def __str__(self) -> str: - return f'{self.name}: .{self.type} {self.value}' + if self.value[-1] == '\n': self.value = self.value[0:-1] + return f'{self.name}: .{self.type} \"{str(self.value)}\"' class Func: def __init__(self, name, list_cmd= []) -> None: From d6a2fa2f62e36d1b82b7a9d38ef668e430c50b47 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 17:21:48 -0500 Subject: [PATCH 30/91] ready print hello word init test --- .../v0_type_data_code/type_data_code_visitor.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 14 ++++++++------ .../codegen/v1_mips_generate/mipsgenerate_ast.py | 10 +++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index cfe1cfe4e..89c6c9da8 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -78,7 +78,7 @@ def visit(self, node: AST.CoolClass, scope: Scope): if node.type.name == 'Main': self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) - self.new_type_func.expr_push(ASTR.Call(result, 'Main', 'Main_main')) + self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'Main_main')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index deace9d40..a4c079f0c 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -24,15 +24,15 @@ def visit(self, node: AST.Program): self.new_program = ASTR.Program() for func in self.func_list: - self.visit(self.cil_func[func]) + if func in self.native_fun: + self.new_program.func[func] = self.native_fun[func]() + else: + self.visit(self.cil_func[func]) return self.new_program @visitor.when(AST.Function) def visit(self, node: AST.Function): - if node.name in self.native_fun: - self.new_program[node.name] = self.native_fun[node.name]() - new_func = ASTR.Func(node.name if not node.name == 'new_ctr_Main' else 'main') self.stack_dir = {} self.stack_pointer = 0 @@ -51,6 +51,8 @@ def visit(self, node: AST.Function): self.new_program.func[new_func.name] = new_func + # print(new_func) + @visitor.when(AST.Param) def visit(self, node: AST.Param): self.stack_pointer += 4 @@ -96,8 +98,8 @@ def visit(self, node: AST.Arg): ASTR.AddI('$sp', '$sp', -4) ] - @visitor.when(AST.Call) - def visit(self, node: AST.Call): + @visitor.when(AST.VCall) + def visit(self, node: AST.VCall): memory_dest = node.x _type = node.y func = node.z diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 945d95048..b47525f0e 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -29,13 +29,12 @@ def __str__(self) -> str: return f'{self.name}: .{self.type} \"{str(self.value)}\"' class Func: - def __init__(self, name, list_cmd= []) -> None: + def __init__(self, name) -> None: self.name = name - self.cmd = list_cmd + self.cmd = [] def __str__(self) -> str: result = f'{self.name}:\n' - for cmd in self.cmd: result += str(cmd) + '\n' @@ -107,11 +106,8 @@ def __str__(self) -> str: class Out_String: - def __init__(self) -> None: - pass - def __str__(self) -> str: - s= "li $v0 , 4\n" + "lw $a0 , 4($sp)\n" + "syscall\n" + "lw $a0 , 8($sp)\n" + "jr $ra" + return "IO_out_string:\nli $v0, 4\nlw $a0, 4($sp)\nsyscall\nlw $a0, 8($sp)\njr $ra" ############################ Loads ################################################## From 8fa3ae8dee567b01bc1c0ea096283c8c00c95730 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 22 Feb 2022 17:33:46 -0500 Subject: [PATCH 31/91] add write .s --- src/cool_compiler/__main__.py | 8 +++++--- .../codegen/v1_mips_generate/mipsgenerate.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 0f348cb58..b1e60fcac 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -16,6 +16,7 @@ with open(path, 'r') as _file: text = _file.read() + _file.close() errors = CoolError(text) lexer = CoolLexer(errors) type_manager = CoolTypeBuildInManager() @@ -35,6 +36,7 @@ ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) - print(ast) - #print(ast) - + +with open(path.replace('.cl', '.s'), '+w') as _file: + _file.write(str(ast)) + _file.close() \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index a4c079f0c..bed2215d7 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -89,7 +89,7 @@ def visit(self, node: AST.ALLOCATE): def visit(self, node: AST.Arg): memory_dir = node.x - stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer + self.local_stack_pointer) + stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer - self.local_stack_pointer) self.local_stack_pointer += 4 return [ @@ -105,7 +105,7 @@ def visit(self, node: AST.VCall): func = node.z self.func_list.append(func) - stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer + self.local_stack_pointer) + stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer - self.local_stack_pointer) self.local_stack_pointer = self.stack_pointer return [ From 5651f3d16caf7c0e4efeaaf23c3fd5f64baab746 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Wed, 23 Feb 2022 10:00:49 -0500 Subject: [PATCH 32/91] fusion --- src/cool_compiler/__main__.py | 4 ++++ .../codegen/v1_mips_generate/mipsgenerate.py | 6 +++--- .../codegen/v1_mips_generate/mipsgenerate_ast.py | 11 +++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 0f348cb58..a560e932e 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -1,4 +1,5 @@ import sys +from cool_compiler.codegen.v0_type_data_code.type_data_code_ast import Type from cool_compiler.codegen.v1_mips_generate.mipsgenerate import MipsGenerate from .error import CoolError @@ -35,6 +36,9 @@ ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) + + + print(ast) #print(ast) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index a4c079f0c..48fb96108 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -89,7 +89,7 @@ def visit(self, node: AST.ALLOCATE): def visit(self, node: AST.Arg): memory_dir = node.x - stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer + self.local_stack_pointer) + stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer - self.local_stack_pointer) self.local_stack_pointer += 4 return [ @@ -105,7 +105,7 @@ def visit(self, node: AST.VCall): func = node.z self.func_list.append(func) - stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer + self.local_stack_pointer) + stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer - self.local_stack_pointer) self.local_stack_pointer = self.stack_pointer return [ @@ -137,6 +137,6 @@ def visit(self, node: AST.Load): stack_plus = self.stack_dir[memory_dest] return [ - ASTR.LW('$t0', data_label), + ASTR.LA('$t0', data_label), ASTR.SW('$t0', f'{stack_plus}($sp)') ] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index b47525f0e..19997b304 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -26,6 +26,9 @@ def __init__(self, _type, name, value) -> None: def __str__(self) -> str: if self.value[-1] == '\n': self.value = self.value[0:-1] + if(type(self.value==type("string"))): + return f'{self.name}: .asciiz \"{str(self.value)}\"' + return f'{self.name}: .{self.type} \"{str(self.value)}\"' class Func: @@ -107,7 +110,7 @@ def __str__(self) -> str: class Out_String: def __str__(self) -> str: - return "IO_out_string:\nli $v0, 4\nlw $a0, 4($sp)\nsyscall\nlw $a0, 8($sp)\njr $ra" + return "IO_out_string:\nli $v0, 4\nlw $a0, 20($sp)\nsyscall\nlw $a0, 8($sp)\njr $ra" ############################ Loads ################################################## @@ -119,7 +122,11 @@ class LI(Load): def __init__(self, registry, memory_dir) -> None: super().__init__('li', registry, memory_dir) - +class LA(Load): + def __init__(self, registry, memory_dir) -> None: + super().__init__('la', registry, memory_dir) + + ############################ Store ################################################## class SW(Store): From 4f926a98aba97412ab638b340e9eace65c334857 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 10:02:09 -0500 Subject: [PATCH 33/91] add comment --- src/cool_compiler/__main__.py | 2 +- .../v0_type_data_code/type_data_code_ast.py | 6 +- .../type_data_code_visitor.py | 148 ++++++++++++++---- .../codegen/v1_mips_generate/mipsgenerate.py | 13 +- .../v1_mips_generate/mipsgenerate_ast.py | 15 +- src/test.s | 45 ++++++ 6 files changed, 184 insertions(+), 45 deletions(-) create mode 100644 src/test.s diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index b1e60fcac..b9aa73e31 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -30,7 +30,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate , MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate ]#, MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 04c3217de..53463feb5 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -253,9 +253,6 @@ class Return(Expression): class Arg(Expression): pass -class Call(Expression): - pass - class VCall(Expression): pass @@ -290,4 +287,7 @@ class Neg(Expression): class Complemnet(Expression): pass +class Comment(Expression): + pass + diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 89c6c9da8..397838476 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -1,5 +1,5 @@ from cool_compiler.cmp.scope import Scope -from cool_compiler.types.cool_type_build_in_manager import CoolTypeBuildInManager +from cool_compiler.types.cool_type_build_in_manager import OBJECT_NAME, CoolTypeBuildInManager from cool_compiler.types.type import Type from ...cmp import visitor from ...semantic.v2_semantic_checking import semantic_checking_ast as AST @@ -10,7 +10,7 @@ CoolInt = CoolTypeBuildInManager().find("Int") CoolBool = CoolTypeBuildInManager().find("Bool") CoolStr = CoolTypeBuildInManager().find("String") - +CoolObject = CoolTypeBuildInManager().find(OBJECT_NAME) def parent_list(node: AST.CoolClass): parent_list = [] @@ -37,6 +37,15 @@ class CILGenerate: def __init__(self, errors) -> None: self.errors = errors self.label_list = {} + self.type_dir = { + OBJECT_NAME: 0 + } + + def map_type(self, name): + try: return self.type_dir[name] + except KeyError: + self.type_dir[name] = len(self.type_dir.keys()) + return self.type_dir[name] @visitor.on('node') def visit(node, scope: Scope): @@ -62,15 +71,27 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.program.add_type(self.currentType) + type_list = [self.map_type(node.type.name)] for parent in parent_list(node): + type_list.append(self.map_type(parent.name)) self.currentType.attr_push('type', 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.data[f'{node.type.name}_parents'] = ASTR.Data(f'{node.type.name}_parents', type_list) + self.program.data[f'{node.type.name}_name'] = ASTR.Data(f'{node.type.name}_name', node.type.name) + self.new_type_func.force_local('instance', self.new_class_scope) + tn = self.new_type_func.local_push('type_name', self.new_class_scope) self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) + self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {node.type.name}')) + self.new_type_func.expr_push(ASTR.Load(tn, f'{node.type.name}_name')) + self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) + self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) + self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) + for feat in node.feature_list: self.visit(feat, self.class_scope) @@ -79,6 +100,7 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'Main_main')) + self.new_type_func.expr_push(ASTR.Comment(f'Llamando al mentodo inicial del programa')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) @@ -94,6 +116,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): exp_list = self.visit(node.expr, self.new_class_scope) exp_list[-1].set_value(attr_name) exp_list.append(ASTR.SetAttr('instance', self.currentType.attr[node.name], attr_name)) + exp_list.append(ASTR.Comment(f"Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}")) self.new_type_func.expr += exp_list self.currentFunc = save_current_func @@ -113,6 +136,7 @@ def visit(self, node: AST.FuncDef, scope: Scope): cond = expr_list[-1].try_set_value(result) expr_list.append(ASTR.Return(result if cond else 'self')) + expr_list.append(ASTR.Comment(f"Final de la function {node.name}")) self.currentFunc.expr = expr_list @@ -121,17 +145,20 @@ def visit(self, node: AST.CastingDispatch, scope: Scope): 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 += 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 arg in arg_list: + for i, arg in enumerate(arg_list): instance_expr_list.append(ASTR.Arg(arg)) - + instance_expr_list.append(f'Agrega a la pila el paramentro {i} al CastingDispatch {node.id}') + instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) return instance_expr_list @@ -140,6 +167,7 @@ def visit(self, node: AST.Dispatch, scope: Scope): instance_expr_list = self.visit(node.expr, scope) instance_name = self.currentFunc.local_push(f'instance_to_call_{node.id}', scope) instance_expr_list[-1].set_value(instance_name) + instance_expr_list.append(ASTR.Comment(f"Fin de la exprecion previa al Dispatch {node.id}")) arg_list = [instance_name] @@ -147,10 +175,12 @@ def visit(self, node: AST.Dispatch, scope: Scope): 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 Dispatch {node.id}")) arg_list.append(param_name) - for arg in arg_list: + for i, arg in enumerate(arg_list): instance_expr_list.append(ASTR.Arg(arg)) + instance_expr_list.append(f'Agrega a la pila el paramentro {i} al Dispatch {node.id}') instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) return instance_expr_list @@ -163,10 +193,12 @@ def visit(self, node: AST.StaticDispatch, scope: Scope): param_expr_list += self.visit(param, scope) param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) param_expr_list[-1].set_value(param_name) + param_expr_list.append(ASTR.Comment(f"Fin del paramentro {i} al StaticDispatch {node.id}")) arg_list.append(param_name) - for arg in arg_list: + for i, arg in enumerate(arg_list): param_expr_list.append(ASTR.Arg(arg)) + param_expr_list.append(ASTR.Comment(f'Agrega a la pila el paramentro {i} al StaticDispatch {node.id}')) param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, self.currentType.methods[node.id])) return param_expr_list @@ -177,6 +209,7 @@ def visit(self, node: AST.Assing, scope: Scope): exp_list = self.visit(node.expr, scope) result_local = self.currentFunc.local_push(f'result@assing@{node.id}', scope) exp_list[-1].set_value(result_local) + exp_list.append(ASTR.Comment(f'Fin de la expresion lista para ser asignada')) var = scope.find_variable(node.id) if not var is None: @@ -194,20 +227,24 @@ def visit(self, node: AST.IfThenElse, scope: Scope): expr_list = self.visit(node.condition, scope) expr_list[-1].set_value(cond_result) + expr_list.append(ASTR.Comment(f'Fin de la evaluacion de la condicion de un IF')) result_if = self.currentFunc.local_push('result@if', scope) label_then = new_name(f'then@{self.currentFunc.name}') label_fin = new_name(f'fin@{self.currentFunc.name}') expr_list.append(ASTR.IfGoTo(cond_result, label_then)) + expr_list.append(ASTR.Comment(f'Else case')) else_list = self.visit(node.else_expr, scope) else_list[-1].set_value(result_if) 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) then_list[-1].set_value(result_if, scope) 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, result_if)] @@ -216,24 +253,29 @@ def visit(self, node: AST.While, scope: Scope): while_cond = new_name('while@cond', self.label_list) while_back = new_name('while@back', self.label_list) + result_list.append(ASTR.Comment(f'Inicio de un While')) result_list = [ASTR.GoTo(while_cond), ASTR.Label(while_back)] result_list += self.visit(node.loop_expr, scope) result_list += [ASTR.Label(while_cond)] + result_list.append(ASTR.Comment(f'Fin del cuerpo e inicio de la condicion de un While')) cond_local = self.currentFunc.local_push('cond@while', scope) result_list += self.visit(node.condition, scope) result_list[-1].set_value(cond_local) result_list.append(ASTR.IfGoTo(cond_local, while_back)) + result_list.append(ASTR.Comment(f'Fin de la condicion de un While')) 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 = self.currentFunc.local_push('step@block', scope) + 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) @@ -244,40 +286,81 @@ def visit(self, node: AST.LetIn, scope: Scope): result_list = [] let_scope = scope.create_child('let') for name, _, expr in node.assing_list: - local_name = self.currentFunc.local_push(name, let_scope) + local_name = self.currentFunc.force_local(name, let_scope) if not expr is None: 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}')) + + + return result_list + self.visit(node.expr, let_scope) + + def basic_cond_case(self, node: AST.Case, scope: Scope, expr_cond_list): + if not node.expr.static_type in [CoolBool, CoolInt, CoolStr]: return [] + + for name, atype , expr in node.case_list: + if node.expr.static_type.conforms_to(atype): + case_scope = scope.create_child('basic_case') + self.currentFunc.force_local(name, case_scope) + expr_cond_list[-1].set_value(name) + expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) + return expr_cond_list + self.visit(expr, case_scope) + + return expr_cond_list + + def object_case_with_ref_cond(self, node: AST.Case, scope: Scope, expr_cond_list): + for name, atype , expr in node.case_list: + if node.expr.static_type.conforms_to(atype): + case_scope = scope.create_child('basic_case') + self.currentFunc.force_local(name, case_scope) + expr_cond_list[-1].set_value(name) + expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) + return expr_cond_list + self.visit(expr, case_scope) + if not atype in [CoolBool, CoolInt, CoolStr]: break + return [] + + def general_case(self, node: AST.Case, scope: Scope, expr_cond_list): + cond_result = self.currentFunc.local_push('cond@result', scope) + expr_cond_list[-1].set_value(cond_result) + type_result = self.currentFunc.local_push('cond@type', scope) + expr_cond_list.append(ASTR.TypeOf(type_result, cond_result)) + final_result = self.currentFunc.local_push('case_result', scope) + + expr_list = [] + end_label = new_name('case_end', self.label_list) + step_case = self.currentFunc.local_push('step@case', scope) + for name, atype , expr in node.case_list: + step_label = new_name(f'{atype.name}_step_case', self.label_list) + expr_cond_list.append(ASTR.CheckType(step_case, type_result, atype.name)) + expr_cond_list.append(ASTR.Comment(f'Check case tipo {atype.name} en un case')) + expr_cond_list.append(ASTR.IfGoTo(step_case, step_label)) - return result_list + self.visit(node.expr, let_scope) + expr_list.append(ASTR.Label(step_label)) + step_scope = scope.create_child('step_case') + self.currentFunc.force_local(name, step_scope) + expr_list += self.visit(expr, step_scope) + expr_list[-1].set_value(final_result) + expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) + expr_list.append(ASTR.GoTo(end_label)) + + return ( + expr_cond_list + + expr_list + + [ASTR.Label(end_label)] + + [ASTR.Assign(super_value, final_result)] + ) @visitor.when(AST.Case) def visit(self, node: AST.Case, scope: Scope): expr_cond_list = self.visit(node.expr) - case_cond_name = self.currentFunc.local_push('case@expr') - expr_cond_list[-1].set_value(case_cond_name) - case_cond_type = self.currentFunc.local_push('case@type') - expr_cond_list.append(ASTR.TypeOf(case_cond_type, case_cond_name)) - case_result = self.currentFunc.local_push('case@result') - case_fin_label = new_name('case@fin', self.label_list) - expr_list = [] - for name, atype , expr in node.case_list: - # get type for iter - # compare type - # self.program.try_add_data(f'type@{atype.name}', atype.name) - case_label = new_name('case@step@label', self.label_list) - local_cmp = self.currentFunc.local_push('case@cmp') - expr_cond_list.append(ASTR.IfGoTo(local_cmp, case_label)) - - expr_list += [ASTR.Label(case_label)] - expr_list += self.visit(expr) - expr_list[-1].set_value(case_result) - expr_list += [ASTR.GoTo(case_fin_label)] - - return (expr_cond_list - + expr_list - + [ASTR.Label(case_fin_label), ASTR.Assign(super_value, case_result)]) + result = self.basic_cond_case(node, scope, expr_cond_list) + if any(result): return result + + result = self.object_case_with_ref_cond(node, scope, expr_cond_list) + if any(result): return result + + return self.general_case(node, scope, expr_cond_list) def binary_op(self, name, node, astr_node, scope: Scope): op_1 = self.currentFunc.local_push(f'{name}@_a', scope) @@ -285,8 +368,11 @@ def binary_op(self, name, node, astr_node, scope: Scope): 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 opercion {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 opercion {name}')) return result_list + [astr_node(super_value, op_1, op_2)] diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index bed2215d7..0c02491cf 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -41,7 +41,10 @@ def visit(self, node: AST.Function): for _local in node.local: new_func.cmd += self.visit(_local) - new_func.cmd += self.visit(AST.Local('$ra')) + [ASTR.SW('$ra', "4($sp)")] + new_func.cmd += ( + self.visit(AST.Local('$ra')) + + [ASTR.SW('$ra', "4($sp)")] + + [ASTR.Comment(f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {node.name}")]) for param in node.param: new_func.cmd += self.visit(param) @@ -68,7 +71,7 @@ def visit(self, node: AST.Local): for key in self.stack_dir.keys(): self.stack_dir[key] += 4 - return [ASTR.AddI('$sp', '$sp', -4)] + return [ASTR.AddI('$sp', '$sp', -4), ASTR.Comment(f'Push local var {node.x}')] @visitor.when(AST.ALLOCATE) def visit(self, node: AST.ALLOCATE): @@ -139,4 +142,8 @@ def visit(self, node: AST.Load): return [ ASTR.LW('$t0', data_label), ASTR.SW('$t0', f'{stack_plus}($sp)') - ] \ No newline at end of file + ] + + @visitor.when(AST.Comment) + def visit(self, node: AST.Comment): + return [ASTR.Comment(node.x)] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index b47525f0e..e71168a4d 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -36,16 +36,20 @@ def __init__(self, name) -> None: def __str__(self) -> str: result = f'{self.name}:\n' for cmd in self.cmd: - result += str(cmd) + '\n' - + try: + if cmd.is_comment: + result = result[0:-1] + ' ' * 10 + str(cmd) + '\n' + except AttributeError: + result += str(cmd) + '\n' return result class Comment: def __init__(self, msg) -> None: self.msg = msg - + self.is_comment = True + def __str__(self) -> str: - return self.msg + return f'//{self.msg}' class Load: def __init__(self, cmd ,registry, memory_dir) -> None: @@ -84,9 +88,6 @@ def __init__(self,cmd,dest) -> None: def __str__(self) -> str: return f'{self.cmd} {self.dest}' - - - class SysCall : def __init__(self) -> None: pass diff --git a/src/test.s b/src/test.s new file mode 100644 index 000000000..0622850ac --- /dev/null +++ b/src/test.s @@ -0,0 +1,45 @@ +.TYPE +type Main: { + attribute type -> Main + function abort -> Object_abort + function copy -> Object_copy + function type_name -> Object_type_name + function in_int -> IO_in_int + function in_string -> IO_in_string + function out_int -> IO_out_int + function out_string -> IO_out_string + function main -> Main_main +} +.DATA + data string_0: Hello, World. + +.FUNCTION +function Main_main: { + PARAM self + LOCAL param_0_to_out_string@0 + LOCAL @result + Load param_0_to_out_string@0 string_0 + Comment Fin del paramentro 0 al StaticDispatch out_string + Arg self + Comment Agrega a la pila el paramentro 0 al StaticDispatch out_string + Arg param_0_to_out_string@0 + Comment Agrega a la pila el paramentro 1 al StaticDispatch out_string + VCall @result Main IO_out_string + Return @result + Comment Final de la function main +} +function new_ctr_Main: { + LOCAL instance + LOCAL type_name@0 + LOCAL @result + ALLOCATE instance Main + Comment Reservando memoria para una instancia de tipo Main + Load type_name@0 Main_name + Comment Cargando el nombre del tipo desde el data + SetAttr instance type type_name@0 + Comment Assignando el nombre del tipo en el campo type + Arg instance + VCall @result Main Main_main + Comment Llamando al mentodo inicial del programa + Return 0 +} From d31111a9af6fccfef98b8acaffa9b16cecb84a1d Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 11:40:59 -0500 Subject: [PATCH 34/91] ready helloe work --- src/cool_compiler/__main__.py | 2 +- .../type_data_code_visitor.py | 1 - .../codegen/v1_mips_generate/mipsgenerate.py | 76 +++++++------ .../v1_mips_generate/mipsgenerate_ast.py | 11 +- src/test.s | 100 ++++++++++-------- 5 files changed, 108 insertions(+), 82 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 19ec027c1..80a95af86 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -31,7 +31,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate ]#, MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 397838476..7da6934e8 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -100,7 +100,6 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'Main_main')) - self.new_type_func.expr_push(ASTR.Comment(f'Llamando al mentodo inicial del programa')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index bd8287ec2..d4130a5c5 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -34,51 +34,51 @@ def visit(self, node: AST.Program): @visitor.when(AST.Function) def visit(self, node: AST.Function): new_func = ASTR.Func(node.name if not node.name == 'new_ctr_Main' else 'main') - self.stack_dir = {} - self.stack_pointer = 0 - self.local_stack_pointer = 0 + self.stack = [] + self.final_len_stack = len(node.param) + len(node.local) + 2 + self.local_push = 0 + + for param in [AST.Param('Return $ra')] + node.param: + new_func.cmd += self.visit(param) - for _local in node.local: + for _local in node.local + [AST.Local('$ra')]: new_func.cmd += self.visit(_local) new_func.cmd += ( - self.visit(AST.Local('$ra')) + - [ASTR.SW('$ra', "4($sp)")] + + [ASTR.SW('$ra', "0($sp)")] + [ASTR.Comment(f"Agrega $ra a la pila para salvar el punto de retorno de la funcion {node.name}")]) - for param in node.param: - new_func.cmd += self.visit(param) - for expr in node.expr: new_func.cmd += self.visit(expr) self.new_program.func[new_func.name] = new_func - # print(new_func) + #stack_pointer = 0 + #bsp = self.base_stack_pointer + def stack_index(self, name): + return (len(self.stack) - self.stack.index(name) - 1) * 4 @visitor.when(AST.Param) def visit(self, node: AST.Param): - self.stack_pointer += 4 - self.local_stack_pointer += 4 - self.stack_dir[node.x] = self.stack_pointer - return [] + self.stack.append(node.x) + return [ASTR.Header_Comment(f'Parametro {node.x} en stackpoiner + {(self.final_len_stack - len(self.stack)) * 4}')] + @visitor.when(AST.Local) def visit(self, node: AST.Local): - self.stack_pointer += 4 - self.local_stack_pointer += 4 - self.stack_dir[node.x] = 0 - for key in self.stack_dir.keys(): - self.stack_dir[key] += 4 - - return [ASTR.AddI('$sp', '$sp', -4), ASTR.Comment(f'Push local var {node.x}')] + self.stack.append(node.x) + return [ + ASTR.AddI('$sp', '$sp', -4), + ASTR.Comment( + f'Push local var {node.x} stackpointer {(self.final_len_stack - len(self.stack)) * 4}') + ] @visitor.when(AST.ALLOCATE) def visit(self, node: AST.ALLOCATE): memory_dir = node.x _type = node.y - stack_plus = self.stack_dir[memory_dir] + stack_plus = self.stack_index(memory_dir) _len = len(self.cil_type[_type].attributes) return [ @@ -91,14 +91,17 @@ def visit(self, node: AST.ALLOCATE): @visitor.when(AST.Arg) def visit(self, node: AST.Arg): memory_dir = node.x - - stack_plus = self.stack_dir[memory_dir] + (self.stack_pointer - self.local_stack_pointer) - self.local_stack_pointer += 4 + + stack_plus = self.stack_index(memory_dir) + self.local_push += 1 + self.stack.append(memory_dir) return [ ASTR.LW('$t0', f'{stack_plus}($sp)'), + ASTR.Comment(f'Saca de la pila {node.x}'), + ASTR.AddI('$sp', '$sp', -4), ASTR.SW('$t0', '0($sp)'), - ASTR.AddI('$sp', '$sp', -4) + ASTR.Comment(f'Mete para la pila {node.x}'), ] @visitor.when(AST.VCall) @@ -108,12 +111,14 @@ def visit(self, node: AST.VCall): func = node.z self.func_list.append(func) - stack_plus = self.stack_dir[memory_dest] + (self.stack_pointer - self.local_stack_pointer) - self.local_stack_pointer = self.stack_pointer - + self.stack = self.stack[0: len(self.stack) - self.local_push] + stack_plus = self.stack_index(memory_dest) + return [ ASTR.JAL(func), - ASTR.SW('$s0', f'{stack_plus}($sp)' ) + ASTR.Comment(f'Call a la function {func}'), + ASTR.SW('$s0', f'{stack_plus}($sp)' ), + ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), ] @visitor.when(AST.Return) @@ -122,12 +127,15 @@ def visit(self, node: AST.Return): return [ASTR.LI('$v0', 10), ASTR.SysCall()] memory_dest = node.x - stack_plus = self.stack_dir[memory_dest] + stack_plus = self.stack_index(memory_dest) return [ ASTR.LW('$s0', f'{stack_plus}($sp)'), - ASTR.LW('$ra', f'4($sp)'), - ASTR.AddI('$sp', '$sp', stack_plus), + ASTR.Comment("Envia el resultado de la funcion en $s0"), + ASTR.LW('$ra', f'{(len(self.stack) - 1)* 4}($sp)'), + ASTR.Comment("Lee el $ra mas profundo de la pila para retornar a la funcion anterior"), + ASTR.AddI('$sp', '$sp', len(self.stack) * 4), + ASTR.Comment("Limpia la pila"), ASTR.JR('$ra') ] @@ -137,7 +145,7 @@ def visit(self, node: AST.Load): data_label = node.y self.new_program.data[data_label] = ASTR.Data('word', data_label, self.cil_data[data_label].value) - stack_plus = self.stack_dir[memory_dest] + stack_plus = self.stack_index(memory_dest) return [ ASTR.LA('$t0', data_label), diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 6ec7a7287..8087261c5 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -52,7 +52,14 @@ def __init__(self, msg) -> None: self.is_comment = True def __str__(self) -> str: - return f'//{self.msg}' + return f'#{self.msg}' + +class Header_Comment: + def __init__(self, msg) -> None: + self.msg = msg + + def __str__(self) -> str: + return f'#{self.msg}' class Load: def __init__(self, cmd ,registry, memory_dir) -> None: @@ -111,7 +118,7 @@ def __str__(self) -> str: class Out_String: def __str__(self) -> str: - return "IO_out_string:\nli $v0, 4\nlw $a0, 20($sp)\nsyscall\nlw $a0, 8($sp)\njr $ra" + return "IO_out_string:\nli $v0, 4\nlw $a0, 0($sp)\nsyscall\nlw $a0, 4($sp)\naddi $sp, $sp, 8\njr $ra" ############################ Loads ################################################## diff --git a/src/test.s b/src/test.s index 0622850ac..49d717c0b 100644 --- a/src/test.s +++ b/src/test.s @@ -1,45 +1,57 @@ -.TYPE -type Main: { - attribute type -> Main - function abort -> Object_abort - function copy -> Object_copy - function type_name -> Object_type_name - function in_int -> IO_in_int - function in_string -> IO_in_string - function out_int -> IO_out_int - function out_string -> IO_out_string - function main -> Main_main -} -.DATA - data string_0: Hello, World. +.data +Main_name: .asciiz "Main" -.FUNCTION -function Main_main: { - PARAM self - LOCAL param_0_to_out_string@0 - LOCAL @result - Load param_0_to_out_string@0 string_0 - Comment Fin del paramentro 0 al StaticDispatch out_string - Arg self - Comment Agrega a la pila el paramentro 0 al StaticDispatch out_string - Arg param_0_to_out_string@0 - Comment Agrega a la pila el paramentro 1 al StaticDispatch out_string - VCall @result Main IO_out_string - Return @result - Comment Final de la function main -} -function new_ctr_Main: { - LOCAL instance - LOCAL type_name@0 - LOCAL @result - ALLOCATE instance Main - Comment Reservando memoria para una instancia de tipo Main - Load type_name@0 Main_name - Comment Cargando el nombre del tipo desde el data - SetAttr instance type type_name@0 - Comment Assignando el nombre del tipo en el campo type - Arg instance - VCall @result Main Main_main - Comment Llamando al mentodo inicial del programa - Return 0 -} +string_0: .asciiz "Hello, World." + +.text +.globl main +main: +#Parametro Return $ra 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 +li $a0, 1 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +la $t0, Main_name +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data #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 From fba57451a6a3f54749963aab302e424362e228ef Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 12:44:26 -0500 Subject: [PATCH 35/91] ya hello wold --- src/cool_compiler/__main__.py | 6 +- .../v0_type_data_code/type_data_code_ast.py | 3 +- .../type_data_code_visitor.py | 22 +-- .../v1_mips_generate/mipsgenerate_ast.py | 2 +- src/test.cl | 30 +++- src/test.mips | 158 ++++++++++++++++++ tests/codegen/hello_world.mips | 57 +++++++ 7 files changed, 259 insertions(+), 19 deletions(-) create mode 100644 src/test.mips create mode 100644 tests/codegen/hello_world.mips diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 80a95af86..c3c5cb270 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +# path = "test.cl" with open(path, 'r') as _file: text = _file.read() @@ -31,13 +31,13 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate]#, MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) if errors.any(): sys.exit(1) -with open(path.replace('.cl', '.s'), '+w') as _file: +with open(path.replace('.cl', '.mips'), '+w') as _file: _file.write(str(ast)) _file.close() diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 53463feb5..f6860f3fb 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -288,6 +288,7 @@ class Complemnet(Expression): pass class Comment(Expression): - pass + def __str__(self) -> str: + return "" diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 7da6934e8..8188c8c64 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -27,11 +27,11 @@ def new_name(name, _dict): index = 0 while True: try: - _ = _dict[f'{name}@{index}'] + _ = _dict[f'{name}_{index}'] index += 1 except KeyError: - _dict[f'{name}@{index}'] = 1 - return f'{name}@{index}' + _dict[f'{name}_{index}'] = 1 + return f'{name}_{index}' class CILGenerate: def __init__(self, errors) -> None: @@ -229,8 +229,8 @@ def visit(self, node: AST.IfThenElse, scope: Scope): expr_list.append(ASTR.Comment(f'Fin de la evaluacion de la condicion de un IF')) result_if = self.currentFunc.local_push('result@if', scope) - label_then = new_name(f'then@{self.currentFunc.name}') - label_fin = new_name(f'fin@{self.currentFunc.name}') + label_then = new_name(f'then_{self.currentFunc.name}', self.label_list) + label_fin = new_name(f'fin_{self.currentFunc.name}', self.label_list) expr_list.append(ASTR.IfGoTo(cond_result, label_then)) expr_list.append(ASTR.Comment(f'Else case')) @@ -249,12 +249,14 @@ def visit(self, node: AST.IfThenElse, scope: Scope): @visitor.when(AST.While) def visit(self, node: AST.While, scope: Scope): - while_cond = new_name('while@cond', self.label_list) - while_back = new_name('while@back', self.label_list) + while_cond = new_name('while_cond', self.label_list) + while_back = new_name('while_back', self.label_list) - result_list.append(ASTR.Comment(f'Inicio de un While')) - result_list = [ASTR.GoTo(while_cond), ASTR.Label(while_back)] + 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_local) result_list += [ASTR.Label(while_cond)] result_list.append(ASTR.Comment(f'Fin del cuerpo e inicio de la condicion de un While')) @@ -449,12 +451,10 @@ def visit(self, node: AST.Id, scope: Scope): return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] @visitor.when(AST.Int) - @visitor.result(ASTR.Int) def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: return [ASTR.Assign(super_value, node.item)] @visitor.when(AST.Bool) - @visitor.result(ASTR.Bool) def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: if node.item == 'True': value = 1 else: value = 0 diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 8087261c5..90ae8d5da 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -25,7 +25,7 @@ def __init__(self, _type, name, value) -> None: self.value = value def __str__(self) -> str: - if self.value[-1] == '\n': self.value = self.value[0:-1] + if self.value[-1] == '\n': self.value = self.value[0:-1] + '\\n' if(type(self.value==type("string"))): return f'{self.name}: .asciiz \"{str(self.value)}\"' diff --git a/src/test.cl b/src/test.cl index b41b36c81..5d612ee92 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,5 +1,29 @@ class Main inherits IO { - main(): IO { - out_string("Hello, World.\n") - }; + -- the class has features. Only methods in this case. + main(): Object { + { + out_string("Enter n to find nth fibonacci number!\n"); + out_int(fib(in_int())); + out_string("\n"); + } + }; + + fib(i : Int) : Int { -- list of formals. And the return type of the method. + let a : Int <- 1, + b : Int <- 0, + c : Int <- 0 + in + { + while (not (i = 0)) loop -- expressions are nested. + { + c <- a + b; + i <- i - 1; + b <- a; + a <- c; + } + pool; + c; + } + }; + }; \ No newline at end of file diff --git a/src/test.mips b/src/test.mips new file mode 100644 index 000000000..4b724f43c --- /dev/null +++ b/src/test.mips @@ -0,0 +1,158 @@ +.TYPE +type Main: { + attribute type -> Main + function abort -> Object_abort + function copy -> Object_copy + function type_name -> Object_type_name + function in_int -> IO_in_int + function in_string -> IO_in_string + function out_int -> IO_out_int + function out_string -> IO_out_string + function main -> Main_main + function fib -> Main_fib +} +.DATA + data string_0: Enter n to find nth fibonacci number! + + data string_1: + +.FUNCTION +function Main_main: { + PARAM self + LOCAL step@block@0 + LOCAL param_0_to_out_string@0 + LOCAL step@block@1 + LOCAL param_0_to_fib@0 + LOCAL param_0_to_out_int@0 + LOCAL param_0_to_out_string@1 + LOCAL @result + + + Load param_0_to_out_string@0 string_0 + + Arg self + + Arg param_0_to_out_string@0 + + VCall step@block@0 Main IO_out_string + + Arg self + + VCall param_0_to_fib@0 Main IO_in_int + + Arg self + + Arg param_0_to_fib@0 + + VCall param_0_to_out_int@0 Main Main_fib + + Arg self + + Arg param_0_to_out_int@0 + + VCall step@block@1 Main IO_out_int + + Load param_0_to_out_string@1 string_1 + + Arg self + + Arg param_0_to_out_string@1 + + VCall @result Main IO_out_string + Return @result + +} +function Main_fib: { + PARAM self + PARAM i@0 + LOCAL a + LOCAL b + LOCAL c + LOCAL step@block@0 + LOCAL result@while@0 + LOCAL step@block@1 + LOCAL sum@_a@0 + LOCAL sum@_b@0 + LOCAL result@assing@c@0 + LOCAL step@block@2 + LOCAL rest@_a@0 + LOCAL rest@_b@0 + LOCAL result@assing@i@0 + LOCAL step@block@3 + LOCAL result@assing@b@0 + LOCAL result@assing@a@0 + LOCAL cond@while@0 + LOCAL neg@_unary@0 + LOCAL int_eq@_a@0 + LOCAL int_eq@_b@0 + LOCAL @result + Assign a 1 + + Assign b 0 + + Assign c 0 + + + + + GoTo while_cond_0 + Label while_back_0 + + + Assign sum@_a@0 a + + Assign sum@_b@0 b + + Sum result@assing@c@0 sum@_a@0 sum@_b@0 + + Assign c result@assing@c@0 + Assign step@block@1 c + + Assign rest@_a@0 i@0 + + Assign rest@_b@0 1 + + Rest result@assing@i@0 rest@_a@0 rest@_b@0 + + Assign i@0 result@assing@i@0 + Assign step@block@2 i@0 + + Assign result@assing@b@0 a + + Assign b result@assing@b@0 + Assign step@block@3 b + + Assign result@assing@a@0 c + + Assign a result@assing@a@0 + Assign result@while@0 a + Label while_cond_0 + + Assign int_eq@_a@0 i@0 + + Assign int_eq@_b@0 0 + + CmpInt neg@_unary@0 int_eq@_a@0 int_eq@_b@0 + Neg cond@while@0 neg@_unary@0 + IfGoTo cond@while@0 while_back_0 + + Assign step@block@0 self + + Assign @result c + Return @result + +} +function new_ctr_Main: { + LOCAL instance + LOCAL type_name@0 + LOCAL @result + ALLOCATE instance Main + + Load type_name@0 Main_name + + SetAttr instance type type_name@0 + + Arg instance + VCall @result Main Main_main + Return 0 +} diff --git a/tests/codegen/hello_world.mips b/tests/codegen/hello_world.mips new file mode 100644 index 000000000..5c396d0bd --- /dev/null +++ b/tests/codegen/hello_world.mips @@ -0,0 +1,57 @@ +.data +Main_name: .asciiz "Main" + +string_0: .asciiz "Hello, World.\n" + +.text +.globl main +main: +#Parametro Return $ra 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 +li $a0, 1 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +la $t0, Main_name +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data #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 From df11740abb1484c780cab8c0328821d6f0aa7cd6 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Wed, 23 Feb 2022 12:52:32 -0500 Subject: [PATCH 36/91] com --- .../v1_mips_generate/mipsgenerate_ast.py | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 8087261c5..3057f5bb3 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -1,3 +1,6 @@ +from ast import Compare + + class Program: def __init__(self) -> None: self.data = {} @@ -25,7 +28,7 @@ def __init__(self, _type, name, value) -> None: self.value = value def __str__(self) -> str: - if self.value[-1] == '\n': self.value = self.value[0:-1] + if self.value[-1] == '\n': self.value = self.value[0:-1] + '\\n' if(type(self.value==type("string"))): return f'{self.name}: .asciiz \"{str(self.value)}\"' @@ -145,6 +148,26 @@ def __init__(self, registry, memory_dir) -> None: ############################ Cmp ################################################## +class SEQ(CmpNotJump): #comparacion igualdad + def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + super().__init__( 'seq' ,r_dest, r_src_1, r_src_2) + +class SGE(CmpNotJump): + def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + super().__init__( 'sge' ,r_dest, r_src_1, r_src_2) + +class SLT (CmpNotJump): + def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + super().__init__( 'slt' ,r_dest, r_src_1, r_src_2) + + +class SLE(CmpNotJump): + def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) + + + + ########################### Jump ##################################################### class JAL(JumpInconditional): def __init__(self,dest) -> None: @@ -161,3 +184,9 @@ class AddI(Operation): def __init__(self,dest,op1,op2) -> None: super().__init__('addi',dest,op1,op2) + +class Add(Operation): + def __init__(self,dest,op1,op2) -> None: + super().__init__('addi',dest,op1,op2) + + From a7897f56a7e35f130d6815d6d5e408866380fbfd Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 15:51:24 -0500 Subject: [PATCH 37/91] cil compile ol test --- src/cool_compiler/__main__.py | 2 +- .../v0_type_data_code/type_data_code_ast.py | 3 + .../type_data_code_visitor.py | 35 +-- .../codegen/v1_mips_generate/mipsgenerate.py | 72 +++++- .../v1_mips_generate/mipsgenerate_ast.py | 5 +- .../semantic_checking_visitor.py | 4 +- src/test.cl | 32 +-- src/test.mips | 218 +++++------------- tests/codegen/hello_world.mips | 57 ----- 9 files changed, 157 insertions(+), 271 deletions(-) delete mode 100644 tests/codegen/hello_world.mips diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index c3c5cb270..f28534900 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -31,7 +31,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate]#, MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index f6860f3fb..b94a0f2ad 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -256,6 +256,9 @@ class Arg(Expression): class VCall(Expression): pass +class Call(Expression): + pass + class Load(Expression): pass diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 8188c8c64..1b8901053 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -6,7 +6,6 @@ from . import type_data_code_ast as ASTR from .type_data_code_ast import result, super_value - CoolInt = CoolTypeBuildInManager().find("Int") CoolBool = CoolTypeBuildInManager().find("Bool") CoolStr = CoolTypeBuildInManager().find("String") @@ -71,35 +70,35 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.program.add_type(self.currentType) - type_list = [self.map_type(node.type.name)] + type_list = [] for parent in parent_list(node): type_list.append(self.map_type(parent.name)) self.currentType.attr_push('type', self.currentType.name) for attr in parent.attributes: - self.currentType.attr_push(attr.name, f'{parent.name}_{attr.name}') + 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.data[f'{node.type.name}_parents'] = ASTR.Data(f'{node.type.name}_parents', type_list) - self.program.data[f'{node.type.name}_name'] = ASTR.Data(f'{node.type.name}_name', node.type.name) + self.program.data_list += [f'{node.type.name}_parents'] + self.new_type_func.force_parma('self', self.new_class_scope) self.new_type_func.force_local('instance', self.new_class_scope) tn = self.new_type_func.local_push('type_name', self.new_class_scope) self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {node.type.name}')) - self.new_type_func.expr_push(ASTR.Load(tn, f'{node.type.name}_name')) + self.new_type_func.expr_push(ASTR.Load(tn, f'{node.type.name}_parents')) self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) - for feat in node.feature_list: self.visit(feat, self.class_scope) if node.type.name == 'Main': self.new_type_func.force_local(result, self.new_class_scope) self.new_type_func.expr_push(ASTR.Arg('instance')) - self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'Main_main')) + self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'main')) self.new_type_func.expr_push(ASTR.Return(0)) else: self.new_type_func.expr_push(ASTR.Return('instance')) @@ -108,8 +107,11 @@ def visit(self, node: AST.CoolClass, scope: Scope): @visitor.when(AST.AtrDef) def visit(self, node: AST.AtrDef, scope: Scope): - if not node.expr is None: - save_current_func = self.currentFunc + if not node.expr in [None, []]: + try: + save_current_func = self.currentFunc + except AttributeError: + save_current_func = None self.currentFunc = self.new_type_func attr_name = self.new_type_func.local_push(node.name, self.new_class_scope) exp_list = self.visit(node.expr, self.new_class_scope) @@ -158,7 +160,7 @@ def visit(self, node: AST.CastingDispatch, scope: Scope): instance_expr_list.append(ASTR.Arg(arg)) instance_expr_list.append(f'Agrega a la pila el paramentro {i} al CastingDispatch {node.id}') - instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) + instance_expr_list.append(ASTR.VCall(super_value, node.type.name, node.id)) return instance_expr_list @visitor.when(AST.Dispatch) @@ -181,7 +183,7 @@ def visit(self, node: AST.Dispatch, scope: Scope): instance_expr_list.append(ASTR.Arg(arg)) instance_expr_list.append(f'Agrega a la pila el paramentro {i} al Dispatch {node.id}') - instance_expr_list.append(ASTR.VCall(super_value, node.type.name, self.currentType.methods[node.id])) + instance_expr_list.append(ASTR.Call(super_value, node.id)) return instance_expr_list @visitor.when(AST.StaticDispatch) @@ -199,7 +201,7 @@ def visit(self, node: AST.StaticDispatch, scope: Scope): param_expr_list.append(ASTR.Arg(arg)) param_expr_list.append(ASTR.Comment(f'Agrega a la pila el paramentro {i} al StaticDispatch {node.id}')) - param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, self.currentType.methods[node.id])) + param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) return param_expr_list @@ -239,8 +241,8 @@ def visit(self, node: AST.IfThenElse, scope: Scope): 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) - then_list[-1].set_value(result_if, scope) + then_list = self.visit(node.then_expr, scope) + then_list[-1].set_value(result_if) expr_list += then_list + [ASTR.Label(label_fin)] expr_list.append(ASTR.Comment(f'Fin de un If')) @@ -332,7 +334,7 @@ def general_case(self, node: AST.Case, scope: Scope, expr_cond_list): step_case = self.currentFunc.local_push('step@case', scope) for name, atype , expr in node.case_list: step_label = new_name(f'{atype.name}_step_case', self.label_list) - expr_cond_list.append(ASTR.CheckType(step_case, type_result, atype.name)) + expr_cond_list.append(ASTR.CheckType(step_case, type_result, self.map_type(atype.name))) expr_cond_list.append(ASTR.Comment(f'Check case tipo {atype.name} en un case')) expr_cond_list.append(ASTR.IfGoTo(step_case, step_label)) @@ -353,7 +355,7 @@ def general_case(self, node: AST.Case, scope: Scope, expr_cond_list): @visitor.when(AST.Case) def visit(self, node: AST.Case, scope: Scope): - expr_cond_list = self.visit(node.expr) + expr_cond_list = self.visit(node.expr, scope) result = self.basic_cond_case(node, scope, expr_cond_list) if any(result): return result @@ -447,6 +449,7 @@ def visit(self, node: AST.Id, scope: Scope): var = scope.find_variable(node.item) if not var is None: return [ASTR.Assign(super_value, var.type)] + else: return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index d4130a5c5..6ffe52981 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -1,8 +1,6 @@ -from cool_compiler.types.type import Type from ...cmp import visitor from ..v0_type_data_code import type_data_code_ast as AST from . import mipsgenerate_ast as ASTR -from ..v0_type_data_code.type_data_code_ast import result, super_value class MipsGenerate: def __init__(self, errors) -> None: @@ -62,7 +60,6 @@ def stack_index(self, name): def visit(self, node: AST.Param): self.stack.append(node.x) return [ASTR.Header_Comment(f'Parametro {node.x} en stackpoiner + {(self.final_len_stack - len(self.stack)) * 4}')] - @visitor.when(AST.Local) def visit(self, node: AST.Local): @@ -78,16 +75,71 @@ def visit(self, node: AST.ALLOCATE): memory_dir = node.x _type = node.y - stack_plus = self.stack_index(memory_dir) - _len = len(self.cil_type[_type].attributes) + stack_plus = self.stack_index(memory_dir) + attr_list = self.cil_type[_type].attributes + _len = len(attr_list) * 4 + 4 - return [ + result = [ + ASTR.Header_Comment(f"Allocate a una class {_type} puntero en sp + {stack_plus}"), + ASTR.Header_Comment(f"atributo type en puntero + 0"), + ] + + for i, attr in enumerate(attr_list): + result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {i + 1 * 4}')) + + return result + [ ASTR.LI('$a0', _len), ASTR.LI('$v0', 9), ASTR.SysCall(), ASTR.SW('$v0', f'{stack_plus}($sp)') ] + @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] + + stack_plus_dest = self.stack_index(memory_dest) + stack_plus_instance = self.stack_index(memory_dir_instance) + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + 4 + + return [ + ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), + ASTR.Comment(f'Buscando la instancia de la clase {_type} en la pila'), + ASTR.LW('$t1', f'{attr_plus}($t0)'), + ASTR.Comment(f'Buscando el valor de la propiedad {attr}'), + ASTR.SW('$t1', f'{stack_plus_dest}($sp)'), + ASTR.Comment(f'Salvando el valor de la propiedad {attr} en la pila en el valor local {memory_dest}'), + ] + + @visitor.when(AST.SetAttr) + def visit(self, node: AST.SetAttr): + if node.y == 'type': + attr_plus = 0 + else: + attr_name = node.z.split('@') + _type = attr_name[0] + attr = attr_name[1] + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + 4 + + memory_dir_instance = node.x + memory_dir_value = node.z + + stack_plus_dir_value = self.stack_index(memory_dir_value) + stack_plus_instance = self.stack_index(memory_dir_instance) + + return [ + ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), + ASTR.Comment(f'Buscando la instancia en la pila {node.x}'), + ASTR.LW('$t1', f'{stack_plus_dir_value}($sp)'), + ASTR.Comment(f'Buscando el valor que se va a guardar en la propiedad'), + ASTR.SW('$t1', f'{attr_plus}($t0)'), + ASTR.Comment(f'Seteando el valor en la direccion de la memoria del objeto'), + ] + @visitor.when(AST.Arg) def visit(self, node: AST.Arg): memory_dir = node.x @@ -108,7 +160,7 @@ def visit(self, node: AST.Arg): def visit(self, node: AST.VCall): memory_dest = node.x _type = node.y - func = node.z + func = self.cil_type[_type].methods[node.z] self.func_list.append(func) self.stack = self.stack[0: len(self.stack) - self.local_push] @@ -143,15 +195,15 @@ def visit(self, node: AST.Return): def visit(self, node: AST.Load): memory_dest = node.x data_label = node.y - - self.new_program.data[data_label] = ASTR.Data('word', data_label, self.cil_data[data_label].value) + + self.new_program.data[data_label] = ASTR.Data(data_label, self.cil_data[data_label].value) stack_plus = self.stack_index(memory_dest) return [ ASTR.LA('$t0', data_label), ASTR.SW('$t0', f'{stack_plus}($sp)') ] - + @visitor.when(AST.Comment) def visit(self, node: AST.Comment): return [ASTR.Comment(node.x)] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 90ae8d5da..74f2465d6 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -19,8 +19,7 @@ def __str__(self) -> str: return result class Data: - def __init__(self, _type, name, value) -> None: - self.type = _type + def __init__(self, name, value) -> None: self.name = name self.value = value @@ -29,7 +28,7 @@ def __str__(self) -> str: if(type(self.value==type("string"))): return f'{self.name}: .asciiz \"{str(self.value)}\"' - return f'{self.name}: .{self.type} \"{str(self.value)}\"' + return f'{self.name}: .word \"{str(self.value)}\"' class Func: def __init__(self, name) -> None: 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 index 059fe3694..5068834f1 100644 --- a/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py +++ b/src/cool_compiler/semantic/v2_semantic_checking/semantic_checking_visitor.py @@ -54,11 +54,11 @@ def visit(self, node: AST.AtrDef, scope: Scope) -> ASTR.Node: 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) diff --git a/src/test.cl b/src/test.cl index 5d612ee92..dbab2d3d9 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,29 +1,9 @@ class Main inherits IO { - -- the class has features. Only methods in this case. - main(): Object { - { - out_string("Enter n to find nth fibonacci number!\n"); - out_int(fib(in_int())); - out_string("\n"); - } - }; + main(): IO { + out_string("Hello, World.\n") + }; +}; + + - fib(i : Int) : Int { -- list of formals. And the return type of the method. - let a : Int <- 1, - b : Int <- 0, - c : Int <- 0 - in - { - while (not (i = 0)) loop -- expressions are nested. - { - c <- a + b; - i <- i - 1; - b <- a; - a <- c; - } - pool; - c; - } - }; -}; \ No newline at end of file diff --git a/src/test.mips b/src/test.mips index 4b724f43c..6b34eaf77 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,158 +1,64 @@ -.TYPE -type Main: { - attribute type -> Main - function abort -> Object_abort - function copy -> Object_copy - function type_name -> Object_type_name - function in_int -> IO_in_int - function in_string -> IO_in_string - function out_int -> IO_out_int - function out_string -> IO_out_string - function main -> Main_main - function fib -> Main_fib -} -.DATA - data string_0: Enter n to find nth fibonacci number! +.data +Main_parents: .asciiz "[0, 1, 2]" - data string_1: +string_0: .asciiz "Hello, World.\n" -.FUNCTION -function Main_main: { - PARAM self - LOCAL step@block@0 - LOCAL param_0_to_out_string@0 - LOCAL step@block@1 - LOCAL param_0_to_fib@0 - LOCAL param_0_to_out_int@0 - LOCAL param_0_to_out_string@1 - LOCAL @result - - - Load param_0_to_out_string@0 string_0 - - Arg self - - Arg param_0_to_out_string@0 - - VCall step@block@0 Main IO_out_string - - Arg self - - VCall param_0_to_fib@0 Main IO_in_int - - Arg self - - Arg param_0_to_fib@0 - - VCall param_0_to_out_int@0 Main Main_fib - - Arg self - - Arg param_0_to_out_int@0 - - VCall step@block@1 Main IO_out_int - - Load param_0_to_out_string@1 string_1 - - Arg self - - Arg param_0_to_out_string@1 - - VCall @result Main IO_out_string - Return @result - -} -function Main_fib: { - PARAM self - PARAM i@0 - LOCAL a - LOCAL b - LOCAL c - LOCAL step@block@0 - LOCAL result@while@0 - LOCAL step@block@1 - LOCAL sum@_a@0 - LOCAL sum@_b@0 - LOCAL result@assing@c@0 - LOCAL step@block@2 - LOCAL rest@_a@0 - LOCAL rest@_b@0 - LOCAL result@assing@i@0 - LOCAL step@block@3 - LOCAL result@assing@b@0 - LOCAL result@assing@a@0 - LOCAL cond@while@0 - LOCAL neg@_unary@0 - LOCAL int_eq@_a@0 - LOCAL int_eq@_b@0 - LOCAL @result - Assign a 1 - - Assign b 0 - - Assign c 0 - - - - - GoTo while_cond_0 - Label while_back_0 - - - Assign sum@_a@0 a - - Assign sum@_b@0 b - - Sum result@assing@c@0 sum@_a@0 sum@_b@0 - - Assign c result@assing@c@0 - Assign step@block@1 c - - Assign rest@_a@0 i@0 - - Assign rest@_b@0 1 - - Rest result@assing@i@0 rest@_a@0 rest@_b@0 - - Assign i@0 result@assing@i@0 - Assign step@block@2 i@0 - - Assign result@assing@b@0 a - - Assign b result@assing@b@0 - Assign step@block@3 b - - Assign result@assing@a@0 c - - Assign a result@assing@a@0 - Assign result@while@0 a - Label while_cond_0 - - Assign int_eq@_a@0 i@0 - - Assign int_eq@_b@0 0 - - CmpInt neg@_unary@0 int_eq@_a@0 int_eq@_b@0 - Neg cond@while@0 neg@_unary@0 - IfGoTo cond@while@0 while_back_0 - - Assign step@block@0 self - - Assign @result c - Return @result - -} -function new_ctr_Main: { - LOCAL instance - LOCAL type_name@0 - LOCAL @result - ALLOCATE instance Main - - Load type_name@0 Main_name - - SetAttr instance type type_name@0 - - Arg instance - VCall @result Main Main_main - Return 0 -} +.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_parents +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/tests/codegen/hello_world.mips b/tests/codegen/hello_world.mips deleted file mode 100644 index 5c396d0bd..000000000 --- a/tests/codegen/hello_world.mips +++ /dev/null @@ -1,57 +0,0 @@ -.data -Main_name: .asciiz "Main" - -string_0: .asciiz "Hello, World.\n" - -.text -.globl main -main: -#Parametro Return $ra 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 -li $a0, 1 -li $v0, 9 -syscall -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -la $t0, Main_name -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data #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 From 77795394fac863de2f10de04c004e4d90f25cb9d Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Wed, 23 Feb 2022 16:12:49 -0500 Subject: [PATCH 38/91] fib --- src/cool_compiler/__main__.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 144 +++++++++++++++++- .../v1_mips_generate/mipsgenerate_ast.py | 47 +++++- src/test.s | 58 +------ 4 files changed, 193 insertions(+), 58 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index c3c5cb270..5c57d5068 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -# path = "test.cl" +path = "test.cl" with open(path, 'r') as _file: text = _file.read() diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index d4130a5c5..b7533e007 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -2,7 +2,7 @@ from ...cmp import visitor from ..v0_type_data_code import type_data_code_ast as AST from . import mipsgenerate_ast as ASTR -from ..v0_type_data_code.type_data_code_ast import result, super_value +from ..v0_type_data_code.type_data_code_ast import GoTo, Label, result, super_value class MipsGenerate: def __init__(self, errors) -> None: @@ -154,4 +154,144 @@ def visit(self, node: AST.Load): @visitor.when(AST.Comment) def visit(self, node: AST.Comment): - return [ASTR.Comment(node.x)] \ No newline at end of file + return [ASTR.Comment(node.x)] + + + @visitor.when(AST.CmpInt) + def visit(self,node:AST.CmpInt): + memory_dest = node.x + dir_cmp1 = node.y + dir_cmp2 = node.z + + stack_plus_opr_1 = self.stack_index(dir_cmp1) + stack_plus_opr_2 = self.stack_index(dir_cmp2) + stack_plus_dest = self.stack_index(memory_dest) + + return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , + ASTR.Comment("carga en $t1 lo que hay en f'{stack_plus_opr_1} "), + ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment("carga en $t2 lo que hay en f'{stack_plus_opr_2} "), + ASTR.SEQ ('$t3','$t2','$t1'), + ASTR.Comment("$t3 = $t2 == $ t1" ), + ASTR.SW ('$t3',f'{stack_plus_opr_1}($sp)'), + ASTR.Comment("Pon en la posicion f'{stack_plus_opr_1} el valor de $t3") + ] + + + + @visitor.when(AST.Assign) + def visit(self,node:AST.Assign): + memory_dest = node.x + dir_value = node.y + stack_plus = self.stack_index(memory_dest) + + if(type(dir_value)==type(int()) or type(dir_value)==type(float())): + return [ + ASTR.LI('$t0' , str(dir_value)), + ASTR.Comment("pon en $t0 f'{dir_value} "), + ASTR.SW ('$t0',f'{stack_plus}($sp)'), + ASTR.Comment("pon en la posicion f'{dir_value} el valor $t0 ") + ] + else: + stack_plus_dir_value = self.stack_index(dir_value) + return [ + ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), + ASTR.Comment("pon en $t0 el contenido de la pos f'{stack_plus_dir_value} "), + ASTR.SW ('$t0',f'{stack_plus}($sp)'), + ASTR.Comment("pon en la pos f'{stack_plus_dir_value} el valor de $t0") + ] + + @visitor.when(AST.Neg) + def visit(self,node:AST.Neg): + memory_dest = node.x + memory_op1 = node.y + stack_plus_memory_dest = self.stack_index(memory_dest) + stack_plus_opr_1 = self.stack_index(memory_op1) + + return [ + ASTR.LW ('$t0',f'{stack_plus_opr_1}($sp)'), + ASTR.Comment("Carga la pos f'{stack_plus_opr_1} en $t0"), + ASTR.AddI ('$t1','$t0',-1 ), + ASTR.Comment("$t1 = $t0 + (-1)"), + ASTR.MUL ('$t0','$t1',-1), + ASTR.Comment("$t0 = $t1 * (-1)"), + ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), + ASTR.Comment("poner en la posicion f'{stack_plus_memory_dest} el contenido de $t0") + + + ] + + + @ visitor.when(AST.Sum) + def visit(self,node:AST.Sum): + memory_dest=node.x + memory_op1=node.y + memory_op2=node.z + + stack_plus_memory_dest = self.stack_index(memory_dest) + stack_plus_opr_1 = self.stack_index(memory_op1) + stack_plus_opr_2 = self.stack_index(memory_op2) + + return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), + ASTR.Comment("poner en registro $t0 lo que hay en f'{stack_plus_opr_1}"), + ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment("poner en registro $t1 lo que hay en f'{stack_plus_opr_2}"), + ASTR.Add('$t0' , '$t0','$t1'), + ASTR.Comment("en $t0 pon el resultado de la suma"), + ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), + ASTR.Comment("poner en la posicion f'{stack_plus_memory_dest} el resultado ") + ] + + @ visitor.when(AST.Rest) + def visit(self,node:AST.Rest): + memory_dest=node.x + memory_op1=node.y + memory_op2=node.z + + stack_plus_memory_dest = self.stack_index(memory_dest) + stack_plus_opr_1 = self.stack_index(memory_op1) + stack_plus_opr_2 = self.stack_index(memory_op2) + + return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), + ASTR.Comment("poner en registro $t0 lo que hay en f'{stack_plus_opr_1}"), + ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment("poner en registro $t1 lo que hay en f'{stack_plus_opr_2}"), + ASTR.SUB('$t0' , '$t0','$t1'), + ASTR.Comment("poner en registro $t0 la suma "), + ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), + ASTR.Comment("poner en f'{stack_plus_memory_dest} el resultado de la suma "), + + ] + + + @ visitor.when(AST.IfGoTo) + def visit(self,node:AST.IfGoTo): + memory_cmp = node.x + label_memory = node.y + + stack_plus_memory_cmp = self.stack_index(memory_cmp) + + + return [ASTR.LI("$t0" ,1), + ASTR.Comment("Cargar 1 a $t0 pa comparar"), + ASTR.LW("$t1", f'{stack_plus_memory_cmp}($sp)' ), + ASTR.Comment("Cargar el valor de la pos f'{stack_plus_memory_cmp} a $t1 pa comparar"), + ASTR.BEQ("$t0","$t1", label_memory), + ASTR.Comment("if $t1==$t0 then jump f'{label_memory}") + ] + + + + @ visitor.when(AST.Label) + def visitor(self,node:AST.Label): + return [ASTR.Label(node.x), + ASTR.Comment("Crea el label f'{node.x} ") + ] + + + @ visitor.when(AST.GoTo) + def visitor(self,node:GoTo): + label = node.x + return [ASTR.Jump (label), + ASTR.Comment("Salta para f{label} ") + ] diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 3057f5bb3..3be1f2064 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -64,6 +64,14 @@ def __init__(self, msg) -> None: 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 Load: def __init__(self, cmd ,registry, memory_dir) -> None: self.registry = registry @@ -100,6 +108,17 @@ def __init__(self,cmd,dest) -> None: def __str__(self) -> str: return f'{self.cmd} {self.dest}' + +class JumpConditional: + def __init__(self,cmd,reg1,reg2,label) -> None: + self.cmd=cmd + self.reg1=reg1 + self.reg2 = reg2 + self.label = label + + def __str__(self) -> str: + return f'{self.cmd} {self.reg1} {self.reg2} {self.label}' + class SysCall : def __init__(self) -> None: @@ -149,20 +168,20 @@ def __init__(self, registry, memory_dir) -> None: ############################ Cmp ################################################## class SEQ(CmpNotJump): #comparacion igualdad - def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'seq' ,r_dest, r_src_1, r_src_2) class SGE(CmpNotJump): - def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sge' ,r_dest, r_src_1, r_src_2) class SLT (CmpNotJump): - def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'slt' ,r_dest, r_src_1, r_src_2) class SLE(CmpNotJump): - def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: + def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) @@ -177,6 +196,17 @@ class JR(JumpInconditional): def __init__(self,dest) -> None: super().__init__('jr',dest) +class Jump(JumpInconditional): + def __init__(self,dest) -> None: + super().__init__('j',dest) +################################# JUMPConditional ####################################### + +class BEQ (JumpConditional): + def __init__(self ,register1, register2, label) -> None: + super().__init__( 'beq' ,register1, register2,label) + + + ################################# Operator ############################################## @@ -187,6 +217,13 @@ def __init__(self,dest,op1,op2) -> None: class Add(Operation): def __init__(self,dest,op1,op2) -> None: - super().__init__('addi',dest,op1,op2) + super().__init__('add',dest,op1,op2) + +class MUL (Operation): + def __init__(self,dest,op1,op2) -> None: + super().__init__('mult',dest,op1,op2) +class SUB (Operation): + def __init__(self,dest,op1,op2) -> None: + super().__init__('sub',dest,op1,op2) diff --git a/src/test.s b/src/test.s index 49d717c0b..c5b9bec4a 100644 --- a/src/test.s +++ b/src/test.s @@ -1,57 +1,15 @@ .data -Main_name: .asciiz "Main" - -string_0: .asciiz "Hello, World." +bool: .word 1 .text -.globl main main: -#Parametro Return $ra 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 -li $a0, 1 -li $v0, 9 -syscall -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -la $t0, Main_name -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data #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 +li $v0 , 1 +li $t0 ,-1 +lw $t2 , bool +addi $t1 , $t2 ,-1 +mul $a0 , $t1 ,-1 # $t0 * $t1 = Hi and Lo registers -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 +syscall -IO_out_string: -li $v0, 4 -lw $a0, 0($sp) +li $v0 ,10 syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 -jr $ra From 1bb2bd9250acd71f44c1f205b85dc573cb623fec Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 16:16:58 -0500 Subject: [PATCH 39/91] refactor mpis --- .../v0_type_data_code/type_data_code_ast.py | 4 -- .../codegen/v1_mips_generate/mipsgenerate.py | 16 +++-- .../v1_mips_generate/mipsgenerate_ast.py | 70 +++++++++++++++++-- src/test.mips | 1 + 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index b94a0f2ad..1e7494fc1 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -265,10 +265,6 @@ class Load(Expression): class ALLOCATE(Expression): pass - -class NegAssing(Expression): - pass - class IfGoTo(Expression): pass diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 6ffe52981..7c3a094ae 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -156,14 +156,10 @@ def visit(self, node: AST.Arg): ASTR.Comment(f'Mete para la pila {node.x}'), ] - @visitor.when(AST.VCall) - def visit(self, node: AST.VCall): - memory_dest = node.x - _type = node.y - func = self.cil_type[_type].methods[node.z] - + def call(self, func, memory_dest): self.func_list.append(func) self.stack = self.stack[0: len(self.stack) - self.local_push] + self.local_push = 0 stack_plus = self.stack_index(memory_dest) return [ @@ -173,6 +169,14 @@ def visit(self, node: AST.VCall): ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), ] + @visitor.when(AST.VCall) + def visit(self, node: AST.VCall): + memory_dest = node.x + _type = node.y + func = self.cil_type[_type].methods[node.z] + + return self.call(func, memory_dest) + @visitor.when(AST.Return) def visit(self, node: AST.Return): if node.x == 0: diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 74f2465d6..1ee801e60 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -115,11 +115,6 @@ def __str__(self) -> str: return f'{self.cmd} {self.dest}, {self.op_1}, {self.op_2}' -class Out_String: - def __str__(self) -> str: - return "IO_out_string:\nli $v0, 4\nlw $a0, 0($sp)\nsyscall\nlw $a0, 4($sp)\naddi $sp, $sp, 8\njr $ra" - - ############################ Loads ################################################## class LW(Load): def __init__(self, registry, memory_dir) -> None: @@ -160,3 +155,68 @@ class AddI(Operation): def __init__(self,dest,op1,op2) -> None: super().__init__('addi',dest,op1,op2) + + + +################################# Native Func IO ################################################ +class Out_String: + def __str__(self) -> str: + return """ +IO_out_string: +li $v0, 4 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra""" + +class Out_Int: + def __str__(self) -> str: + return """ +IO_out_int: +li $v0, 1 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra""" + +class In_String: + def __str__(self) -> str: + return """ +""" + +class In_Int: + def __str__(self) -> str: + return """ +""" +################################# Native Func Str ################################################ +class Length: + def __str__(self) -> str: + return """ +""" + +class Concat: + def __str__(self) -> str: + return """ +""" + +class SubStr: + def __str__(self) -> str: + return """ +""" +################################# Native Func Obj ################################################ +class Copy: + def __str__(self) -> str: + return """ +""" + +class Abort: + def __str__(self) -> str: + return """ +""" + +class Type_Name: + def __str__(self) -> str: + return """ +""" \ No newline at end of file diff --git a/src/test.mips b/src/test.mips index 6b34eaf77..1183245e1 100644 --- a/src/test.mips +++ b/src/test.mips @@ -55,6 +55,7 @@ lw $ra, 16($sp) #Lee el $ra mas profundo de la pila para retornar a la addi $sp, $sp, 20 #Limpia la pila jr $ra #Final de la function main + IO_out_string: li $v0, 4 lw $a0, 0($sp) From 972b4912733e6b366ea29f1d06f0defdcc4ad84d Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 16:55:28 -0500 Subject: [PATCH 40/91] miercoles con solo hello word --- .../codegen/v1_mips_generate/mipsgenerate.py | 10 ++++------ .../codegen/v1_mips_generate/mipsgenerate_ast.py | 1 - src/makefile | 5 ++++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 6fc417ded..94e64f830 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -177,6 +177,10 @@ def visit(self, node: AST.VCall): return self.call(func, memory_dest) + @visitor.when(AST.New) + def visit(self, node: AST.New): + return self.call(f'new_ctr_{node.y}', node.x) + @visitor.when(AST.Return) def visit(self, node: AST.Return): if node.x == 0: @@ -233,8 +237,6 @@ def visit(self,node:AST.CmpInt): ASTR.Comment("Pon en la posicion f'{stack_plus_opr_1} el valor de $t3") ] - - @visitor.when(AST.Assign) def visit(self,node:AST.Assign): memory_dest = node.x @@ -319,7 +321,6 @@ def visit(self,node:AST.Rest): ] - @ visitor.when(AST.IfGoTo) def visit(self,node:AST.IfGoTo): memory_cmp = node.x @@ -336,15 +337,12 @@ def visit(self,node:AST.IfGoTo): ASTR.Comment("if $t1==$t0 then jump f'{label_memory}") ] - - @ visitor.when(AST.Label) def visitor(self,node:AST.Label): return [ASTR.Label(node.x), ASTR.Comment("Crea el label f'{node.x} ") ] - @ visitor.when(AST.GoTo) def visitor(self,node:AST.GoTo): label = node.x diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 45cc19948..82564f3af 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -1,6 +1,5 @@ from ast import Compare - class Program: def __init__(self) -> None: self.data = {} diff --git a/src/makefile b/src/makefile index b999fcf4e..432fdccb9 100755 --- a/src/makefile +++ b/src/makefile @@ -23,4 +23,7 @@ parser: python3.8 cool_compiler/parser/__main__.py semantic: - python3.8 cool_compiler/semantic/__main__.py \ No newline at end of file + python3.8 cool_compiler/semantic/__main__.py + +exec: + spim -file test.mips \ No newline at end of file From f4dd7eddbbfe24ff4efbd3a0aed3126edf7293a9 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Wed, 23 Feb 2022 21:41:43 -0500 Subject: [PATCH 41/91] refactor call --- .../v0_type_data_code/type_data_code_ast.py | 5 + .../type_data_code_visitor.py | 39 +-- .../codegen/v1_mips_generate/mipsgenerate.py | 41 +++- .../v1_mips_generate/mipsgenerate_ast.py | 16 +- src/test.cl | 133 +++++++++- src/test.mips | 230 ++++++++++++++++-- 6 files changed, 406 insertions(+), 58 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index 1e7494fc1..fc6d890a7 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -60,6 +60,11 @@ def add_data(self, name, value): 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 diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 1b8901053..7eadc3535 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -37,13 +37,13 @@ def __init__(self, errors) -> None: self.errors = errors self.label_list = {} self.type_dir = { - OBJECT_NAME: 0 + OBJECT_NAME: 1 } def map_type(self, name): try: return self.type_dir[name] except KeyError: - self.type_dir[name] = len(self.type_dir.keys()) + self.type_dir[name] = len(self.type_dir.keys()) + 1 return self.type_dir[name] @visitor.on('node') @@ -62,11 +62,9 @@ def visit(self, node: AST.Program, scope: Scope = None): @visitor.when(AST.CoolClass) def visit(self, node: AST.CoolClass, scope: Scope): self.class_scope = scope.create_child(node.type.name) - self.new_class_scope = scope.create_child(f'new_{node.type.name}') self.currentType = ASTR.Type(node.type.name) self.currentClass = node.type - self.new_type_func = ASTR.Function(f'new_ctr_{node.type.name}') self.program.add_type(self.currentType) @@ -79,19 +77,12 @@ def visit(self, node: AST.CoolClass, scope: Scope): for func in parent.methods: self.currentType.method_push(func.name, f'{parent.name}_{func.name}') - self.program.data[f'{node.type.name}_parents'] = ASTR.Data(f'{node.type.name}_parents', type_list) - self.program.data_list += [f'{node.type.name}_parents'] - - self.new_type_func.force_parma('self', self.new_class_scope) - self.new_type_func.force_local('instance', self.new_class_scope) - tn = self.new_type_func.local_push('type_name', self.new_class_scope) - self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) - self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {node.type.name}')) - self.new_type_func.expr_push(ASTR.Load(tn, f'{node.type.name}_parents')) - self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) - self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) - self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) + self.program.force_data(f'{node.type.name}_parents', type_list + [0]) + self.program.force_data(node.type.name, + [f'{node.type.name}_parents'] + + [self.currentType.methods[key] for key in self.currentType.methods.keys()]) + self.create_new_func_by_type(node, scope) for feat in node.feature_list: self.visit(feat, self.class_scope) @@ -105,6 +96,20 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.program.add_func(self.new_type_func) + def create_new_func_by_type(self, node, scope): + self.new_class_scope = scope.create_child(f'new_{node.type.name}') + self.new_type_func = ASTR.Function(f'new_ctr_{node.type.name}') + + self.new_type_func.force_parma('self', self.new_class_scope) + self.new_type_func.force_local('instance', self.new_class_scope) + tn = self.new_type_func.local_push('type_name', self.new_class_scope) + self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) + self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {node.type.name}')) + self.new_type_func.expr_push(ASTR.Load(tn, node.type.name)) + self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) + self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) + self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) + @visitor.when(AST.AtrDef) def visit(self, node: AST.AtrDef, scope: Scope): if not node.expr in [None, []]: @@ -183,7 +188,7 @@ def visit(self, node: AST.Dispatch, scope: Scope): instance_expr_list.append(ASTR.Arg(arg)) instance_expr_list.append(f'Agrega a la pila el paramentro {i} al Dispatch {node.id}') - instance_expr_list.append(ASTR.Call(super_value, node.id)) + 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) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 94e64f830..427655d40 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -21,6 +21,9 @@ def visit(self, node: AST.Program): 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: if func in self.native_fun: self.new_program.func[func] = self.native_fun[func]() @@ -81,11 +84,11 @@ def visit(self, node: AST.ALLOCATE): result = [ ASTR.Header_Comment(f"Allocate a una class {_type} puntero en sp + {stack_plus}"), - ASTR.Header_Comment(f"atributo type en puntero + 0"), + ASTR.Header_Comment(f"atributo @type en puntero + 0"), ] for i, attr in enumerate(attr_list): - result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {i + 1 * 4}')) + result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {(i + 1) * 4}')) return result + [ ASTR.LI('$a0', _len), @@ -120,7 +123,7 @@ def visit(self, node: AST.SetAttr): if node.y == 'type': attr_plus = 0 else: - attr_name = node.z.split('@') + attr_name = node.y.split('@') _type = attr_name[0] attr = attr_name[1] attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + 4 @@ -157,7 +160,6 @@ def visit(self, node: AST.Arg): ] def call(self, func, memory_dest): - self.func_list.append(func) self.stack = self.stack[0: len(self.stack) - self.local_push] self.local_push = 0 stack_plus = self.stack_index(memory_dest) @@ -174,13 +176,36 @@ def visit(self, node: AST.VCall): memory_dest = node.x _type = node.y func = self.cil_type[_type].methods[node.z] + self.func_list.append(func) return self.call(func, memory_dest) @visitor.when(AST.New) def visit(self, node: AST.New): + func = f'new_ctr_{node.y}' + 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 + instance_stack = self.stack_index(node.y) + _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] + + func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 4 + result = [ + ASTR.LW('$t0', f'{instance_stack}($sp)'), + ASTR.Comment(f"Sacando la instancia de la pila (en {instance_stack - self.local_push * 4}) de una clase que hereda de {_type}"), + ASTR.LW('$t1', '0($t0)'), + ASTR.Comment(f"Leyendo el tipo de la instancia que hereda de {_type}"), + ASTR.LW('$t3', f'{func_address}($t1)'), + ASTR.Comment(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: @@ -204,7 +229,6 @@ def visit(self, node: AST.Load): memory_dest = node.x data_label = node.y - self.new_program.data[data_label] = ASTR.Data(data_label, self.cil_data[data_label].value) stack_plus = self.stack_index(memory_dest) return [ @@ -216,7 +240,6 @@ def visit(self, node: AST.Load): def visit(self, node: AST.Comment): return [ASTR.Comment(node.x)] - @visitor.when(AST.CmpInt) def visit(self,node:AST.CmpInt): memory_dest = node.x @@ -279,7 +302,6 @@ def visit(self,node:AST.Neg): ] - @ visitor.when(AST.Sum) def visit(self,node:AST.Sum): memory_dest=node.x @@ -328,7 +350,6 @@ def visit(self,node:AST.IfGoTo): stack_plus_memory_cmp = self.stack_index(memory_cmp) - return [ASTR.LI("$t0" ,1), ASTR.Comment("Cargar 1 a $t0 pa comparar"), ASTR.LW("$t1", f'{stack_plus_memory_cmp}($sp)' ), @@ -338,13 +359,13 @@ def visit(self,node:AST.IfGoTo): ] @ visitor.when(AST.Label) - def visitor(self,node:AST.Label): + def visit(self,node:AST.Label): return [ASTR.Label(node.x), ASTR.Comment("Crea el label f'{node.x} ") ] @ visitor.when(AST.GoTo) - def visitor(self,node:AST.GoTo): + def visit(self,node:AST.GoTo): label = node.x return [ASTR.Jump (label), ASTR.Comment("Salta para f{label} ") diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 82564f3af..bb45b1726 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -9,9 +9,9 @@ def __str__(self) -> str: result = ".data\n" for key in self.data.keys(): - result += str(self.data[key]) + '\n\n' + result += str(self.data[key]) + '\n' - result += '.text\n.globl main\n' + result += '\n.text\n.globl main\n' result += str(self.func['main']) + '\n' for key in self.func.keys(): @@ -26,9 +26,15 @@ def __init__(self, name, value) -> None: self.value = value def __str__(self) -> str: - if self.value[-1] == '\n': self.value = self.value[0:-1] + '\\n' - if(type(self.value==type("string"))): - return f'{self.name}: .asciiz \"{str(self.value)}\"' + 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)}\"' diff --git a/src/test.cl b/src/test.cl index dbab2d3d9..d02b2c7ae 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,9 +1,134 @@ -class Main inherits IO { - main(): IO { - out_string("Hello, World.\n") - }; +-- example of static and dynamic type differing for a dispatch + +Class Book inherits IO { + title : String; + author : String; + + initBook(title_p : String, author_p : String) : Book { + { + title <- title_p; + author <- author_p; + self; + } + }; + + print() : Book { + { + out_string("title: ").out_string(title).out_string("\n"); + out_string("author: ").out_string(author).out_string("\n"); + self; + } + }; +}; + +Class Article inherits Book { + per_title : String; + + initArticle(title_p : String, author_p : String, + per_title_p : String) : Article { + { + initBook(title_p, author_p); + per_title <- per_title_p; + self; + } + }; + + print() : Book { + { + self@Book.print(); + out_string("periodical: ").out_string(per_title).out_string("\n"); + self; + } + }; +}; + +Class BookList inherits IO { + (* Since abort "returns" type Object, we have to add + an expression of type Bool here to satisfy the typechecker. + This code is unreachable, since abort() halts the program. + *) + isNil() : Bool { { abort(); true; } }; + + cons(hd : Book) : Cons { + (let new_cell : Cons <- new Cons in + new_cell.init(hd,self) + ) + }; + + (* Since abort "returns" type Object, we have to add + an expression of type Book here to satisfy the typechecker. + This code is unreachable, since abort() halts the program. + *) + car() : Book { { abort(); new Book; } }; + + (* Since abort "returns" type Object, we have to add + an expression of type BookList here to satisfy the typechecker. + This code is unreachable, since abort() halts the program. + *) + cdr() : BookList { { abort(); new BookList; } }; + + print_list() : Object { abort() }; }; +Class Cons inherits BookList { + xcar : Book; -- We keep the car and cdr in attributes. + xcdr : BookList; -- Because methods and features must have different names, + -- we use xcar and xcdr for the attributes and reserve + -- car and cdr for the features. + + isNil() : Bool { false }; + + init(hd : Book, tl : BookList) : Cons { + { + xcar <- hd; + xcdr <- tl; + self; + } + }; + car() : Book { xcar }; + + cdr() : BookList { xcdr }; + + print_list() : Object { + { + case xcar.print() of + dummy : Book => out_string("- dynamic type was Book -\n"); + dummy : Article => out_string("- dynamic type was Article -\n"); + esac; + xcdr.print_list(); + } + }; +}; + +Class Nil inherits BookList { + isNil() : Bool { true }; + + print_list() : Object { true }; +}; + + +Class Main { + + books : BookList; + + main() : Object { + (let a_book : Book <- + (new Book).initBook("Compilers, Principles, Techniques, and Tools", + "Aho, Sethi, and Ullman") + in + (let an_article : Article <- + (new Article).initArticle("The Top 100 CD_ROMs", + "Ulanoff", + "PC Magazine") + in + { + books <- (new Nil).cons(a_book).cons(an_article); + books.print_list(); + } + ) -- end let an_article + ) -- end let a_book + }; +}; diff --git a/src/test.mips b/src/test.mips index 1183245e1..a8fcd908a 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,7 +1,28 @@ .data -Main_parents: .asciiz "[0, 1, 2]" - -string_0: .asciiz "Hello, World.\n" +Book_parents: .word 1, 2, 3, 0, +Book: .word 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, +string_0: .asciiz "title: " +string_1: .asciiz "\n" +string_2: .asciiz "author: " +string_3: .asciiz "\n" +Article_parents: .word 1, 2, 3, 4, 0, +Article: .word Article_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_initArticle, +string_4: .asciiz "periodical: " +string_5: .asciiz "\n" +BookList_parents: .word 1, 2, 5, 0, +BookList: .word 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, 2, 5, 6, 0, +Cons: .word Cons_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_init, +string_6: .asciiz "- dynamic type was Book -\n" +Nil_parents: .word 1, 2, 5, 7, 0, +Nil: .word Nil_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, +Main_parents: .word 1, 8, 0, +Main: .word Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, +string_7: .asciiz "Compilers, Principles, Techniques, and Tools" +string_8: .asciiz "Aho, Sethi, and Ullman" +string_9: .asciiz "The Top 100 CD_ROMs" +string_10: .asciiz "Ulanoff" +string_11: .asciiz "PC Magazine" .text .globl main @@ -14,13 +35,14 @@ 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 + 0 #atributo type en puntero + 4 -li $a0, 8 +#atributo books en puntero + 8 +li $a0, 12 li $v0, 9 syscall sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -la $t0, Main_parents +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 @@ -34,32 +56,196 @@ 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 +#Parametro Return $ra en stackpoiner + 76 +#Parametro self en stackpoiner + 72 +addi $sp, $sp, -4 #Push local var a_book stackpointer 68 +addi $sp, $sp, -4 #Push local var instance_to_call_initBook@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_initBook@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var param_1_to_initBook@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var an_article stackpointer 52 +addi $sp, $sp, -4 #Push local var instance_to_call_initArticle@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_initArticle@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_1_to_initArticle@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var param_2_to_initArticle@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_to_call_cons@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_to_call_cons@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_cons@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var result@assing@books@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var instance_to_call_print_list@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 +jal new_ctr_Book #Call a la function new_ctr_Book +sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch initBook +la $t0, string_7 +sw $t0, 60($sp) #Fin del paramentro 0 al Dispatch initBook +la $t0, string_8 +sw $t0, 56($sp) #Fin del paramentro 1 al Dispatch initBook +lw $t0, 64($sp) #Saca de la pila instance_to_call_initBook@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_initBook@0 +lw $t0, 64($sp) #Saca de la pila param_0_to_initBook@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_initBook@0 +lw $t0, 64($sp) #Saca de la pila param_1_to_initBook@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_initBook@0 +lw $t0, 76($sp) #Sacando la instancia de la pila (en 64) de una clase que hereda de Book +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Book +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion initBook +jal $t3 #Call a la function $t3 +sw $s0, 68($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let a_book +jal new_ctr_Article #Call a la function new_ctr_Article +sw $s0, 48($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch initArticle +la $t0, string_9 +sw $t0, 44($sp) #Fin del paramentro 0 al Dispatch initArticle +la $t0, string_10 +sw $t0, 40($sp) #Fin del paramentro 1 al Dispatch initArticle +la $t0, string_11 +sw $t0, 36($sp) #Fin del paramentro 2 al Dispatch initArticle +lw $t0, 48($sp) #Saca de la pila instance_to_call_initArticle@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_initArticle@0 +lw $t0, 48($sp) #Saca de la pila param_0_to_initArticle@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_initArticle@0 +lw $t0, 48($sp) #Saca de la pila param_1_to_initArticle@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_initArticle@0 +lw $t0, 48($sp) #Saca de la pila param_2_to_initArticle@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_2_to_initArticle@0 +lw $t0, 64($sp) #Sacando la instancia de la pila (en 48) de una clase que hereda de Article +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Article +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion initArticle +jal $t3 #Call a la function $t3 +sw $s0, 52($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let an_article #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +jal new_ctr_Nil #Call a la function new_ctr_Nil +sw $s0, 28($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch cons +lw $t0, 68($sp) #pon en $t0 el contenido de la pos f'{stack_plus_dir_value} +sw $t0, 24($sp) #pon en la pos f'{stack_plus_dir_value} el valor de $t0 #Fin del paramentro 0 al Dispatch cons +lw $t0, 28($sp) #Saca de la pila instance_to_call_cons@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_cons@0 +lw $t0, 28($sp) #Saca de la pila param_0_to_cons@0 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 +sw $t0, 0($sp) #Mete para la pila param_0_to_cons@0 +lw $t0, 36($sp) #Sacando la instancia de la pila (en 28) de una clase que hereda de Nil +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Nil +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 #Call a la function $t3 +sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch cons +lw $t0, 52($sp) #pon en $t0 el contenido de la pos f'{stack_plus_dir_value} +sw $t0, 16($sp) #pon en la pos f'{stack_plus_dir_value} el valor de $t0 #Fin del paramentro 0 al Dispatch cons +lw $t0, 20($sp) #Saca de la pila instance_to_call_cons@1 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 $t0, 0($sp) #Mete para la pila instance_to_call_cons@1 +lw $t0, 20($sp) #Saca de la pila param_0_to_cons@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cons@1 +lw $t0, 28($sp) #Sacando la instancia de la pila (en 20) de una clase que hereda de Cons +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Cons +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons +jal $t3 #Call a la function $t3 +sw $s0, 12($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada +lw $t0, 72($sp) #Buscando la instancia en la pila self +lw $t1, 12($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 8($t0) #Seteando el valor en la direccion de la memoria del objeto +lw $t0, 72($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad books +sw $t1, 32($sp) #Salvando el valor de la propiedad books en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block +lw $t0, 72($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad books +sw $t1, 8($sp) #Salvando el valor de la propiedad books en la pila en el valor local instance_to_call_print_list@0 #Fin de la exprecion previa al Dispatch print_list +lw $t0, 8($sp) #Saca de la pila instance_to_call_print_list@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_print_list@0 +lw $t0, 12($sp) #Sacando la instancia de la pila (en 8) de una clase que hereda de BookList +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de BookList +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion print_list +jal $t3 #Call a la function $t3 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, 76($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 80 #Limpia la pila +jr $ra #Final de la function main + +new_ctr_Book: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_Book +#Allocate a una class Book puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +#atributo title en puntero + 8 +#atributo author en puntero + 12 +li $a0, 16 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Book +la $t0, Book +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 +jr $ra +new_ctr_Article: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_Article +#Allocate a una class Article puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +#atributo title en puntero + 8 +#atributo author en puntero + 12 +#atributo per_title en puntero + 16 +li $a0, 20 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Article +la $t0, Article +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 -IO_out_string: -li $v0, 4 -lw $a0, 0($sp) +new_ctr_Nil: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_Nil +#Allocate a una class Nil puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +li $a0, 8 +li $v0, 9 syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Nil +la $t0, Nil +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 + From 1efe275b6ea8757577c1199eb0b669f1f16081c2 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 09:14:01 -0500 Subject: [PATCH 42/91] add report --- doc/report.md | 103 ++++++++++++++++++++++++++ doc/team.yml | 15 ++-- src/cool_compiler/lexer/cool_lexer.py | 1 - 3 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 doc/report.md diff --git a/doc/report.md b/doc/report.md new file mode 100644 index 000000000..5b6bb73f8 --- /dev/null +++ b/doc/report.md @@ -0,0 +1,103 @@ +# 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 direccilón en esta ocación terminado en `".mips"`. El programa se puede ejecutar +con el commando: + + 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 7 módulos más: + +### 1 - Módulo Cmp + +Módulo aportado por los profesores de la asigantura, cuyas impelmentaciones 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 decoredores necesarios para +implementar el patrón **visitor**. A dichas implementaciones a lo largo del desarrollo se le +realizarón 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 funcion a la cual decora, una vez + dicha funcion concluye sus valores de retorno son utilizados para instanciar la clase en + cuestion. Además pasa del nodo de entrada hacia el nuevo nodo resultante la informacion + sobre a que linea y columna pertenecen dichos nodos en el codigo original + +### 2 - Módulo Lexer + +Módulo que comienza con el analisis 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 sintácticamente significativas y según +este significado se les asigan un tipo (literal, keyword, type, identificador, number, string, etc). +El desarrollo de este módulo se apoyo en la libreria **sly**; expecificamente la clase **Lexer**, la cual +brinda la facilidad de definir un automata que reconozca las subcadenas significativas para una +sintaxis dada. Heredando de la clase **Lexer** y definiendo las propiedades _literals_ y _tokens_ se +puede expersar la lista de expersiones regulares que el automata 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 typos de +token definidos en la lista se le deben asignar a toda ocurrencia literal de dicho tipo, obviando si los +caracteres se encuentran en mayuscula o no. En caso en que el comportamietot por defecto no se ajuste +a las necesidades del lenguaje, **sly** permite que se redefina la expresion regular asignada a los typos +de token definidos (por ejemplo en el caso de cool los token ID y STRING). La sintaxis para refefinir +la expresion regular, es definiendole 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 analisis del automata. Para explotar esta caracteristica de la libreria +basta con definir un metodo 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 analisis 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 automata finito determinista para reconocer todo el lenguaje. Para completar el reconocimiento +de estos fragmentos, apoyados en **sly**, se impelmentaro automatas con manipulación de memoria y asi poder contar +la cantidad de ocurrencias de los distintos delimitadores diff --git a/doc/team.yml b/doc/team.yml index c16162532..3a3665511 100755 --- 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/src/cool_compiler/lexer/cool_lexer.py b/src/cool_compiler/lexer/cool_lexer.py index 034d36093..ca5aeccb7 100755 --- a/src/cool_compiler/lexer/cool_lexer.py +++ b/src/cool_compiler/lexer/cool_lexer.py @@ -1,5 +1,4 @@ from sly import Lexer -from sly.lex import LexError from .comment_lexer import CoolComment from .string_lexer import CoolString import re From 14b6210f6cb7d1ce1478a2cf7a95f05c89413b85 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 11:06:12 -0500 Subject: [PATCH 43/91] creado test de mips --- src/cool_compiler/__main__.py | 2 +- .../codegen/mips_code/dynamic_call_func.mips | 60 ++++ .../codegen/mips_code/hello_word.mips | 77 +++++ .../type_data_code_visitor.py | 48 +-- .../v1_create_type/create_type_visitor.py | 1 + src/makefile | 2 +- src/test.cl | 137 +-------- src/test.mips | 287 +++--------------- 8 files changed, 221 insertions(+), 393 deletions(-) create mode 100644 src/cool_compiler/codegen/mips_code/dynamic_call_func.mips create mode 100644 src/cool_compiler/codegen/mips_code/hello_word.mips diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index f4c7063bb..f28534900 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +# path = "test.cl" with open(path, 'r') as _file: text = _file.read() 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/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 7eadc3535..e37c73b30 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -13,7 +13,7 @@ def parent_list(node: AST.CoolClass): parent_list = [] - parent = node.type + parent = node while True: if parent is None: break parent_list.append(parent) @@ -54,22 +54,26 @@ def visit(node, scope: Scope): def visit(self, node: AST.Program, scope: Scope = None): self.program = ASTR.Program() scope = Scope() + + _dictt = CoolTypeBuildInManager().dictt + for key in _dictt.keys(): + self.create_type(_dictt[key], scope) + self.new_type_func.expr_push(ASTR.Return('instance')) + self.program.add_func(self.new_type_func) + for cls in node.class_list: self.visit(cls, scope) 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.currentType = ASTR.Type(node.type.name) - self.currentClass = node.type + 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 parent_list(node): + for parent in parent_list(_type): type_list.append(self.map_type(parent.name)) self.currentType.attr_push('type', self.currentType.name) for attr in parent.attributes: @@ -77,12 +81,18 @@ def visit(self, node: AST.CoolClass, scope: Scope): for func in parent.methods: self.currentType.method_push(func.name, f'{parent.name}_{func.name}') - self.program.force_data(f'{node.type.name}_parents', type_list + [0]) - self.program.force_data(node.type.name, - [f'{node.type.name}_parents'] + + self.program.force_data(f'{_type.name}_parents', type_list + [0]) + self.program.force_data(_type.name, + [f'{_type.name}_parents'] + [self.currentType.methods[key] for key in self.currentType.methods.keys()]) - - self.create_new_func_by_type(node, scope) + + self.create_new_func_by_type(_type, scope) + + @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) @@ -96,16 +106,16 @@ def visit(self, node: AST.CoolClass, scope: Scope): self.program.add_func(self.new_type_func) - def create_new_func_by_type(self, node, scope): - self.new_class_scope = scope.create_child(f'new_{node.type.name}') - self.new_type_func = ASTR.Function(f'new_ctr_{node.type.name}') + 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) self.new_type_func.force_local('instance', self.new_class_scope) tn = self.new_type_func.local_push('type_name', self.new_class_scope) - self.new_type_func.expr_push(ASTR.ALLOCATE('instance', node.type.name)) - self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {node.type.name}')) - self.new_type_func.expr_push(ASTR.Load(tn, node.type.name)) + self.new_type_func.expr_push(ASTR.ALLOCATE('instance', _type.name)) + self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {_type.name}')) + self.new_type_func.expr_push(ASTR.Load(tn, _type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) 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 index f4b68d77b..5492462ef 100644 --- a/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py +++ b/src/cool_compiler/semantic/v1_create_type/create_type_visitor.py @@ -37,6 +37,7 @@ def visit(self, node : AST.Program) : else: self.global_types[name] = Type(name) class_list = self.visit_all(node.class_list) + return class_list, @visitor.when(AST.CoolClass) diff --git a/src/makefile b/src/makefile index 432fdccb9..7ad327735 100755 --- a/src/makefile +++ b/src/makefile @@ -1,7 +1,7 @@ .PHONY: clean main: - python -m cool_compiler test.cl + rm -rf test.mips && python -m cool_compiler test.cl clean: rm -rf build/* diff --git a/src/test.cl b/src/test.cl index d02b2c7ae..0c818f908 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,134 +1,5 @@ --- example of static and dynamic type differing for a dispatch - -Class Book inherits IO { - title : String; - author : String; - - initBook(title_p : String, author_p : String) : Book { - { - title <- title_p; - author <- author_p; - self; - } - }; - - print() : Book { - { - out_string("title: ").out_string(title).out_string("\n"); - out_string("author: ").out_string(author).out_string("\n"); - self; - } - }; +class Main inherits IO { + main(): IO { + out_string("Hello, World.\n") + }; }; - -Class Article inherits Book { - per_title : String; - - initArticle(title_p : String, author_p : String, - per_title_p : String) : Article { - { - initBook(title_p, author_p); - per_title <- per_title_p; - self; - } - }; - - print() : Book { - { - self@Book.print(); - out_string("periodical: ").out_string(per_title).out_string("\n"); - self; - } - }; -}; - -Class BookList inherits IO { - (* Since abort "returns" type Object, we have to add - an expression of type Bool here to satisfy the typechecker. - This code is unreachable, since abort() halts the program. - *) - isNil() : Bool { { abort(); true; } }; - - cons(hd : Book) : Cons { - (let new_cell : Cons <- new Cons in - new_cell.init(hd,self) - ) - }; - - (* Since abort "returns" type Object, we have to add - an expression of type Book here to satisfy the typechecker. - This code is unreachable, since abort() halts the program. - *) - car() : Book { { abort(); new Book; } }; - - (* Since abort "returns" type Object, we have to add - an expression of type BookList here to satisfy the typechecker. - This code is unreachable, since abort() halts the program. - *) - cdr() : BookList { { abort(); new BookList; } }; - - print_list() : Object { abort() }; -}; - -Class Cons inherits BookList { - xcar : Book; -- We keep the car and cdr in attributes. - xcdr : BookList; -- Because methods and features must have different names, - -- we use xcar and xcdr for the attributes and reserve - -- car and cdr for the features. - - isNil() : Bool { false }; - - init(hd : Book, tl : BookList) : Cons { - { - xcar <- hd; - xcdr <- tl; - self; - } - }; - - car() : Book { xcar }; - - cdr() : BookList { xcdr }; - - print_list() : Object { - { - case xcar.print() of - dummy : Book => out_string("- dynamic type was Book -\n"); - dummy : Article => out_string("- dynamic type was Article -\n"); - esac; - xcdr.print_list(); - } - }; -}; - -Class Nil inherits BookList { - isNil() : Bool { true }; - - print_list() : Object { true }; -}; - - -Class Main { - - books : BookList; - - main() : Object { - (let a_book : Book <- - (new Book).initBook("Compilers, Principles, Techniques, and Tools", - "Aho, Sethi, and Ullman") - in - (let an_article : Article <- - (new Article).initArticle("The Top 100 CD_ROMs", - "Ulanoff", - "PC Magazine") - in - { - books <- (new Nil).cons(a_book).cons(an_article); - books.print_list(); - } - ) -- end let an_article - ) -- end let a_book - }; -}; - - diff --git a/src/test.mips b/src/test.mips index a8fcd908a..bacc5c687 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,251 +1,60 @@ .data -Book_parents: .word 1, 2, 3, 0, -Book: .word 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, -string_0: .asciiz "title: " -string_1: .asciiz "\n" -string_2: .asciiz "author: " -string_3: .asciiz "\n" -Article_parents: .word 1, 2, 3, 4, 0, -Article: .word Article_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_initArticle, -string_4: .asciiz "periodical: " -string_5: .asciiz "\n" -BookList_parents: .word 1, 2, 5, 0, -BookList: .word 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, 2, 5, 6, 0, -Cons: .word Cons_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_init, -string_6: .asciiz "- dynamic type was Book -\n" -Nil_parents: .word 1, 2, 5, 7, 0, -Nil: .word Nil_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, -Main_parents: .word 1, 8, 0, -Main: .word Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, -string_7: .asciiz "Compilers, Principles, Techniques, and Tools" -string_8: .asciiz "Aho, Sethi, and Ullman" -string_9: .asciiz "The Top 100 CD_ROMs" -string_10: .asciiz "Ulanoff" -string_11: .asciiz "PC Magazine" +Main_parents: .word 1 2 3 +Main: .word Main_parents f1 +endLine: .asciiz "\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 -#atributo books en puntero + 8 -li $a0, 12 + +li $a0, 4 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 +sw $v0, 0($sp) -Main_main: -#Parametro Return $ra en stackpoiner + 76 -#Parametro self en stackpoiner + 72 -addi $sp, $sp, -4 #Push local var a_book stackpointer 68 -addi $sp, $sp, -4 #Push local var instance_to_call_initBook@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var param_0_to_initBook@0 stackpointer 60 -addi $sp, $sp, -4 #Push local var param_1_to_initBook@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var an_article stackpointer 52 -addi $sp, $sp, -4 #Push local var instance_to_call_initArticle@0 stackpointer 48 -addi $sp, $sp, -4 #Push local var param_0_to_initArticle@0 stackpointer 44 -addi $sp, $sp, -4 #Push local var param_1_to_initArticle@0 stackpointer 40 -addi $sp, $sp, -4 #Push local var param_2_to_initArticle@0 stackpointer 36 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var instance_to_call_cons@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var param_0_to_cons@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var instance_to_call_cons@1 stackpointer 20 -addi $sp, $sp, -4 #Push local var param_0_to_cons@1 stackpointer 16 -addi $sp, $sp, -4 #Push local var result@assing@books@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var instance_to_call_print_list@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 -jal new_ctr_Book #Call a la function new_ctr_Book -sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch initBook -la $t0, string_7 -sw $t0, 60($sp) #Fin del paramentro 0 al Dispatch initBook -la $t0, string_8 -sw $t0, 56($sp) #Fin del paramentro 1 al Dispatch initBook -lw $t0, 64($sp) #Saca de la pila instance_to_call_initBook@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_initBook@0 -lw $t0, 64($sp) #Saca de la pila param_0_to_initBook@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_initBook@0 -lw $t0, 64($sp) #Saca de la pila param_1_to_initBook@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_initBook@0 -lw $t0, 76($sp) #Sacando la instancia de la pila (en 64) de una clase que hereda de Book -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Book -lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion initBook -jal $t3 #Call a la function $t3 -sw $s0, 68($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let a_book -jal new_ctr_Article #Call a la function new_ctr_Article -sw $s0, 48($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch initArticle -la $t0, string_9 -sw $t0, 44($sp) #Fin del paramentro 0 al Dispatch initArticle -la $t0, string_10 -sw $t0, 40($sp) #Fin del paramentro 1 al Dispatch initArticle -la $t0, string_11 -sw $t0, 36($sp) #Fin del paramentro 2 al Dispatch initArticle -lw $t0, 48($sp) #Saca de la pila instance_to_call_initArticle@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_initArticle@0 -lw $t0, 48($sp) #Saca de la pila param_0_to_initArticle@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_initArticle@0 -lw $t0, 48($sp) #Saca de la pila param_1_to_initArticle@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_initArticle@0 -lw $t0, 48($sp) #Saca de la pila param_2_to_initArticle@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_2_to_initArticle@0 -lw $t0, 64($sp) #Sacando la instancia de la pila (en 48) de una clase que hereda de Article -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Article -lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion initArticle -jal $t3 #Call a la function $t3 -sw $s0, 52($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let an_article #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -jal new_ctr_Nil #Call a la function new_ctr_Nil -sw $s0, 28($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch cons -lw $t0, 68($sp) #pon en $t0 el contenido de la pos f'{stack_plus_dir_value} -sw $t0, 24($sp) #pon en la pos f'{stack_plus_dir_value} el valor de $t0 #Fin del paramentro 0 al Dispatch cons -lw $t0, 28($sp) #Saca de la pila instance_to_call_cons@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_cons@0 -lw $t0, 28($sp) #Saca de la pila param_0_to_cons@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cons@0 -lw $t0, 36($sp) #Sacando la instancia de la pila (en 28) de una clase que hereda de Nil -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Nil -lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons -jal $t3 #Call a la function $t3 -sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch cons -lw $t0, 52($sp) #pon en $t0 el contenido de la pos f'{stack_plus_dir_value} -sw $t0, 16($sp) #pon en la pos f'{stack_plus_dir_value} el valor de $t0 #Fin del paramentro 0 al Dispatch cons -lw $t0, 20($sp) #Saca de la pila instance_to_call_cons@1 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_cons@1 -lw $t0, 20($sp) #Saca de la pila param_0_to_cons@1 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cons@1 -lw $t0, 28($sp) #Sacando la instancia de la pila (en 20) de una clase que hereda de Cons -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Cons -lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion cons -jal $t3 #Call a la function $t3 -sw $s0, 12($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada -lw $t0, 72($sp) #Buscando la instancia en la pila self -lw $t1, 12($sp) #Buscando el valor que se va a guardar en la propiedad -sw $t1, 8($t0) #Seteando el valor en la direccion de la memoria del objeto -lw $t0, 72($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad books -sw $t1, 32($sp) #Salvando el valor de la propiedad books en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block -lw $t0, 72($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad books -sw $t1, 8($sp) #Salvando el valor de la propiedad books en la pila en el valor local instance_to_call_print_list@0 #Fin de la exprecion previa al Dispatch print_list -lw $t0, 8($sp) #Saca de la pila instance_to_call_print_list@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_print_list@0 -lw $t0, 12($sp) #Sacando la instancia de la pila (en 8) de una clase que hereda de BookList -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de BookList -lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion print_list -jal $t3 #Call a la function $t3 -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, 76($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 80 #Limpia la pila -jr $ra #Final de la function main +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 -new_ctr_Book: -#Parametro Return $ra en stackpoiner + 16 -#Parametro self en stackpoiner + 12 -addi $sp, $sp, -4 #Push local var instance stackpointer 8 -addi $sp, $sp, -4 #Push local var type_name@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_Book -#Allocate a una class Book puntero en sp + 8 -#atributo @type en puntero + 0 -#atributo type en puntero + 4 -#atributo title en puntero + 8 -#atributo author en puntero + 12 -li $a0, 16 -li $v0, 9 -syscall -sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Book -la $t0, Book -sw $t0, 4($sp) #Cargando el nombre del tipo desde el data -lw $t0, 8($sp) #Buscando la instancia en la pila instance -lw $t1, 4($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 $s0, 8($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 +li $v0, 1 # system call #4 - print string +la $a0, Main # Imprime direccion de Main +syscall # execute -new_ctr_Article: -#Parametro Return $ra en stackpoiner + 16 -#Parametro self en stackpoiner + 12 -addi $sp, $sp, -4 #Push local var instance stackpointer 8 -addi $sp, $sp, -4 #Push local var type_name@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_Article -#Allocate a una class Article puntero en sp + 8 -#atributo @type en puntero + 0 -#atributo type en puntero + 4 -#atributo title en puntero + 8 -#atributo author en puntero + 12 -#atributo per_title en puntero + 16 -li $a0, 20 -li $v0, 9 -syscall -sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Article -la $t0, Article -sw $t0, 4($sp) #Cargando el nombre del tipo desde el data -lw $t0, 8($sp) #Buscando la instancia en la pila instance -lw $t1, 4($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 $s0, 8($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 +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 -new_ctr_Nil: -#Parametro Return $ra en stackpoiner + 16 -#Parametro self en stackpoiner + 12 -addi $sp, $sp, -4 #Push local var instance stackpointer 8 -addi $sp, $sp, -4 #Push local var type_name@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_Nil -#Allocate a una class Nil puntero en sp + 8 -#atributo @type en puntero + 0 -#atributo type en puntero + 4 -li $a0, 8 -li $v0, 9 -syscall -sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Nil -la $t0, Nil -sw $t0, 4($sp) #Cargando el nombre del tipo desde el data -lw $t0, 8($sp) #Buscando la instancia en la pila instance -lw $t1, 4($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 $s0, 8($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 +f1: +li $v0, 1 # system call #4 - print string +la $a0, 10 +syscall # execute +jr $ra \ No newline at end of file From 26b1fd2f01884cbf28b6095f96eea1d996644a0b Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 11:08:48 -0500 Subject: [PATCH 44/91] mipstest --- src/cool_compiler/__main__.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 30 +++++- .../v1_mips_generate/mipsgenerate_ast.py | 99 ++++++++++++++++++- src/test.cl | 31 +++++- src/test.mips | 95 +++++++----------- src/test.s | 1 + 6 files changed, 187 insertions(+), 71 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index f4c7063bb..3a1b97a12 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -31,7 +31,7 @@ ast = parser.parse(iter(tokens)) if errors.any(): sys.exit(1) - visitorList = [ CreateType, SemanticChecking, CILGenerate, MipsGenerate ] + visitorList = [ CreateType, SemanticChecking, CILGenerate,MipsGenerate ] for visitorClass in visitorList: ast = visitorClass(errors).visit(ast) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 6fc417ded..d5ce04f49 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -6,7 +6,10 @@ class MipsGenerate: def __init__(self, errors) -> None: self.func_list = ['new_ctr_Main'] self.native_fun = { - "IO_out_string": ASTR.Out_String + "IO_out_string": ASTR.Out_String, + "IO_in_int":ASTR.In_Int, + "IO_in_string":ASTR.In_String, + "IO_out_int":ASTR.Out_Int } @visitor.on('node') @@ -272,7 +275,7 @@ def visit(self,node:AST.Neg): ASTR.MUL ('$t0','$t1',-1), ASTR.Comment("$t0 = $t1 * (-1)"), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment("poner en la posicion f'{stack_plus_memory_dest} el contenido de $t0") + ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el contenido de $t0") ] @@ -339,14 +342,33 @@ def visit(self,node:AST.IfGoTo): @ visitor.when(AST.Label) - def visitor(self,node:AST.Label): + def visit(self,node:AST.Label): return [ASTR.Label(node.x), ASTR.Comment("Crea el label f'{node.x} ") ] + @visitor.when(AST.CheckType) + def visit(self,node:AST.CheckType): + memory_dir = node.x + memory_instance = node.y + type_name = node.z + + stack_plus_memory_dir = self.stack_index(memory_dir) + stack_plus_memory_instance = self.stack_index(memory_instance) + + return [ + ASTR.LW('$s2',f'{stack_plus_memory_instance}($sp)'), + ASTR.LW('$a1', type_name), + ASTR.JAL('Contain'), + ASTR.SW ('$S0',f'{stack_plus_memory_dir}($sp)') + + + + ] + @ visitor.when(AST.GoTo) - def visitor(self,node:AST.GoTo): + def visit(self,node:AST.GoTo): label = node.x return [ASTR.Jump (label), ASTR.Comment("Salta para f{label} ") diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 45cc19948..9069d14d8 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -48,6 +48,36 @@ def __str__(self) -> str: result += str(cmd) + '\n' return result +class Compare_String: + def __init__(self) -> None: + pass + + def __str__(self) -> str: + return """ +compare_String: # compare str1 ($a0), str2 ($a1) salida en $s0 +LOOP: + lb $t0, ($a0) + lb $t1, ($a1) + add $a0, $a0, 1 + add $a1, $a1, 1 + beqz $t0, LOOP_END + beqz $t1, LOOP_END + beq $t0, $t1, LOOP + li $s0 , 0 + jr $ra + +EQUAL: + li $s0, 1 + j END + +LOOP_END: + beq $t0, $t1, EQUAL + li $s0 , 0 + jr $ra +END: + jr $ra""" + + class Comment: def __init__(self, msg) -> None: self.msg = msg @@ -214,7 +244,7 @@ def __init__(self,dest,op1,op2) -> None: class MUL (Operation): def __init__(self,dest,op1,op2) -> None: - super().__init__('mult',dest,op1,op2) + super().__init__('mul',dest,op1,op2) class SUB (Operation): def __init__(self,dest,op1,op2) -> None: @@ -244,44 +274,105 @@ def __str__(self) -> str: addi $sp, $sp, 8 jr $ra""" +class Out_Float: + def __str__(self) -> str: + return """ +IO_out_Float: +li $v0, 2 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra""" + class In_String: def __str__(self) -> str: return """ +IO_in_string: +li $v0,8 +li $a1 , 10000 +syscall +move $s0 , $a0 + + """ class In_Int: def __str__(self) -> str: return """ +IO_in_int: +li $v0,5 +syscall +move $s0 , $a0 """ + +class In_Float: + def __str__(self) -> str: + return """ +In_Float: +li $v0,6 +syscall +move $s0 , $a0 +""" + +class Contain: + def __str__(self) -> str: + return """ +Contain: + +loop: + lw $s0 , ($s2) + beq $s0, $a1, Equal # if $s0 ==a$t1 then target + beq $s0 , $zero, END + add $s2,$s2,4 + j loop + + +Equal: +li $s0 , 1 +jr $ra + +END: +li $s0 , 0 +jr $ra +""" + ################################# Native Func Str ################################################ class Length: def __str__(self) -> str: - return """ + return """ yaaaa """ class Concat: def __str__(self) -> str: - return """ + return """ yaaaa """ class SubStr: def __str__(self) -> str: - return """ + return """ yaaaaa """ ################################# Native Func Obj ################################################ class Copy: def __str__(self) -> str: return """ + El método de copia, sabemos que el resultado de la copia es el +igual que el tipo del autoparámetro + + """ class Abort: def __str__(self) -> str: return """ + El método abortar detiene la ejecución del programa con un mensaje de error. """ class Type_Name: def __str__(self) -> str: return """ + El nombre del tipo de método devuelve un +cadena con el nombre de la clase del objeto """ diff --git a/src/test.cl b/src/test.cl index dbab2d3d9..94c781d90 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,9 +1,30 @@ class Main inherits IO { - main(): IO { - out_string("Hello, World.\n") - }; -}; - + -- the class has features. Only methods in this case. + main(): Object { + { + out_string("Enter n to find nth fibonacci number!\n"); + out_int(fib(in_int())); + out_string("\n"); + } + }; + fib(i : Int) : Int { -- list of formals. And the return type of the method. + let a : Int <- 1, + b : Int <- 0, + c : Int <- 0 + in + { + while (not (i = 0)) loop -- expressions are nested. + { + c <- a + b; + i <- i - 1; + b <- a; + a <- c; + } + pool; + c; + } + }; +}; diff --git a/src/test.mips b/src/test.mips index 1183245e1..1d7789d75 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,65 +1,46 @@ -.data -Main_parents: .asciiz "[0, 1, 2]" - -string_0: .asciiz "Hello, World.\n" +.data +arra: .word 4 5 6 7 0 .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_parents -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 +li $a1 , 5 #guarde 5 numero a buscar +la $s2 , arra #dir del array +move $a0, $a1 # $a0 = $a1 +li $v0, 1 # syscall print int +syscall # execute + +jal Contain # jump to Contain and save position to $ra -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 +move $a0, $a1 # $a0 = $a1 +li $v0, 1 # syscall print int +syscall # execute +move $a0 , $s0 +li $v0, 1 # syscall print str +syscall + # execute +move $a0, $a1 # $a0 = $a1 +li $v0, 1 # syscall print int +syscall # execute -IO_out_string: -li $v0, 4 -lw $a0, 0($sp) +li $v0,10 syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 + + +Contain: +#s2 array +loop: + lw $s0 , ($s2) + beq $s0, $a1, Equal # if $s0 ==a$t1 then target + beq $s0 , $zero, END + add $s2,$s2,4 + j loop + + +Equal: +li $s0 , 1 jr $ra + +END: +li $s0 , 0 +jr $ra \ No newline at end of file diff --git a/src/test.s b/src/test.s index c5b9bec4a..70b92d2cc 100644 --- a/src/test.s +++ b/src/test.s @@ -1,6 +1,7 @@ .data bool: .word 1 + .text main: li $v0 , 1 From 9638a65637888d1830d0d7288f39fc018d3a11eb Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 11:22:26 -0500 Subject: [PATCH 45/91] mipsss --- .../codegen/v1_mips_generate/mipsgenerate.py | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 255327254..1c33b543c 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -254,13 +254,13 @@ def visit(self,node:AST.CmpInt): stack_plus_dest = self.stack_index(memory_dest) return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , - ASTR.Comment("carga en $t1 lo que hay en f'{stack_plus_opr_1} "), + ASTR.Comment(f"carga en $t1 lo que hay en {stack_plus_opr_1} "), ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment("carga en $t2 lo que hay en f'{stack_plus_opr_2} "), + ASTR.Comment(f"carga en $t2 lo que hay en {stack_plus_opr_2} "), ASTR.SEQ ('$t3','$t2','$t1'), ASTR.Comment("$t3 = $t2 == $ t1" ), - ASTR.SW ('$t3',f'{stack_plus_opr_1}($sp)'), - ASTR.Comment("Pon en la posicion f'{stack_plus_opr_1} el valor de $t3") + ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), + ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") ] @visitor.when(AST.Assign) @@ -272,17 +272,17 @@ def visit(self,node:AST.Assign): if(type(dir_value)==type(int()) or type(dir_value)==type(float())): return [ ASTR.LI('$t0' , str(dir_value)), - ASTR.Comment("pon en $t0 f'{dir_value} "), + ASTR.Comment(f"pon en $t0 {dir_value} "), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment("pon en la posicion f'{dir_value} el valor $t0 ") + ASTR.Comment(f"pon en la posicion {dir_value} el valor $t0 ") ] else: stack_plus_dir_value = self.stack_index(dir_value) return [ ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), - ASTR.Comment("pon en $t0 el contenido de la pos f'{stack_plus_dir_value} "), + ASTR.Comment(f"pon en $t0 el contenido de la pos {stack_plus_dir_value} "), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment("pon en la pos f'{stack_plus_dir_value} el valor de $t0") + ASTR.Comment(f"pon en la pos {stack_plus_dir_value} el valor de $t0") ] @visitor.when(AST.Neg) @@ -294,7 +294,7 @@ def visit(self,node:AST.Neg): return [ ASTR.LW ('$t0',f'{stack_plus_opr_1}($sp)'), - ASTR.Comment("Carga la pos f'{stack_plus_opr_1} en $t0"), + ASTR.Comment(f"Carga la pos {stack_plus_opr_1} en $t0"), ASTR.AddI ('$t1','$t0',-1 ), ASTR.Comment("$t1 = $t0 + (-1)"), ASTR.MUL ('$t0','$t1',-1), @@ -316,13 +316,13 @@ def visit(self,node:AST.Sum): stack_plus_opr_2 = self.stack_index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment("poner en registro $t0 lo que hay en f'{stack_plus_opr_1}"), + ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment("poner en registro $t1 lo que hay en f'{stack_plus_opr_2}"), + ASTR.Comment(f"poner en registro $t1 lo que hay en {stack_plus_opr_2}"), ASTR.Add('$t0' , '$t0','$t1'), ASTR.Comment("en $t0 pon el resultado de la suma"), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment("poner en la posicion f'{stack_plus_memory_dest} el resultado ") + ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el resultado ") ] @ visitor.when(AST.Rest) @@ -336,13 +336,13 @@ def visit(self,node:AST.Rest): stack_plus_opr_2 = self.stack_index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment("poner en registro $t0 lo que hay en f'{stack_plus_opr_1}"), + ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), ASTR.Comment("poner en registro $t1 lo que hay en f'{stack_plus_opr_2}"), ASTR.SUB('$t0' , '$t0','$t1'), ASTR.Comment("poner en registro $t0 la suma "), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment("poner en f'{stack_plus_memory_dest} el resultado de la suma "), + ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la suma "), ] @@ -356,15 +356,15 @@ def visit(self,node:AST.IfGoTo): return [ASTR.LI("$t0" ,1), ASTR.Comment("Cargar 1 a $t0 pa comparar"), ASTR.LW("$t1", f'{stack_plus_memory_cmp}($sp)' ), - ASTR.Comment("Cargar el valor de la pos f'{stack_plus_memory_cmp} a $t1 pa comparar"), + ASTR.Comment(f"Cargar el valor de la pos {stack_plus_memory_cmp} a $t1 pa comparar"), ASTR.BEQ("$t0","$t1", label_memory), - ASTR.Comment("if $t1==$t0 then jump f'{label_memory}") + ASTR.Comment(f"if $t1==$t0 then jump {label_memory}") ] @ visitor.when(AST.Label) def visit(self,node:AST.Label): return [ASTR.Label(node.x), - ASTR.Comment("Crea el label f'{node.x} ") + ASTR.Comment(f"Crea el label {node.x} ") ] @visitor.when(AST.CheckType) @@ -378,9 +378,15 @@ def visit(self,node:AST.CheckType): return [ ASTR.LW('$s2',f'{stack_plus_memory_instance}($sp)'), + ASTR.Comment(f' pon en $s2 el contenido de {stack_plus_memory_instance}($sp)'), ASTR.LW('$a1', type_name), + ASTR.Comment(f"guarda en $a1 {type_name} "), ASTR.JAL('Contain'), - ASTR.SW ('$S0',f'{stack_plus_memory_dir}($sp)') + ASTR.Comment("Salta para Contain"), + ASTR.SW ('$s0',f'{stack_plus_memory_dir}($sp)'), + ASTR.Comment(f"Guarda en la pos {stack_plus_memory_dir}($sp) el contenido de $s0") + + From e9135e7c400056352e28810b57d52bb0453fee7c Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 11:23:57 -0500 Subject: [PATCH 46/91] megre --- .../codegen/v1_mips_generate/mipsgenerate.py | 4 +- src/test.cl | 102 ++++- src/test.mips | 389 ++++++++++++++++-- 3 files changed, 450 insertions(+), 45 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 427655d40..298652a63 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -256,8 +256,8 @@ def visit(self,node:AST.CmpInt): ASTR.Comment("carga en $t2 lo que hay en f'{stack_plus_opr_2} "), ASTR.SEQ ('$t3','$t2','$t1'), ASTR.Comment("$t3 = $t2 == $ t1" ), - ASTR.SW ('$t3',f'{stack_plus_opr_1}($sp)'), - ASTR.Comment("Pon en la posicion f'{stack_plus_opr_1} el valor de $t3") + ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), + ASTR.Comment("Pon en la posicion f's{stack_plus_opr_1} el valor de $t3") ] @visitor.when(AST.Assign) diff --git a/src/test.cl b/src/test.cl index 0c818f908..7f0de869e 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,5 +1,103 @@ +(* + * The IO class is predefined and has 4 methods: + * + * out_string(s : String) : SELF_TYPE + * out_int(i : Int) : SELF_TYPE + * in_string() : String + * in_int() : Int + * + * The out operations print their argument to the terminal. The + * in_string method reads an entire line from the terminal and returns a + * string not containing the new line. The in_int method also reads + * an entire line from the terminal and returns the integer + * corresponding to the first non blank word on the line. If that + * word is not an integer, it returns 0. + * + * + * Because our language is object oriented, we need an object of type + * IO in order to call any of these methods. + * + * There are basically two ways of getting access to IO in a class C. + * + * 1) Define C to Inherit from IO. This way the IO methods become + * methods of C, and they can be called using the abbreviated + * dispatch, i.e. + * + * class C inherits IO is + * ... + * out_string("Hello world\n") + * ... + * end; + * + * 2) If your class C does not directly or indirectly inherit from + * IO, the best way to access IO is through an initialized + * attribute of type IO. + * + * class C inherits Foo is + * io : IO <- new IO; + * ... + * io.out_string("Hello world\n"); + * ... + * end; + * + * Approach 1) is most often used, in particular when you need IO + * functions in the Main class. + * + *) + + +class A { + + -- Let's assume that we don't want A to not inherit from IO. + + io : IO <- new IO; + + out_a() : Object { io.out_string("A: Hello world\n") }; + +}; + + +class B inherits A { + + -- B does not have to an extra attribute, since it inherits io from A. + + out_b() : Object { io.out_string("B: Hello world\n") }; + +}; + + +class C inherits IO { + + -- Now the IO methods are part of C. + + out_c() : Object { out_string("C: Hello world\n") }; + + -- Note that out_string(...) is just a shorthand for self.out_string(...) + +}; + + +class D inherits C { + + -- Inherits IO methods from C. + + out_d() : Object { out_string("D: Hello world\n") }; + +}; + + class Main inherits IO { - main(): IO { - out_string("Hello, World.\n") + + -- Same case as class C. + + main() : Object { + { + (new A).out_a(); + (new B).out_b(); + (new C).out_c(); + (new D).out_d(); + out_string("Done.\n"); + } }; + }; diff --git a/src/test.mips b/src/test.mips index bacc5c687..db9c4a5f6 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,60 +1,367 @@ .data -Main_parents: .word 1 2 3 -Main: .word Main_parents f1 -endLine: .asciiz "\n" +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, +A_parents: .word 1, 7, 0, +A: .word A_parents, Object_abort, Object_copy, Object_type_name, A_out_a, +B_parents: .word 1, 7, 8, 0, +B: .word B_parents, Object_abort, Object_copy, Object_type_name, A_out_a, B_out_b, +C_parents: .word 1, 6, 9, 0, +C: .word 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: .word 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: .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 "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: - -li $a0, 4 +#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, 0($sp) +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 -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 +Main_main: +#Parametro Return $ra en stackpoiner + 48 +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_to_call_out_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_to_call_out_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var step@block@2 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_to_call_out_c@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var step@block@3 stackpointer 16 +addi $sp, $sp, -4 #Push local var instance_to_call_out_d@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 @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 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +jal new_ctr_A #Call a la function new_ctr_A +sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch out_a +lw $t0, 36($sp) #Saca de la pila instance_to_call_out_a@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_a@0 +lw $t0, 40($sp) #Sacando la instancia de la pila (en 36) de una clase que hereda de A +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de A +lw $t3, 16($t1) #Buscando el metodo dinamico para la funcion out_a +jal $t3 #Call a la function $t3 +sw $s0, 40($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block +jal new_ctr_B #Call a la function new_ctr_B +sw $s0, 28($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch out_b +lw $t0, 28($sp) #Saca de la pila instance_to_call_out_b@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_b@0 +lw $t0, 32($sp) #Sacando la instancia de la pila (en 28) de una clase que hereda de B +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de B +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion out_b +jal $t3 #Call a la function $t3 +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +jal new_ctr_C #Call a la function new_ctr_C +sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch out_c +lw $t0, 20($sp) #Saca de la pila instance_to_call_out_c@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_c@0 +lw $t0, 24($sp) #Sacando la instancia de la pila (en 20) de una clase que hereda de C +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de C +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion out_c +jal $t3 #Call a la function $t3 +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 3 de una sequencia Block +jal new_ctr_D #Call a la function new_ctr_D +sw $s0, 12($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch out_d +lw $t0, 12($sp) #Saca de la pila instance_to_call_out_d@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_d@0 +lw $t0, 16($sp) #Sacando la instancia de la pila (en 12) de una clase que hereda de D +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de D +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion out_d +jal $t3 #Call a la function $t3 +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 4 de una sequencia Block +la $t0, string_4 +sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 44($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, 48($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 52 #Limpia la pila +jr $ra #Final de la function main -li $v0, 1 # system call #4 - print string -la $a0, Main # Imprime direccion de Main -syscall # execute +new_ctr_A: +#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 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 +#Allocate a una class A puntero en sp + 12 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +#atributo io en puntero + 8 +li $a0, 12 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo A +la $t0, A +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 +jal new_ctr_IO #Call a la function new_ctr_IO +sw $s0, 4($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +lw $t0, 12($sp) #Buscando la instancia en la pila instance +lw $t1, 4($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 8($t0) #Seteando el valor en la direccion de la memoria del objeto #Assignando el resultado de la expression al atributo io de la clase A +lw $s0, 12($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 20($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 #Limpia la pila +jr $ra -li $v0, 4 # system call #4 - print string -la $a0, endLine -syscall +A_out_a: +#Parametro Return $ra en stackpoiner + 20 +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_to_call_out_string@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 @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 A_out_a +lw $t0, 16($sp) #Buscando la instancia de la clase A en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad io +sw $t1, 12($sp) #Salvando el valor de la propiedad io en la pila en el valor local instance_to_call_out_string@0 #Fin de la exprecion previa al Dispatch out_string +la $t0, string_0 +sw $t0, 8($sp) #Fin del paramentro 0 al Dispatch out_string +lw $t0, 12($sp) #Saca de la pila instance_to_call_out_string@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_string@0 +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 +lw $t0, 20($sp) #Sacando la instancia de la pila (en 12) de una clase que hereda de IO +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de IO +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 #Call a la function $t3 +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, 20($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 #Limpia la pila +jr $ra #Final de la function out_a -li $v0, 1 # system call #4 - print string -la $a0, ($t2) # Imprime 1 primer elemento de Main_parents -syscall # execute +new_ctr_B: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_B +#Allocate a una class B puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +#atributo io en puntero + 8 +li $a0, 12 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo B +la $t0, B +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 -li $v0, 4 # system call #4 - print string -la $a0, endLine -syscall # execute +B_out_b: +#Parametro Return $ra en stackpoiner + 20 +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_to_call_out_string@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 @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 B_out_b +lw $t0, 16($sp) #Buscando la instancia de la clase A en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad io +sw $t1, 12($sp) #Salvando el valor de la propiedad io en la pila en el valor local instance_to_call_out_string@0 #Fin de la exprecion previa al Dispatch out_string +la $t0, string_1 +sw $t0, 8($sp) #Fin del paramentro 0 al Dispatch out_string +lw $t0, 12($sp) #Saca de la pila instance_to_call_out_string@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_out_string@0 +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 +lw $t0, 20($sp) #Sacando la instancia de la pila (en 12) de una clase que hereda de IO +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de IO +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion out_string +jal $t3 #Call a la function $t3 +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, 20($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 #Limpia la pila +jr $ra #Final de la function out_b -li $v0, 1 # system call #4 - print string -la $a0, 0($t3) # Imprime direccion de Main -syscall # execute +new_ctr_C: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_C +#Allocate a una class C puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo C +la $t0, C +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 -li $v0, 4 # system call #4 - print string -la $a0, endLine -syscall # execute +C_out_c: +#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 C_out_c +la $t0, string_2 +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 out_c -lw $t4, 4($t3) -jal $t4 +new_ctr_D: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_D +#Allocate a una class D puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo D +la $t0, D +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 -li $v0, 4 # system call #4 - print string -la $a0, endLine -syscall # execute +D_out_d: +#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 D_out_d +la $t0, string_3 +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 out_d -li $v0, 10 -syscall # execute +IO_out_string: +li $v0, 4 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra +new_ctr_IO: +#Parametro Return $ra en stackpoiner + 16 +#Parametro self en stackpoiner + 12 +addi $sp, $sp, -4 #Push local var instance stackpointer 8 +addi $sp, $sp, -4 #Push local var type_name@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_IO +#Allocate a una class IO puntero en sp + 8 +#atributo @type en puntero + 0 +#atributo type en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo IO +la $t0, IO +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando la instancia en la pila instance +lw $t1, 4($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 $s0, 8($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 -f1: -li $v0, 1 # system call #4 - print string -la $a0, 10 -syscall # execute -jr $ra \ No newline at end of file From ba8a3c6fcad20e89c88fa3402b0afe7e1d08354a Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 11:59:56 -0500 Subject: [PATCH 47/91] defasaje de la pila --- .../v0_type_data_code/type_data_code_visitor.py | 3 ++- .../codegen/v1_mips_generate/mipsgenerate.py | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index e37c73b30..36c985c8c 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -110,11 +110,12 @@ 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) + self.new_type_func.force_local('self', self.new_class_scope) self.new_type_func.force_local('instance', self.new_class_scope) tn = self.new_type_func.local_push('type_name', self.new_class_scope) self.new_type_func.expr_push(ASTR.ALLOCATE('instance', _type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {_type.name}')) + self.new_type_func.expr_push(ASTR.Assign('self', 'instance')) self.new_type_func.expr_push(ASTR.Load(tn, _type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 1c33b543c..08ada5e8e 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -269,20 +269,20 @@ def visit(self,node:AST.Assign): dir_value = node.y stack_plus = self.stack_index(memory_dest) - if(type(dir_value)==type(int()) or type(dir_value)==type(float())): + if type(dir_value) in [type(int()), type(float())]: return [ ASTR.LI('$t0' , str(dir_value)), - ASTR.Comment(f"pon en $t0 {dir_value} "), + ASTR.Comment(f"Guarda el numbero que se va a asignar"), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"pon en la posicion {dir_value} el valor $t0 ") + ASTR.Comment(f"Escribe en la pila el numero que se le asigno a {memory_dest}") ] else: stack_plus_dir_value = self.stack_index(dir_value) return [ ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), - ASTR.Comment(f"pon en $t0 el contenido de la pos {stack_plus_dir_value} "), + ASTR.Comment(f"Lee de la pila {dir_value} en {stack_plus_dir_value} para assignar"), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"pon en la pos {stack_plus_dir_value} el valor de $t0") + ASTR.Comment(f"Escribe en la pila el valor que se le asigno a {memory_dest}") ] @visitor.when(AST.Neg) From d36a3ed43aaa8132f9c8ff0ec4107b8ffa6412df Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 12:01:19 -0500 Subject: [PATCH 48/91] mipsgen --- src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 1c33b543c..fb34cf895 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -274,7 +274,7 @@ def visit(self,node:AST.Assign): ASTR.LI('$t0' , str(dir_value)), ASTR.Comment(f"pon en $t0 {dir_value} "), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"pon en la posicion {dir_value} el valor $t0 ") + ASTR.Comment(f'pon en la posicion {stack_plus} el valor $t0 ') ] else: stack_plus_dir_value = self.stack_index(dir_value) @@ -282,7 +282,7 @@ def visit(self,node:AST.Assign): ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), ASTR.Comment(f"pon en $t0 el contenido de la pos {stack_plus_dir_value} "), ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"pon en la pos {stack_plus_dir_value} el valor de $t0") + ASTR.Comment(f"pon en la pos {stack_plus} el valor de $t0") ] @visitor.when(AST.Neg) From 19c1b8787f668c7841e93b6e6dbe059feb7cc75f Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 12:01:47 -0500 Subject: [PATCH 49/91] nn --- src/cool_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 7098dfaa6..3a1b97a12 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -# path = "test.cl" +path = "test.cl" with open(path, 'r') as _file: text = _file.read() From bcc01fbd7d1033ea6a5842f7632b5ad1554870cb Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 12:46:19 -0500 Subject: [PATCH 50/91] refactor assing ra --- src/cool_compiler/__main__.py | 2 +- .../v0_type_data_code/type_data_code_visitor.py | 4 ++-- .../codegen/v1_mips_generate/mipsgenerate.py | 17 ++++++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 7098dfaa6..3a1b97a12 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -# path = "test.cl" +path = "test.cl" with open(path, 'r') as _file: text = _file.read() diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 36c985c8c..99831ad70 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -75,7 +75,7 @@ def create_type(self, _type, scope): type_list = [] for parent in parent_list(_type): type_list.append(self.map_type(parent.name)) - self.currentType.attr_push('type', self.currentType.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: @@ -118,7 +118,7 @@ def create_new_func_by_type(self, _type, scope): self.new_type_func.expr_push(ASTR.Assign('self', 'instance')) self.new_type_func.expr_push(ASTR.Load(tn, _type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) - self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type', tn)) + self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type_name', tn)) self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) @visitor.when(AST.AtrDef) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 08ada5e8e..29394b3f5 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -42,7 +42,7 @@ def visit(self, node: AST.Function): self.final_len_stack = len(node.param) + len(node.local) + 2 self.local_push = 0 - for param in [AST.Param('Return $ra')] + node.param: + for param in node.param: new_func.cmd += self.visit(param) for _local in node.local + [AST.Local('$ra')]: @@ -83,15 +83,14 @@ def visit(self, node: AST.ALLOCATE): stack_plus = self.stack_index(memory_dir) attr_list = self.cil_type[_type].attributes - _len = len(attr_list) * 4 + 4 + _len = len(attr_list) * 4 result = [ ASTR.Header_Comment(f"Allocate a una class {_type} puntero en sp + {stack_plus}"), - ASTR.Header_Comment(f"atributo @type en puntero + 0"), ] for i, attr in enumerate(attr_list): - result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {(i + 1) * 4}')) + result.append(ASTR.Header_Comment(f'atributo {attr} en puntero + {i * 4}')) return result + [ ASTR.LI('$a0', _len), @@ -110,7 +109,7 @@ def visit(self, node: AST.GetAttr): stack_plus_dest = self.stack_index(memory_dest) stack_plus_instance = self.stack_index(memory_dir_instance) - attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + 4 + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 return [ ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), @@ -123,13 +122,13 @@ def visit(self, node: AST.GetAttr): @visitor.when(AST.SetAttr) def visit(self, node: AST.SetAttr): - if node.y == 'type': + if node.y == 'type_name': attr_plus = 0 else: attr_name = node.y.split('@') _type = attr_name[0] attr = attr_name[1] - attr_plus = self.cil_type[_type].attributes.index(attr) * 4 + 4 + attr_plus = self.cil_type[_type].attributes.index(attr) * 4 memory_dir_instance = node.x memory_dir_value = node.z @@ -139,7 +138,7 @@ def visit(self, node: AST.SetAttr): return [ ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), - ASTR.Comment(f'Buscando la instancia en la pila {node.x}'), + ASTR.Comment(f'Buscando en la pila la variable {node.x} y guarda la direccion a la que apunta'), ASTR.LW('$t1', f'{stack_plus_dir_value}($sp)'), ASTR.Comment(f'Buscando el valor que se va a guardar en la propiedad'), ASTR.SW('$t1', f'{attr_plus}($t0)'), @@ -220,7 +219,7 @@ def visit(self, node: AST.Return): return [ ASTR.LW('$s0', f'{stack_plus}($sp)'), ASTR.Comment("Envia el resultado de la funcion en $s0"), - ASTR.LW('$ra', f'{(len(self.stack) - 1)* 4}($sp)'), + ASTR.LW('$ra', '0($sp)'),#f'{(len(self.stack) - 1)* 4}($sp)'), ASTR.Comment("Lee el $ra mas profundo de la pila para retornar a la funcion anterior"), ASTR.AddI('$sp', '$sp', len(self.stack) * 4), ASTR.Comment("Limpia la pila"), From 47145081357264da57791f4dc620be176709cdcd Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 14:59:46 -0500 Subject: [PATCH 51/91] fib --- .../v1_mips_generate/mipsgenerate_ast.py | 74 ++++++++++++++++++- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 5d86d440b..f25b28562 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -308,7 +308,8 @@ def __str__(self) -> str: IO_in_int: li $v0,5 syscall -move $s0 , $a0 +move $s0 , $v0 +jr $ra """ class In_Float: @@ -345,17 +346,82 @@ def __str__(self) -> str: ################################# Native Func Str ################################################ class Length: def __str__(self) -> str: - return """ yaaaa + return """ + + legnht: + li $t0 , 0 + lw $s2 , ($sp) + loop: + lb $s0 , ($s2) + beq $s0 , $zero, END + add $t0 , $t0 ,1 + add $s2,$s2,4 + j loop + + + END: + move $s0 , $t0 + jr $ra + """ class Concat: def __str__(self) -> str: - return """ yaaaa + return """ + Concat: + lw $s2 , 4($sp) + lw $s1 , 0($sp) + + li $v0 , 9 + li $a0 , 100 + syscall + move $s3 , $v0 + + loop_str1: + lb $t0 , ($s1) + beq $t0 , $zero, loop_str2 + add $s1 , $s1 ,1 + sb $t0,($s3) + add $s3 , $s3 , 1 + j loop_str1 + + loop_str2: + lb $t0 , ($s2) + beq $t0 , $zero, ENDConcat + add $s2 , $s2 ,1 + sb $t0,($s3) + add $s3 , $s3 , 1 + j loop_str1 + + ENDConcat: + move $s0, $v0 + jr $ra """ class SubStr: def __str__(self) -> str: - return """ yaaaaa + return """ + + Substring: + li $t0 ,0 + find_index: + beq $t0, $s1, find_length # if $t0 == $t1 then target + add $s3, $s3, 1 #s2 = s2 + 1 + add $t0, $t0, 1 # $t0 = $t0 + 1 + j find_index + + find_length: + lb $t1, ($s3) # + sb $t1, ($s4) + beq $t0, $s2, END_Substring # if $t0 == $t1 then target + add $s4, $s4, 1 # $S4 = s41 1t2 + # + add $s3, $s3, 1 #s2 = s2 + 1 + add $t0, $t0, 1 # $t0 = $t0 + 1 + j find_length + + END_Substring: + jr $ra """ ################################# Native Func Obj ################################################ class Copy: From 48c2ae1be8616b4a3579f89561308369a3bdcbc9 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 15:00:02 -0500 Subject: [PATCH 52/91] cambiando la pila --- .../codegen/v1_mips_generate/mipsgenerate.py | 77 +++++++++---------- .../codegen/v1_mips_generate/stack.py | 28 +++++++ 2 files changed, 64 insertions(+), 41 deletions(-) create mode 100644 src/cool_compiler/codegen/v1_mips_generate/stack.py diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 29394b3f5..e776572d7 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -1,3 +1,4 @@ +from cool_compiler.codegen.v1_mips_generate.stack import Stack from ...cmp import visitor from ..v0_type_data_code import type_data_code_ast as AST from . import mipsgenerate_ast as ASTR @@ -38,9 +39,7 @@ def visit(self, node: AST.Program): @visitor.when(AST.Function) def visit(self, node: AST.Function): new_func = ASTR.Func(node.name if not node.name == 'new_ctr_Main' else 'main') - self.stack = [] - self.final_len_stack = len(node.param) + len(node.local) + 2 - self.local_push = 0 + self.stack = Stack(node) for param in node.param: new_func.cmd += self.visit(param) @@ -59,21 +58,19 @@ def visit(self, node: AST.Function): #stack_pointer = 0 #bsp = self.base_stack_pointer - def stack_index(self, name): - return (len(self.stack) - self.stack.index(name) - 1) * 4 @visitor.when(AST.Param) def visit(self, node: AST.Param): - self.stack.append(node.x) - return [ASTR.Header_Comment(f'Parametro {node.x} en stackpoiner + {(self.final_len_stack - len(self.stack)) * 4}')] + self.stack.list.append(node.x) + return [ASTR.Header_Comment(f'Parametro {node.x} en stackpoiner + {self.stack.initial_index}')] @visitor.when(AST.Local) def visit(self, node: AST.Local): - self.stack.append(node.x) + self.stack.list.append(node.x) return [ ASTR.AddI('$sp', '$sp', -4), ASTR.Comment( - f'Push local var {node.x} stackpointer {(self.final_len_stack - len(self.stack)) * 4}') + f'Push local var {node.x} stackpointer {self.stack.initial_index}') ] @visitor.when(AST.ALLOCATE) @@ -81,7 +78,7 @@ def visit(self, node: AST.ALLOCATE): memory_dir = node.x _type = node.y - stack_plus = self.stack_index(memory_dir) + stack_plus = self.stack.index(memory_dir) attr_list = self.cil_type[_type].attributes _len = len(attr_list) * 4 @@ -107,8 +104,8 @@ def visit(self, node: AST.GetAttr): _type = attr_name[0] attr = attr_name[1] - stack_plus_dest = self.stack_index(memory_dest) - stack_plus_instance = self.stack_index(memory_dir_instance) + stack_plus_dest = self.stack.index(memory_dest) + stack_plus_instance = self.stack.index(memory_dir_instance) attr_plus = self.cil_type[_type].attributes.index(attr) * 4 return [ @@ -133,8 +130,8 @@ def visit(self, node: AST.SetAttr): memory_dir_instance = node.x memory_dir_value = node.z - stack_plus_dir_value = self.stack_index(memory_dir_value) - stack_plus_instance = self.stack_index(memory_dir_instance) + stack_plus_dir_value = self.stack.index(memory_dir_value) + stack_plus_instance = self.stack.index(memory_dir_instance) return [ ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), @@ -149,9 +146,8 @@ def visit(self, node: AST.SetAttr): def visit(self, node: AST.Arg): memory_dir = node.x - stack_plus = self.stack_index(memory_dir) - self.local_push += 1 - self.stack.append(memory_dir) + stack_plus = self.stack.index(memory_dir) + self.stack.push(memory_dir) return [ ASTR.LW('$t0', f'{stack_plus}($sp)'), @@ -162,9 +158,8 @@ def visit(self, node: AST.Arg): ] def call(self, func, memory_dest): - self.stack = self.stack[0: len(self.stack) - self.local_push] - self.local_push = 0 - stack_plus = self.stack_index(memory_dest) + self.stack.clean() + stack_plus = self.stack.index(memory_dest) return [ ASTR.JAL(func), @@ -191,7 +186,7 @@ def visit(self, node: AST.New): @visitor.when(AST.Call) def visit(self, node: AST.Call): memory_dest = node.x - instance_stack = self.stack_index(node.y) + instance_stack = self.stack.index(node.y) _type, func_name = node.z.split('@') self.func_list += [func for func in self.cil_func.keys() @@ -200,7 +195,7 @@ def visit(self, node: AST.Call): func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 4 result = [ ASTR.LW('$t0', f'{instance_stack}($sp)'), - ASTR.Comment(f"Sacando la instancia de la pila (en {instance_stack - self.local_push * 4}) de una clase que hereda de {_type}"), + ASTR.Comment(f"Sacando la instancia de la pila (en {instance_stack - self.stack.local_push * 4}) de una clase que hereda de {_type}"), ASTR.LW('$t1', '0($t0)'), ASTR.Comment(f"Leyendo el tipo de la instancia que hereda de {_type}"), ASTR.LW('$t3', f'{func_address}($t1)'), @@ -214,14 +209,14 @@ def visit(self, node: AST.Return): return [ASTR.LI('$v0', 10), ASTR.SysCall()] memory_dest = node.x - stack_plus = self.stack_index(memory_dest) + stack_plus = self.stack.index(memory_dest) return [ ASTR.LW('$s0', f'{stack_plus}($sp)'), ASTR.Comment("Envia el resultado de la funcion en $s0"), ASTR.LW('$ra', '0($sp)'),#f'{(len(self.stack) - 1)* 4}($sp)'), ASTR.Comment("Lee el $ra mas profundo de la pila para retornar a la funcion anterior"), - ASTR.AddI('$sp', '$sp', len(self.stack) * 4), + ASTR.AddI('$sp', '$sp', self.stack.close()), ASTR.Comment("Limpia la pila"), ASTR.JR('$ra') ] @@ -231,7 +226,7 @@ def visit(self, node: AST.Load): memory_dest = node.x data_label = node.y - stack_plus = self.stack_index(memory_dest) + stack_plus = self.stack.index(memory_dest) return [ ASTR.LA('$t0', data_label), @@ -248,9 +243,9 @@ def visit(self,node:AST.CmpInt): dir_cmp1 = node.y dir_cmp2 = node.z - stack_plus_opr_1 = self.stack_index(dir_cmp1) - stack_plus_opr_2 = self.stack_index(dir_cmp2) - stack_plus_dest = self.stack_index(memory_dest) + stack_plus_opr_1 = self.stack.index(dir_cmp1) + stack_plus_opr_2 = self.stack.index(dir_cmp2) + stack_plus_dest = self.stack.index(memory_dest) return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , ASTR.Comment(f"carga en $t1 lo que hay en {stack_plus_opr_1} "), @@ -266,7 +261,7 @@ def visit(self,node:AST.CmpInt): def visit(self,node:AST.Assign): memory_dest = node.x dir_value = node.y - stack_plus = self.stack_index(memory_dest) + stack_plus = self.stack.index(memory_dest) if type(dir_value) in [type(int()), type(float())]: return [ @@ -276,7 +271,7 @@ def visit(self,node:AST.Assign): ASTR.Comment(f"Escribe en la pila el numero que se le asigno a {memory_dest}") ] else: - stack_plus_dir_value = self.stack_index(dir_value) + stack_plus_dir_value = self.stack.index(dir_value) return [ ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), ASTR.Comment(f"Lee de la pila {dir_value} en {stack_plus_dir_value} para assignar"), @@ -288,8 +283,8 @@ def visit(self,node:AST.Assign): def visit(self,node:AST.Neg): memory_dest = node.x memory_op1 = node.y - stack_plus_memory_dest = self.stack_index(memory_dest) - stack_plus_opr_1 = self.stack_index(memory_op1) + stack_plus_memory_dest = self.stack.index(memory_dest) + stack_plus_opr_1 = self.stack.index(memory_op1) return [ ASTR.LW ('$t0',f'{stack_plus_opr_1}($sp)'), @@ -310,9 +305,9 @@ def visit(self,node:AST.Sum): memory_op1=node.y memory_op2=node.z - stack_plus_memory_dest = self.stack_index(memory_dest) - stack_plus_opr_1 = self.stack_index(memory_op1) - stack_plus_opr_2 = self.stack_index(memory_op2) + stack_plus_memory_dest = self.stack.index(memory_dest) + stack_plus_opr_1 = self.stack.index(memory_op1) + stack_plus_opr_2 = self.stack.index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), @@ -330,9 +325,9 @@ def visit(self,node:AST.Rest): memory_op1=node.y memory_op2=node.z - stack_plus_memory_dest = self.stack_index(memory_dest) - stack_plus_opr_1 = self.stack_index(memory_op1) - stack_plus_opr_2 = self.stack_index(memory_op2) + stack_plus_memory_dest = self.stack.index(memory_dest) + stack_plus_opr_1 = self.stack.index(memory_op1) + stack_plus_opr_2 = self.stack.index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), @@ -350,7 +345,7 @@ def visit(self,node:AST.IfGoTo): memory_cmp = node.x label_memory = node.y - stack_plus_memory_cmp = self.stack_index(memory_cmp) + stack_plus_memory_cmp = self.stack.index(memory_cmp) return [ASTR.LI("$t0" ,1), ASTR.Comment("Cargar 1 a $t0 pa comparar"), @@ -372,8 +367,8 @@ def visit(self,node:AST.CheckType): memory_instance = node.y type_name = node.z - stack_plus_memory_dir = self.stack_index(memory_dir) - stack_plus_memory_instance = self.stack_index(memory_instance) + stack_plus_memory_dir = self.stack.index(memory_dir) + stack_plus_memory_instance = self.stack.index(memory_instance) return [ ASTR.LW('$s2',f'{stack_plus_memory_instance}($sp)'), 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..947e38e7e --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/stack.py @@ -0,0 +1,28 @@ +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 + self.list.append(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): + result = len(self.list) * 4 + self.local_push + self.list = [] + return result \ No newline at end of file From 7b339a277c9dc85442390255ef01d50d8bfda8e4 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 15:48:31 -0500 Subject: [PATCH 53/91] fib --- .../codegen/v1_mips_generate/mipsgenerate_ast.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index f25b28562..2344a6ead 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -298,8 +298,8 @@ def __str__(self) -> str: li $a1 , 10000 syscall move $s0 , $a0 - - +addi $sp, $sp, 4 +jr $ra """ class In_Int: @@ -309,6 +309,7 @@ def __str__(self) -> str: li $v0,5 syscall move $s0 , $v0 +addi $sp, $sp, 4 jr $ra """ From 6d6da5d4001de136916b6fff912954ae8dc96629 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 16:03:54 -0500 Subject: [PATCH 54/91] refactor nodes --- .../codegen/v1_mips_generate/mipsgenerate_ast.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 2344a6ead..b13f62998 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -334,7 +334,6 @@ def __str__(self) -> str: add $s2,$s2,4 j loop - Equal: li $s0 , 1 jr $ra @@ -362,6 +361,7 @@ def __str__(self) -> str: END: move $s0 , $t0 + addi $sp, $sp, 4 jr $ra """ @@ -396,14 +396,14 @@ def __str__(self) -> str: ENDConcat: move $s0, $v0 + addi $sp, $sp, 8 jr $ra """ class SubStr: def __str__(self) -> str: - return """ - - Substring: + return """ +Substring: li $t0 ,0 find_index: beq $t0, $s1, find_length # if $t0 == $t1 then target @@ -422,6 +422,7 @@ def __str__(self) -> str: j find_length END_Substring: + addi $sp, $sp, 12 jr $ra """ ################################# Native Func Obj ################################################ From be45bae789de3493019cd3a9fec24cffda0f9e40 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 16:04:16 -0500 Subject: [PATCH 55/91] space --- .../codegen/v1_mips_generate/mipsgenerate.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index e776572d7..0ca6b545e 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -379,13 +379,7 @@ def visit(self,node:AST.CheckType): ASTR.Comment("Salta para Contain"), ASTR.SW ('$s0',f'{stack_plus_memory_dir}($sp)'), ASTR.Comment(f"Guarda en la pos {stack_plus_memory_dir}($sp) el contenido de $s0") - - - - - - ] - + ] @ visitor.when(AST.GoTo) def visit(self,node:AST.GoTo): From e1c885ebfcac8abead20aee29471ab2dca09cfea Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 16:10:35 -0500 Subject: [PATCH 56/91] cilo de mips --- src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 0ca6b545e..024159426 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -173,14 +173,14 @@ def visit(self, node: AST.VCall): memory_dest = node.x _type = node.y func = self.cil_type[_type].methods[node.z] - self.func_list.append(func) + if not func in self.func_list: self.func_list.append(func) return self.call(func, memory_dest) @visitor.when(AST.New) def visit(self, node: AST.New): func = f'new_ctr_{node.y}' - self.func_list.append(func) + 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) From 3c61a17343d34c80c15e47dec5013d464eaaefe7 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 16:11:57 -0500 Subject: [PATCH 57/91] palind --- .../v1_mips_generate/mipsgenerate_ast.py | 7 + src/test.cl | 25 + src/test.mips | 224 ++++++ tests/codegen/cells.mips | 702 ++++++++++++++++++ tests/codegen/complex.mips | 319 ++++++++ tests/codegen/hello_world.mips | 76 ++ 6 files changed, 1353 insertions(+) create mode 100644 tests/codegen/cells.mips create mode 100644 tests/codegen/complex.mips create mode 100644 tests/codegen/hello_world.mips diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index f25b28562..e883b62d5 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -298,6 +298,8 @@ def __str__(self) -> str: li $a1 , 10000 syscall move $s0 , $a0 +addi $sp , $sp ,4 +jr $ra """ @@ -309,6 +311,7 @@ def __str__(self) -> str: li $v0,5 syscall move $s0 , $v0 +addi $sp ,$sp ,4 jr $ra """ @@ -336,10 +339,12 @@ def __str__(self) -> str: Equal: li $s0 , 1 +adii $sp , $sp ,4 jr $ra END: li $s0 , 0 +addi $sp , $sp , 4 jr $ra """ @@ -361,6 +366,7 @@ def __str__(self) -> str: END: move $s0 , $t0 + addi $sp , $sp ,4 jr $ra """ @@ -421,6 +427,7 @@ def __str__(self) -> str: j find_length END_Substring: + adii $sp , $sp ,12 jr $ra """ ################################# Native Func Obj ################################################ diff --git a/src/test.cl b/src/test.cl index e69de29bb..f15425a96 100755 --- a/src/test.cl +++ b/src/test.cl @@ -0,0 +1,25 @@ +class Main inherits IO { + pal(s : String) : Bool { + if s.length() = 0 + then true + else if s.length() = 1 + then true + else if s.substr(0, 1) = s.substr(s.length() - 1, 1) + then pal(s.substr(1, s.length() -2)) + else false + fi fi fi + }; + + i : Int; + + main() : IO { + { + i <- ~1; + out_string("enter a string\n"); + if pal(in_string()) + then out_string("that was a palindrome\n") + else out_string("that was not a palindrome\n") + fi; + } + }; +}; \ No newline at end of file diff --git a/src/test.mips b/src/test.mips index e69de29bb..ddc81d92e 100644 --- a/src/test.mips +++ b/src/test.mips @@ -0,0 +1,224 @@ +.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, 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 20 +addi $sp, $sp, -4 #Push local var instance stackpointer 16 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 new_ctr_Main +#Allocate a una class Main puntero en sp + 12 +#atributo type_name en puntero + 0 +li $a0, 4 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, Main +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data +lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +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 self en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_fib@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@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Main_main #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +la $t0, string_0 +sw $t0, 24($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 32($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, 28($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, 28($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block +lw $t0, 32($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 in_int +jal IO_in_int #Call a la function IO_in_int +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch fib +lw $t0, 32($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 fib +lw $t0, 20($sp) #Saca de la pila param_0_to_fib@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_fib@0 #Agrega a la pila el paramentro 1 al StaticDispatch fib +jal Main_fib #Call a la function Main_fib +sw $s0, 12($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch out_int +lw $t0, 32($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_int +lw $t0, 16($sp) #Saca de la pila param_0_to_out_int@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_out_int@0 #Agrega a la pila el paramentro 1 al StaticDispatch out_int +jal IO_out_int #Call a la function IO_out_int +sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +la $t0, string_1 +sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 32($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@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 36 #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 + +IO_in_int: +li $v0,5 +syscall +move $s0 , $v0 +addi $sp ,$sp ,4 +jr $ra + +Main_fib: +#Parametro self en stackpoiner + 96 +#Parametro i@0 en stackpoiner + 92 +addi $sp, $sp, -4 #Push local var a stackpointer 88 +addi $sp, $sp, -4 #Push local var b stackpointer 84 +addi $sp, $sp, -4 #Push local var c stackpointer 80 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var result@assing@c@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var step@block@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 result@assing@i@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var step@block@3 stackpointer 36 +addi $sp, $sp, -4 #Push local var result@assing@b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var result@assing@a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var neg@_unary@0 stackpointer 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 @result stackpointer 8 +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 Main_fib +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 84($sp) #Escribe en la pila el numero que se le asigno a a #Fin de la asignacion Let a +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 80($sp) #Escribe en la pila el numero que se le asigno a b #Fin de la asignacion Let b +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 76($sp) #Escribe en la pila el numero que se le asigno a c #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 #Salta para f{label} +while_back_0 : #Crea el label while_back_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 84($sp) #Lee de la pila a en 84 para assignar +sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum +lw $t0, 80($sp) #Lee de la pila b en 80 para assignar +sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum +lw $t0, 60($sp) #poner en registro $t0 lo que hay en 60 +lw $t1, 56($sp) #poner en registro $t1 lo que hay en 56 +add $t0, $t0, $t1 #en $t0 pon el resultado de la suma +sw $t0, 52($sp) #poner en la posicion 52 el resultado #Fin de la expresion lista para ser asignada +lw $t0, 52($sp) #Lee de la pila result@assing@c@0 en 52 para assignar +sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a c +lw $t0, 76($sp) #Lee de la pila c en 76 para assignar +sw $t0, 64($sp) #Escribe en la pila el valor que se le asigno a step@block@1 #Inicio del paso 1 de una sequencia Block +lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar +sw $t0, 44($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 44($sp) #poner en registro $t0 lo que hay en 44 +lw $t1, 40($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 36($sp) #poner en 36 el resultado de la suma #Fin de la expresion lista para ser asignada +lw $t0, 36($sp) #Lee de la pila result@assing@i@0 en 36 para assignar +sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a i@0 +lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar +sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a step@block@2 #Inicio del paso 2 de una sequencia Block +lw $t0, 84($sp) #Lee de la pila a en 84 para assignar +sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a result@assing@b@0 #Fin de la expresion lista para ser asignada +lw $t0, 28($sp) #Lee de la pila result@assing@b@0 en 28 para assignar +sw $t0, 80($sp) #Escribe en la pila el valor que se le asigno a b +lw $t0, 80($sp) #Lee de la pila b en 80 para assignar +sw $t0, 32($sp) #Escribe en la pila el valor que se le asigno a step@block@3 #Inicio del paso 3 de una sequencia Block +lw $t0, 76($sp) #Lee de la pila c en 76 para assignar +sw $t0, 24($sp) #Escribe en la pila el valor que se le asigno a result@assing@a@0 #Fin de la expresion lista para ser asignada +lw $t0, 24($sp) #Lee de la pila result@assing@a@0 en 24 para assignar +sw $t0, 84($sp) #Escribe en la pila el valor que se le asigno a a +lw $t0, 84($sp) #Lee de la pila a en 84 para assignar +sw $t0, 68($sp) #Escribe en la pila el valor que se le asigno a result@while@0 +while_cond_0 : #Crea el label while_cond_0 #Fin del cuerpo e inicio de la condicion de un While +lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar +sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 12($sp) #carga en $t1 lo que hay en 12 +lw $t2, 8($sp) #carga en $t2 lo que hay en 8 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 16($sp) #Pon en la posicion 16 el valor de $t3 +lw $t0, 16($sp) #Carga la pos 16 en $t0 +addi $t1, $t0, -1 #$t1 = $t0 + (-1) +mul $t0, $t1, -1 #$t0 = $t1 * (-1) +sw $t0, 20($sp) #poner en la posicion 20 el contenido de $t0 +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 20($sp) #Cargar el valor de la pos 20 a $t1 pa comparar +beq $t0 $t1 while_back_0 #if $t1==$t0 then jump while_back_0 #Fin de la condicion de un While +lw $t0, 92($sp) #Lee de la pila self en 92 para assignar +sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a step@block@0 #Inicio del paso 1 de una sequencia Block +lw $t0, 76($sp) #Lee de la pila c en 76 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 96 #Limpia la pila +jr $ra #Final de la function fib + + +IO_out_int: +li $v0, 1 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra diff --git a/tests/codegen/cells.mips b/tests/codegen/cells.mips new file mode 100644 index 000000000..d6367fd46 --- /dev/null +++ b/tests/codegen/cells.mips @@ -0,0 +1,702 @@ +.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, +CellularAutomaton_parents: .word 1, 6, 7, 0, +CellularAutomaton: .word 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: .word 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 20 +addi $sp, $sp, -4 #Push local var instance stackpointer 16 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 new_ctr_Main +#Allocate a una class Main puntero en sp + 12 +#atributo type_name en puntero + 0 +#atributo cells en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, Main +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data +lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +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 self en stackpoiner + 88 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var instance_to_call_init@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var result@assing@cells@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var instance_to_call_print@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var step@block@2 stackpointer 60 +addi $sp, $sp, -4 #Push local var countdown stackpointer 56 +addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var step@block@3 stackpointer 48 +addi $sp, $sp, -4 #Push local var instance_to_call_evolve@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var step@block@4 stackpointer 40 +addi $sp, $sp, -4 #Push local var instance_to_call_print@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var result@assing@countdown@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Main_main #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +jal new_ctr_CellularAutomaton #Call a la function new_ctr_CellularAutomaton +sw $s0, 76($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch init +la $t0, string_6 +sw $t0, 72($sp) #Fin del paramentro 0 al Dispatch init +lw $t0, 76($sp) #Saca de la pila instance_to_call_init@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_init@0 +lw $t0, 76($sp) #Saca de la pila param_0_to_init@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_init@0 +lw $t0, 84($sp) #Sacando la instancia de la pila (en 76) de una clase que hereda de CellularAutomaton +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 #Call a la function $t3 +sw $s0, 68($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada +lw $t0, 84($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 68($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto +lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad cells +sw $t1, 80($sp) #Salvando el valor de la propiedad cells en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block +lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad cells +sw $t1, 60($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_print@0 #Fin de la exprecion previa al Dispatch print +lw $t0, 60($sp) #Saca de la pila instance_to_call_print@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_print@0 +lw $t0, 64($sp) #Sacando la instancia de la pila (en 60) de una clase que hereda de CellularAutomaton +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 #Call a la function $t3 +sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +li $t0, 20 #Guarda el numbero que se va a asignar +sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a countdown #Fin de la asignacion Let countdown #Inicio de un While +j while_cond_1 #Salta para f{label} +while_back_1 : #Crea el label while_back_1 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad cells +sw $t1, 40($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_evolve@0 #Fin de la exprecion previa al Dispatch evolve +lw $t0, 40($sp) #Saca de la pila instance_to_call_evolve@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_evolve@0 +lw $t0, 44($sp) #Sacando la instancia de la pila (en 40) de una clase que hereda de CellularAutomaton +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton +lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion evolve +jal $t3 #Call a la function $t3 +sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block +lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad cells +sw $t1, 32($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_print@1 #Fin de la exprecion previa al Dispatch print +lw $t0, 32($sp) #Saca de la pila instance_to_call_print@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_print@1 +lw $t0, 36($sp) #Sacando la instancia de la pila (en 32) de una clase que hereda de CellularAutomaton +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton +lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion print +jal $t3 #Call a la function $t3 +sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar +sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 24($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 28($sp) #poner en registro $t0 lo que hay en 28 +lw $t1, 24($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 20($sp) #poner en 20 el resultado de la suma #Fin de la expresion lista para ser asignada +lw $t0, 20($sp) #Lee de la pila result@assing@countdown@0 en 20 para assignar +sw $t0, 52($sp) #Escribe en la pila el valor que se le asigno a countdown +lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar +sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a result@while@0 +while_cond_1 : #Crea el label while_cond_1 #Fin del cuerpo e inicio de la condicion de un While +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a less@_a@0 #Resolucion del operado izquierdo de una opercion less +lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar +sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a less@_b@0 #Resolucion del operado derecha de una opercion less +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 16($sp) #Cargar el valor de la pos 16 a $t1 pa comparar +beq $t0 $t1 while_back_1 #if $t1==$t0 then jump while_back_1 #Fin de la condicion de un While +lw $t0, 84($sp) #Lee de la pila self en 84 para assignar +sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a step@block@2 #Inicio del paso 3 de una sequencia Block +lw $t0, 84($sp) #Lee de la pila self en 84 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 88 #Limpia la pila +jr $ra #Final de la function main + +new_ctr_CellularAutomaton: +addi $sp, $sp, -4 #Push local var self stackpointer 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 $ra stackpointer 4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_CellularAutomaton +#Allocate a una class CellularAutomaton puntero en sp + 8 +#atributo type_name en puntero + 0 +#atributo population_map en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 8($sp) #Reservando memoria para una instancia de tipo CellularAutomaton +lw $t0, 8($sp) #Lee de la pila instance en 8 para assignar +sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, CellularAutomaton +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +lw $t1, 4($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 $s0, 8($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra + +CellularAutomaton_init: +#Parametro self en stackpoiner + 24 +#Parametro map@0 en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var result@assing@population_map@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_init #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 16($sp) #Lee de la pila map@0 en 16 para assignar +sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a result@assing@population_map@0 #Fin de la expresion lista para ser asignada +lw $t0, 20($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto +lw $t0, 20($sp) #Buscando la instancia de la clase CellularAutomaton en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad population_map +sw $t1, 12($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block +lw $t0, 20($sp) #Lee de la pila self en 20 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 #Limpia la pila +jr $ra #Final de la function init + +CellularAutomaton_print: +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var instance_to_call_concat@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_concat@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 @result stackpointer 8 +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 CellularAutomaton_print #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 24($sp) #Buscando la instancia de la clase CellularAutomaton en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad population_map +sw $t1, 16($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_concat@0 #Fin de la exprecion previa al Dispatch concat +la $t0, string_0 +sw $t0, 12($sp) #Fin del paramentro 0 al Dispatch concat +lw $t0, 16($sp) #Saca de la pila instance_to_call_concat@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_concat@0 +lw $t0, 16($sp) #Saca de la pila param_0_to_concat@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_concat@0 +lw $t0, 24($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 16($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 #Call a la function $t3 +sw $s0, 8($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 24($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, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block +lw $t0, 24($sp) #Lee de la pila self en 24 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 #Limpia la pila +jr $ra #Final de la function print + +CellularAutomaton_evolve: +#Parametro self en stackpoiner + 84 +addi $sp, $sp, -4 #Push local var position stackpointer 80 +addi $sp, $sp, -4 #Push local var num stackpointer 76 +addi $sp, $sp, -4 #Push local var temp stackpointer 72 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_to_call_concat@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_cell_at_next_evolution@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var result@assing@temp@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var result@assing@position@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var step@block@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var result@assing@population_map@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_evolve +lw $t0, 80($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 num_cells +jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells +sw $s0, 72($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let num #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block #Inicio de un While +j while_cond_0 #Salta para f{label} +while_back_0 : #Crea el label while_back_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar +sw $t0, 52($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_concat@0 #Fin de la exprecion previa al Dispatch concat +lw $t0, 76($sp) #Lee de la pila position en 76 para assignar +sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_at_next_evolution@0 #Fin del paramentro 0 al StaticDispatch cell_at_next_evolution +lw $t0, 80($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 cell_at_next_evolution +lw $t0, 52($sp) #Saca de la pila param_0_to_cell_at_next_evolution@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell_at_next_evolution@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_at_next_evolution +jal CellularAutomaton_cell_at_next_evolution #Call a la function CellularAutomaton_cell_at_next_evolution +sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al Dispatch concat +lw $t0, 52($sp) #Saca de la pila instance_to_call_concat@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_concat@0 +lw $t0, 48($sp) #Saca de la pila param_0_to_concat@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_concat@0 +lw $t0, 60($sp) #Sacando la instancia de la pila (en 52) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 16($t1) #Buscando el metodo dinamico para la funcion concat +jal $t3 #Call a la function $t3 +sw $s0, 40($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada +lw $t0, 40($sp) #Lee de la pila result@assing@temp@0 en 40 para assignar +sw $t0, 68($sp) #Escribe en la pila el valor que se le asigno a temp +lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar +sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a step@block@1 #Inicio del paso 1 de una sequencia Block +lw $t0, 76($sp) #Lee de la pila position en 76 para assignar +sw $t0, 36($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum +lw $t0, 36($sp) #poner en registro $t0 lo que hay en 36 +lw $t1, 32($sp) #poner en registro $t1 lo que hay en 32 +add $t0, $t0, $t1 #en $t0 pon el resultado de la suma +sw $t0, 28($sp) #poner en la posicion 28 el resultado #Fin de la expresion lista para ser asignada +lw $t0, 28($sp) #Lee de la pila result@assing@position@0 en 28 para assignar +sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a position +lw $t0, 76($sp) #Lee de la pila position en 76 para assignar +sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a result@while@0 +while_cond_0 : #Crea el label while_cond_0 #Fin del cuerpo e inicio de la condicion de un While +lw $t0, 76($sp) #Lee de la pila position en 76 para assignar +sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a less@_a@0 #Resolucion del operado izquierdo de una opercion less +lw $t0, 72($sp) #Lee de la pila num en 72 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a less@_b@0 #Resolucion del operado derecha de una opercion less +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 24($sp) #Cargar el valor de la pos 24 a $t1 pa comparar +beq $t0 $t1 while_back_0 #if $t1==$t0 then jump while_back_0 #Fin de la condicion de un While +lw $t0, 80($sp) #Lee de la pila self en 80 para assignar +sw $t0, 64($sp) #Escribe en la pila el valor que se le asigno a step@block@0 #Inicio del paso 1 de una sequencia Block +lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar +sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a result@assing@population_map@0 #Fin de la expresion lista para ser asignada +lw $t0, 80($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto +lw $t0, 80($sp) #Buscando la instancia de la clase CellularAutomaton en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad population_map +sw $t1, 12($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local step@block@2 #Inicio del paso 2 de una sequencia Block +lw $t0, 80($sp) #Lee de la pila self en 80 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 84 #Limpia la pila +jr $ra #Final de la function evolve + + +IO_out_string: +li $v0, 4 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra +CellularAutomaton_num_cells: +#Parametro self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_num_cells +lw $t0, 12($sp) #Buscando la instancia de la clase CellularAutomaton en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad population_map +sw $t1, 8($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length +lw $t0, 8($sp) #Saca de la pila instance_to_call_length@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_length@0 +lw $t0, 12($sp) #Sacando la instancia de la pila (en 8) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 #Call a la function $t3 +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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra #Final de la function num_cells + +CellularAutomaton_cell_at_next_evolution: +#Parametro self en stackpoiner + 108 +#Parametro position@0 en stackpoiner + 104 +addi $sp, $sp, -4 #Push local var cond@if_else@0 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 sum@_a@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 80 +addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 76 +addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 64 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 52 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 48 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_0_to_cell_left_neighbor@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var cond@if_else@3 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_cell_right_neighbor@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var result@if@3 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_cell_at_next_evolution +lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar +sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell@0 #Fin del paramentro 0 al StaticDispatch cell +lw $t0, 104($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 cell +lw $t0, 60($sp) #Saca de la pila param_0_to_cell@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell +jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell +sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +la $t0, string_1 +sw $t0, 60($sp) #Resolucion del operado derecha de una opercion int_eq +lw $t1, 64($sp) #carga en $t1 lo que hay en 64 +lw $t2, 60($sp) #carga en $t2 lo que hay en 60 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 68($sp) #Pon en la posicion 68 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 68($sp) #Cargar el valor de la pos 68 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_0 #Else case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a result@if@0 +j fin_CellularAutomaton_cell_at_next_evolution_0 #Salta para f{label} +then_CellularAutomaton_cell_at_next_evolution_0 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_0 #Then case +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a result@if@0 +fin_CellularAutomaton_cell_at_next_evolution_0 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_0 #Fin de un If +lw $t0, 52($sp) #Lee de la pila result@if@0 en 52 para assignar +sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a sum@_a@1 #Resolucion del operado izquierdo de una opercion sum +lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar +sw $t0, 36($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_left_neighbor@0 #Fin del paramentro 0 al StaticDispatch cell_left_neighbor +lw $t0, 104($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 cell_left_neighbor +lw $t0, 40($sp) #Saca de la pila param_0_to_cell_left_neighbor@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell_left_neighbor@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_left_neighbor +jal CellularAutomaton_cell_left_neighbor #Call a la function CellularAutomaton_cell_left_neighbor +sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +la $t0, string_2 +sw $t0, 40($sp) #Resolucion del operado derecha de una opercion int_eq +lw $t1, 44($sp) #carga en $t1 lo que hay en 44 +lw $t2, 40($sp) #carga en $t2 lo que hay en 40 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 48($sp) #Pon en la posicion 48 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 48($sp) #Cargar el valor de la pos 48 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_1 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_1 #Else case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a result@if@1 +j fin_CellularAutomaton_cell_at_next_evolution_1 #Salta para f{label} +then_CellularAutomaton_cell_at_next_evolution_1 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_1 #Then case +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a result@if@1 +fin_CellularAutomaton_cell_at_next_evolution_1 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_1 #Fin de un If +lw $t0, 32($sp) #Lee de la pila result@if@1 en 32 para assignar +sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a sum@_b@1 #Resolucion del operado derecha de una opercion sum +lw $t0, 76($sp) #poner en registro $t0 lo que hay en 76 +lw $t1, 72($sp) #poner en registro $t1 lo que hay en 72 +add $t0, $t0, $t1 #en $t0 pon el resultado de la suma +sw $t0, 84($sp) #poner en la posicion 84 el resultado #Resolucion del operado izquierdo de una opercion sum +lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_right_neighbor@0 #Fin del paramentro 0 al StaticDispatch cell_right_neighbor +lw $t0, 104($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 cell_right_neighbor +lw $t0, 20($sp) #Saca de la pila param_0_to_cell_right_neighbor@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell_right_neighbor@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_right_neighbor +jal CellularAutomaton_cell_right_neighbor #Call a la function CellularAutomaton_cell_right_neighbor +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +la $t0, string_3 +sw $t0, 20($sp) #Resolucion del operado derecha de una opercion int_eq +lw $t1, 24($sp) #carga en $t1 lo que hay en 24 +lw $t2, 20($sp) #carga en $t2 lo que hay en 20 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 28($sp) #Pon en la posicion 28 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 28($sp) #Cargar el valor de la pos 28 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_2 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_2 #Else case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a result@if@2 +j fin_CellularAutomaton_cell_at_next_evolution_2 #Salta para f{label} +then_CellularAutomaton_cell_at_next_evolution_2 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_2 #Then case +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a result@if@2 +fin_CellularAutomaton_cell_at_next_evolution_2 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_2 #Fin de un If +lw $t0, 12($sp) #Lee de la pila result@if@2 en 12 para assignar +sw $t0, 80($sp) #Escribe en la pila el valor que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum +lw $t0, 84($sp) #poner en registro $t0 lo que hay en 84 +lw $t1, 80($sp) #poner en registro $t1 lo que hay en 80 +add $t0, $t0, $t1 #en $t0 pon el resultado de la suma +sw $t0, 92($sp) #poner en la posicion 92 el resultado #Resolucion del operado izquierdo de una opercion int_eq +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 92($sp) #carga en $t1 lo que hay en 92 +lw $t2, 88($sp) #carga en $t2 lo que hay en 88 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 96($sp) #Pon en la posicion 96 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 96($sp) #Cargar el valor de la pos 96 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_3 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_3 #Else case +la $t0, string_4 +sw $t0, 8($sp) +j fin_CellularAutomaton_cell_at_next_evolution_3 #Salta para f{label} +then_CellularAutomaton_cell_at_next_evolution_3 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_3 #Then case +la $t0, string_5 +sw $t0, 8($sp) +fin_CellularAutomaton_cell_at_next_evolution_3 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_3 #Fin de un If +lw $t0, 8($sp) #Lee de la pila result@if@3 en 8 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 108 #Limpia la pila +jr $ra #Final de la function cell_at_next_evolution + +CellularAutomaton_cell: +#Parametro self en stackpoiner + 28 +#Parametro position@0 en stackpoiner + 24 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_cell +lw $t0, 24($sp) #Buscando la instancia de la clase CellularAutomaton en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad population_map +sw $t1, 16($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr +lw $t0, 20($sp) #Lee de la pila position@0 en 20 para assignar +sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr +lw $t0, 16($sp) #Saca de la pila instance_to_call_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@0 +lw $t0, 16($sp) #Saca de la pila param_0_to_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_substr@0 +lw $t0, 16($sp) #Saca de la pila param_1_to_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_substr@0 +lw $t0, 28($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 #Call a la function $t3 +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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 #Limpia la pila +jr $ra #Final de la function cell + +CellularAutomaton_cell_left_neighbor: +#Parametro self en stackpoiner + 56 +#Parametro position@0 en stackpoiner + 52 +addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 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 result@if@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_cell@0 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 param_0_to_cell@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_cell_left_neighbor +lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar +sw $t0, 40($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 36($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 40($sp) #carga en $t1 lo que hay en 40 +lw $t2, 36($sp) #carga en $t2 lo que hay en 36 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 44($sp) #Pon en la posicion 44 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 44($sp) #Cargar el valor de la pos 44 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_left_neighbor_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_left_neighbor_0 #Else case +lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar +sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 24($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 28($sp) #poner en registro $t0 lo que hay en 28 +lw $t1, 24($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 20($sp) #poner en 20 el resultado de la suma #Fin del paramentro 0 al StaticDispatch cell +lw $t0, 52($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 cell +lw $t0, 24($sp) #Saca de la pila param_0_to_cell@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell +jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +j fin_CellularAutomaton_cell_left_neighbor_0 #Salta para f{label} +then_CellularAutomaton_cell_left_neighbor_0 : #Crea el label then_CellularAutomaton_cell_left_neighbor_0 #Then case +lw $t0, 52($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 num_cells +jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest +lw $t0, 16($sp) #poner en registro $t0 lo que hay en 16 +lw $t1, 12($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 8($sp) #poner en 8 el resultado de la suma #Fin del paramentro 0 al StaticDispatch cell +lw $t0, 52($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 cell +lw $t0, 12($sp) #Saca de la pila param_0_to_cell@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell@1 #Agrega a la pila el paramentro 1 al StaticDispatch cell +jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +fin_CellularAutomaton_cell_left_neighbor_0 : #Crea el label fin_CellularAutomaton_cell_left_neighbor_0 #Fin de un If +lw $t0, 32($sp) #Lee de la pila result@if@0 en 32 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 #Limpia la pila +jr $ra #Final de la function cell_left_neighbor + +CellularAutomaton_cell_right_neighbor: +#Parametro self en stackpoiner + 56 +#Parametro position@0 en stackpoiner + 52 +addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 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 rest@_a@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var result@if@0 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 param_0_to_cell@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_0_to_cell@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 CellularAutomaton_cell_right_neighbor +lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar +sw $t0, 40($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 52($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 num_cells +jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 32($sp) #poner en registro $t0 lo que hay en 32 +lw $t1, 28($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 36($sp) #poner en 36 el resultado de la suma #Resolucion del operado derecha de una opercion int_eq +lw $t1, 40($sp) #carga en $t1 lo que hay en 40 +lw $t2, 36($sp) #carga en $t2 lo que hay en 36 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 44($sp) #Pon en la posicion 44 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 44($sp) #Cargar el valor de la pos 44 a $t1 pa comparar +beq $t0 $t1 then_CellularAutomaton_cell_right_neighbor_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_right_neighbor_0 #Else case +lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar +sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 16($sp) #Escribe en la pila el numero que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum +lw $t0, 20($sp) #poner en registro $t0 lo que hay en 20 +lw $t1, 16($sp) #poner en registro $t1 lo que hay en 16 +add $t0, $t0, $t1 #en $t0 pon el resultado de la suma +sw $t0, 12($sp) #poner en la posicion 12 el resultado #Fin del paramentro 0 al StaticDispatch cell +lw $t0, 52($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 cell +lw $t0, 16($sp) #Saca de la pila param_0_to_cell@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell +jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +j fin_CellularAutomaton_cell_right_neighbor_0 #Salta para f{label} +then_CellularAutomaton_cell_right_neighbor_0 : #Crea el label then_CellularAutomaton_cell_right_neighbor_0 #Then case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a param_0_to_cell@1 #Fin del paramentro 0 al StaticDispatch cell +lw $t0, 52($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 cell +lw $t0, 12($sp) #Saca de la pila param_0_to_cell@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_cell@1 #Agrega a la pila el paramentro 1 al StaticDispatch cell +jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +fin_CellularAutomaton_cell_right_neighbor_0 : #Crea el label fin_CellularAutomaton_cell_right_neighbor_0 #Fin de un If +lw $t0, 24($sp) #Lee de la pila result@if@0 en 24 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 56 #Limpia la pila +jr $ra #Final de la function cell_right_neighbor + diff --git a/tests/codegen/complex.mips b/tests/codegen/complex.mips new file mode 100644 index 000000000..55200f39c --- /dev/null +++ b/tests/codegen/complex.mips @@ -0,0 +1,319 @@ +.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, +Complex_parents: .word 1, 6, 8, 0, +Complex: .word 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 20 +addi $sp, $sp, -4 #Push local var instance stackpointer 16 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 new_ctr_Main +#Allocate a una class Main puntero en sp + 12 +#atributo type_name en puntero + 0 +li $a0, 4 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, Main +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data +lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +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 self en stackpoiner + 64 +addi $sp, $sp, -4 #Push local var c stackpointer 60 +addi $sp, $sp, -4 #Push local var instance_to_call_init@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var cond@if_else@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 instance_to_call_reflect_X@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var instance_to_call_reflect_Y@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var instance_to_call_reflect_0@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var result@if@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 param_0_to_out_string@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Main_main +jal new_ctr_Complex #Call a la function new_ctr_Complex +sw $s0, 52($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch init +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 48($sp) #Escribe en la pila el numero que se le asigno a param_0_to_init@0 #Fin del paramentro 0 al Dispatch init +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 44($sp) #Escribe en la pila el numero que se le asigno a param_1_to_init@0 #Fin del paramentro 1 al Dispatch init +lw $t0, 52($sp) #Saca de la pila instance_to_call_init@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_init@0 +lw $t0, 52($sp) #Saca de la pila param_0_to_init@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_init@0 +lw $t0, 52($sp) #Saca de la pila param_1_to_init@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_init@0 +lw $t0, 64($sp) #Sacando la instancia de la pila (en 52) de una clase que hereda de Complex +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion init +jal $t3 #Call a la function $t3 +sw $s0, 56($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let c +lw $t0, 56($sp) #Lee de la pila c en 56 para assignar +sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_reflect_X@0 #Fin de la exprecion previa al Dispatch reflect_X +lw $t0, 28($sp) #Saca de la pila instance_to_call_reflect_X@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_reflect_X@0 +lw $t0, 32($sp) #Sacando la instancia de la pila (en 28) de una clase que hereda de Complex +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex +lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion reflect_X +jal $t3 #Call a la function $t3 +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch reflect_Y +lw $t0, 24($sp) #Saca de la pila instance_to_call_reflect_Y@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_reflect_Y@0 +lw $t0, 28($sp) #Sacando la instancia de la pila (en 24) de una clase que hereda de Complex +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex +lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion reflect_Y +jal $t3 #Call a la function $t3 +sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 56($sp) #Lee de la pila c en 56 para assignar +sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_reflect_0@0 #Fin de la exprecion previa al Dispatch reflect_0 +lw $t0, 20($sp) #Saca de la pila instance_to_call_reflect_0@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_reflect_0@0 +lw $t0, 24($sp) #Sacando la instancia de la pila (en 20) de una clase que hereda de Complex +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex +lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion reflect_0 +jal $t3 #Call a la function $t3 +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq +lw $t1, 36($sp) #carga en $t1 lo que hay en 36 +lw $t2, 32($sp) #carga en $t2 lo que hay en 32 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 40($sp) #Pon en la posicion 40 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 40($sp) #Cargar el valor de la pos 40 a $t1 pa comparar +beq $t0 $t1 then_Main_main_0 #if $t1==$t0 then jump then_Main_main_0 #Else case +la $t0, string_0 +sw $t0, 12($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 60($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, 16($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, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +j fin_Main_main_0 #Salta para f{label} +then_Main_main_0 : #Crea el label then_Main_main_0 #Then case +la $t0, string_1 +sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 60($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@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #Agrega a la pila el paramentro 1 al StaticDispatch out_string +jal IO_out_string #Call a la function IO_out_string +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +fin_Main_main_0 : #Crea el label fin_Main_main_0 #Fin de un If +lw $t0, 16($sp) #Lee de la pila result@if@0 en 16 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 64 #Limpia la pila +jr $ra #Final de la function main + +new_ctr_Complex: +addi $sp, $sp, -4 #Push local var self stackpointer 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 $ra stackpointer 4 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Complex +#Allocate a una class Complex puntero en sp + 8 +#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, 8($sp) #Reservando memoria para una instancia de tipo Complex +lw $t0, 8($sp) #Lee de la pila instance en 8 para assignar +sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, Complex +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +lw $t1, 4($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 $s0, 8($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 #Limpia la pila +jr $ra + +Complex_init: +#Parametro self en stackpoiner + 44 +#Parametro a@0 en stackpoiner + 40 +#Parametro b@0 en stackpoiner + 36 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Complex_init #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad x +sw $t1, 24($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 36($sp) #Lee de la pila a@0 en 36 para assignar +sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 24($sp) #carga en $t1 lo que hay en 24 +lw $t2, 20($sp) #carga en $t2 lo que hay en 20 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 28($sp) #Pon en la posicion 28 el valor de $t3 #Inicio del paso 1 de una sequencia Block +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad y +sw $t1, 12($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@1 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 32($sp) #Lee de la pila b@0 en 32 para assignar +sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 12($sp) #carga en $t1 lo que hay en 12 +lw $t2, 8($sp) #carga en $t2 lo que hay en 8 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 16($sp) #Pon en la posicion 16 el valor de $t3 #Inicio del paso 2 de una sequencia Block +lw $t0, 40($sp) #Lee de la pila self en 40 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 #Limpia la pila +jr $ra #Final de la function init + +Complex_reflect_X: +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Complex_reflect_X #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad y +sw $t1, 16($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad y +sw $t1, 8($sp) #Salvando el valor de la propiedad y en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 16($sp) #carga en $t1 lo que hay en 16 +lw $t2, 12($sp) #carga en $t2 lo que hay en 12 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 1 de una sequencia Block +lw $t0, 24($sp) #Lee de la pila self en 24 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 #Limpia la pila +jr $ra #Final de la function reflect_X + +Complex_reflect_Y: +#Parametro self en stackpoiner + 28 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Complex_reflect_Y #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad x +sw $t1, 16($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad x +sw $t1, 8($sp) #Salvando el valor de la propiedad x en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 16($sp) #carga en $t1 lo que hay en 16 +lw $t2, 12($sp) #carga en $t2 lo que hay en 12 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 1 de una sequencia Block +lw $t0, 24($sp) #Lee de la pila self en 24 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 28 #Limpia la pila +jr $ra #Final de la function reflect_Y + +Complex_reflect_0: +#Parametro self en stackpoiner + 44 +addi $sp, $sp, -4 #Push local var step@block@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 compl@_unary@0 stackpointer 28 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 16 +addi $sp, $sp, -4 #Push local var compl@_unary@1 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 Complex_reflect_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad x +sw $t1, 32($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad x +sw $t1, 24($sp) #Salvando el valor de la propiedad x en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 32($sp) #carga en $t1 lo que hay en 32 +lw $t2, 28($sp) #carga en $t2 lo que hay en 28 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 36($sp) #Pon en la posicion 36 el valor de $t3 #Inicio del paso 1 de una sequencia Block +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad y +sw $t1, 16($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@1 #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila +lw $t1, 8($t0) #Buscando el valor de la propiedad y +sw $t1, 8($sp) #Salvando el valor de la propiedad y en la pila en el valor local compl@_unary@1 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 16($sp) #carga en $t1 lo que hay en 16 +lw $t2, 12($sp) #carga en $t2 lo que hay en 12 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 2 de una sequencia Block +lw $t0, 40($sp) #Lee de la pila self en 40 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result +lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 44 #Limpia la pila +jr $ra #Final de la function reflect_0 + + +IO_out_string: +li $v0, 4 +lw $a0, 0($sp) +syscall +lw $a0, 4($sp) +addi $sp, $sp, 8 +jr $ra diff --git a/tests/codegen/hello_world.mips b/tests/codegen/hello_world.mips new file mode 100644 index 000000000..47560dc29 --- /dev/null +++ b/tests/codegen/hello_world.mips @@ -0,0 +1,76 @@ +.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: +addi $sp, $sp, -4 #Push local var self stackpointer 20 +addi $sp, $sp, -4 #Push local var instance stackpointer 16 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 new_ctr_Main +#Allocate a una class Main puntero en sp + 12 +#atributo type_name en puntero + 0 +li $a0, 4 +li $v0, 9 +syscall +sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main +lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self +la $t0, Main +sw $t0, 8($sp) #Cargando el nombre del tipo desde el data +lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta +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 self en stackpoiner + 16 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var @result stackpointer 8 +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 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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 16 #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 From 1a0806e25b43c1209e8c24efd98da9911ac48cb2 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 16:58:10 -0500 Subject: [PATCH 58/91] dslnas --- .../codegen/v1_mips_generate/mipsgenerate.py | 6 +++- .../v1_mips_generate/mipsgenerate_ast.py | 31 +++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 024159426..b82f9be14 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -10,7 +10,8 @@ def __init__(self, errors) -> None: "IO_out_string": ASTR.Out_String, "IO_in_int":ASTR.In_Int, "IO_in_string":ASTR.In_String, - "IO_out_int":ASTR.Out_Int + "IO_out_int":ASTR.Out_Int, + "String_length":ASTR.Length } @visitor.on('node') @@ -192,6 +193,9 @@ def visit(self, node: AST.Call): 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_fun.keys() + if func_name in func and not func in self.func_list] + func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 4 result = [ ASTR.LW('$t0', f'{instance_stack}($sp)'), diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index b13f62998..3cbd68ba8 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -346,24 +346,21 @@ def __str__(self) -> str: ################################# Native Func Str ################################################ class Length: def __str__(self) -> str: - return """ - - legnht: - li $t0 , 0 - lw $s2 , ($sp) - loop: - lb $s0 , ($s2) - beq $s0 , $zero, END - add $t0 , $t0 ,1 - add $s2,$s2,4 - j loop - - - END: - move $s0 , $t0 - addi $sp, $sp, 4 - jr $ra + return """ +String_length: +li $t0 , 0 +lw $s2 , ($sp) + loop: + lb $s0 , ($s2) + beq $s0 , $zero, END + add $t0 , $t0 ,1 + add $s2,$s2,4 + j loop +END: + move $s0 , $t0 + addi $sp, $sp, 4 + jr $ra """ class Concat: From 048c09b88b31b9b1779e1993f9d821c32ce235e2 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 20:42:20 -0500 Subject: [PATCH 59/91] 3 test pass --- .../v0_type_data_code/type_data_code_ast.py | 5 +- .../type_data_code_visitor.py | 70 +++++++++++++------ .../codegen/v1_mips_generate/mipsgenerate.py | 27 +++++-- .../v1_mips_generate/mipsgenerate_ast.py | 16 +---- src/cool_compiler/types/build_in_types/str.py | 3 + 5 files changed, 77 insertions(+), 44 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py index fc6d890a7..6ca414b61 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py @@ -51,7 +51,7 @@ def try_add_data(self, name, value): try: _ = self.data[name] except KeyError: - self.data[name] = value + self.data[name] = Data(name, value) def add_data(self, name, value): index = 0 @@ -264,6 +264,9 @@ class VCall(Expression): class Call(Expression): pass +class SimpleCall(Expression): + pass + class Load(Expression): pass diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 99831ad70..02477ff14 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -1,10 +1,9 @@ from cool_compiler.cmp.scope import Scope from cool_compiler.types.cool_type_build_in_manager import OBJECT_NAME, CoolTypeBuildInManager -from cool_compiler.types.type import Type from ...cmp import visitor from ...semantic.v2_semantic_checking import semantic_checking_ast as AST from . import type_data_code_ast as ASTR -from .type_data_code_ast import result, super_value +from .type_data_code_ast import Arg, result, super_value CoolInt = CoolTypeBuildInManager().find("Int") CoolBool = CoolTypeBuildInManager().find("Bool") @@ -53,17 +52,29 @@ def visit(node, scope: Scope): @visitor.when(AST.Program) def visit(self, node: AST.Program, scope: Scope = None): self.program = ASTR.Program() + self.program.try_add_data('_______error______', 'runtime error') scope = Scope() _dictt = CoolTypeBuildInManager().dictt for key in _dictt.keys(): self.create_type(_dictt[key], scope) - self.new_type_func.expr_push(ASTR.Return('instance')) + self.new_type_func.expr_push(ASTR.Return('self')) self.program.add_func(self.new_type_func) 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.Arg('self')) + main.expr_push(ASTR.SimpleCall('new_ctr_Main')) + main.expr_push(ASTR.Arg('self')) + main.expr_push(ASTR.VCall(result, 'Main', 'main')) + main.expr_push(ASTR.Return(0)) + self.program.add_func(main) + return self.program def create_type(self, _type, scope): @@ -82,8 +93,9 @@ def create_type(self, _type, scope): 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}_parents'] + + [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) @@ -96,29 +108,23 @@ def visit(self, node: AST.CoolClass, scope: Scope): for feat in node.feature_list: self.visit(feat, self.class_scope) - if node.type.name == 'Main': - self.new_type_func.force_local(result, self.new_class_scope) - self.new_type_func.expr_push(ASTR.Arg('instance')) - self.new_type_func.expr_push(ASTR.VCall(result, 'Main', 'main')) - self.new_type_func.expr_push(ASTR.Return(0)) - else: - self.new_type_func.expr_push(ASTR.Return('instance')) + self.new_type_func.expr_push(ASTR.Return('self')) self.program.add_func(self.new_type_func) 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_local('self', self.new_class_scope) - self.new_type_func.force_local('instance', self.new_class_scope) + self.new_type_func.force_parma('self', self.new_class_scope) tn = self.new_type_func.local_push('type_name', self.new_class_scope) - self.new_type_func.expr_push(ASTR.ALLOCATE('instance', _type.name)) - self.new_type_func.expr_push(ASTR.Comment(f'Reservando memoria para una instancia de tipo {_type.name}')) - self.new_type_func.expr_push(ASTR.Assign('self', 'instance')) + + 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.Load(tn, _type.name)) self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) - self.new_type_func.expr_push(ASTR.SetAttr('instance', 'type_name', tn)) + self.new_type_func.expr_push(ASTR.SetAttr('self', 'type_name', tn)) self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) @visitor.when(AST.AtrDef) @@ -132,7 +138,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): attr_name = self.new_type_func.local_push(node.name, self.new_class_scope) exp_list = self.visit(node.expr, self.new_class_scope) exp_list[-1].set_value(attr_name) - exp_list.append(ASTR.SetAttr('instance', self.currentType.attr[node.name], attr_name)) + exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.name], attr_name)) exp_list.append(ASTR.Comment(f"Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}")) self.new_type_func.expr += exp_list self.currentFunc = save_current_func @@ -220,7 +226,6 @@ def visit(self, node: AST.StaticDispatch, scope: Scope): param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) return param_expr_list - @visitor.when(AST.Assing) def visit(self, node: AST.Assing, scope: Scope): exp_list = self.visit(node.expr, scope) @@ -430,7 +435,12 @@ def visit(self, node: AST.Equals, scope: Scope): @visitor.when(AST.New) def visit(self, node: AST.New, scope: Scope): - return [ASTR.New(super_value, node.item.name)] + instance = self.currentFunc.local_push(f'instance_{node.item.name}', scope) + return [ + ASTR.ALLOCATE(instance, node.item.name), + ASTR.Arg(instance), + ASTR.New(super_value, node.item.name) + ] def unary_op(self, name, node, astr_node, scope: Scope): op = self.currentFunc.local_push(f'{name}@_unary', scope) @@ -451,9 +461,10 @@ def visit(self, node: AST.Neg, scope: Scope): def visit(self, node: AST.Void, scope: Scope): op_1 = self.currentFunc.local_push('void@_op', scope) null = self.currentFunc.local_push('void@_null', scope) - unary_list = self.unary_op('void', node, ASTR.Complemnet, scope) + unary_list = self.visit(node.item, scope) unary_list[-1].set_value(op_1) + self.program.try_add_data('NULL', 'null') return ( [ASTR.Load(null, "NULL")] + unary_list @@ -482,4 +493,17 @@ def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: @visitor.when(AST.Str) def visit(self, node: AST.Str, scope: Scope): name = self.program.add_data('string', node.item) - return [ASTR.Load(super_value, name)] \ No newline at end of file + string_value = self.currentFunc.local_push('value_string', scope) + string_type = self.currentFunc.local_push('type_string', scope) + string_instance = self.currentFunc.local_push('string_instance', scope) + + return [ + ASTR.Load(string_value, name), + ASTR.Comment("Carga la referecia a string"), + ASTR.ALLOCATE(string_instance, 'String'), + ASTR.SetAttr(string_instance, 'String@value', string_value), + ASTR.Comment(f"Setear la propiedad value al string en la variable {string_value}"), + ASTR.SetAttr(string_instance, 'type_name', string_type), + ASTR.Comment(f"Setear la propiedad type_name al string en la variable {string_value}"), + ASTR.Assign(super_value, string_instance), + ] \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index b82f9be14..a98b08d6b 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -5,13 +5,18 @@ class MipsGenerate: def __init__(self, errors) -> None: - self.func_list = ['new_ctr_Main'] + self.func_list = ['main'] self.native_fun = { "IO_out_string": ASTR.Out_String, "IO_in_int":ASTR.In_Int, "IO_in_string":ASTR.In_String, "IO_out_int":ASTR.Out_Int, - "String_length":ASTR.Length + "String_length":ASTR.Length, + "String_concat":1, + "String_substr":1, + "Object_copy":1, + "Object_type_name":1, + "Object_abort":1 } @visitor.on('node') @@ -31,15 +36,20 @@ def visit(self, node: AST.Program): for func in self.func_list: if func in self.native_fun: - self.new_program.func[func] = self.native_fun[func]() + self.new_program.func[func] = self.native_fun[func]() else: self.visit(self.cil_func[func]) + for func in list(self.cil_func.keys()) + list(self.native_fun.keys()): + if func in self.func_list: continue + self.new_program.func[func] = ASTR.Func(func) + self.new_program.func[func].cmd += [ASTR.Comment("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 if not node.name == 'new_ctr_Main' else 'main') + new_func = ASTR.Func(node.name) self.stack = Stack(node) for param in node.param: @@ -94,7 +104,8 @@ def visit(self, node: AST.ALLOCATE): ASTR.LI('$a0', _len), ASTR.LI('$v0', 9), ASTR.SysCall(), - ASTR.SW('$v0', f'{stack_plus}($sp)') + ASTR.SW('$v0', f'{stack_plus}($sp)'), + ASTR.Comment(f'Guardando en la pila el pintero de la instancia de la clase {_type}') ] @visitor.when(AST.GetAttr) @@ -168,6 +179,10 @@ def call(self, func, memory_dest): ASTR.SW('$s0', f'{stack_plus}($sp)' ), ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), ] + @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: -2] @visitor.when(AST.VCall) def visit(self, node: AST.VCall): @@ -196,7 +211,7 @@ def visit(self, node: AST.Call): self.func_list += [func for func in self.native_fun.keys() if func_name in func and not func in self.func_list] - func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 4 + func_address = self.cil_type[_type].method_list.index(func_name) * 4 + 12 result = [ ASTR.LW('$t0', f'{instance_stack}($sp)'), ASTR.Comment(f"Sacando la instancia de la pila (en {instance_stack - self.stack.local_push * 4}) de una clase que hereda de {_type}"), diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 3cbd68ba8..74c405ae0 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -261,10 +261,10 @@ class Out_String: def __str__(self) -> str: return """ IO_out_string: +lw $t0 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 -lw $a0, 0($sp) +lw $a0, 4($t0) #Pintando la propiedad value del string syscall -lw $a0, 4($sp) addi $sp, $sp, 8 jr $ra""" @@ -275,18 +275,6 @@ def __str__(self) -> str: li $v0, 1 lw $a0, 0($sp) syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 -jr $ra""" - -class Out_Float: - def __str__(self) -> str: - return """ -IO_out_Float: -li $v0, 2 -lw $a0, 0($sp) -syscall -lw $a0, 4($sp) addi $sp, $sp, 8 jr $ra""" diff --git a/src/cool_compiler/types/build_in_types/str.py b/src/cool_compiler/types/build_in_types/str.py index 42377a4d4..d3ceae608 100755 --- a/src/cool_compiler/types/build_in_types/str.py +++ b/src/cool_compiler/types/build_in_types/str.py @@ -13,6 +13,9 @@ def __init__(self): def is_shield(self): return True + def value(self): + self.define_attribute("value", self) + def length(self): self.define_method("length", [], Int()) From f6b0457cdb652a9630cda73621ec69f93f02c288 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 21:00:08 -0500 Subject: [PATCH 60/91] refactor type name --- .../type_data_code_visitor.py | 1 + .../codegen/v1_mips_generate/mipsgenerate.py | 2 +- .../v1_mips_generate/mipsgenerate_ast.py | 21 ++++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 02477ff14..0f397a85b 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -503,6 +503,7 @@ def visit(self, node: AST.Str, scope: Scope): ASTR.ALLOCATE(string_instance, 'String'), ASTR.SetAttr(string_instance, 'String@value', string_value), ASTR.Comment(f"Setear la propiedad value al string en la variable {string_value}"), + ASTR.Load(string_type, 'String'), ASTR.SetAttr(string_instance, 'type_name', string_type), ASTR.Comment(f"Setear la propiedad type_name al string en la variable {string_value}"), ASTR.Assign(super_value, string_instance), diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index a98b08d6b..e2b4d8776 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -15,7 +15,7 @@ def __init__(self, errors) -> None: "String_concat":1, "String_substr":1, "Object_copy":1, - "Object_type_name":1, + "Object_type_name":ASTR.Type_Name, "Object_abort":1 } diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 74c405ae0..fa8356dfd 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -429,8 +429,23 @@ def __str__(self) -> str: class Type_Name: def __str__(self) -> str: return """ - El nombre del tipo de método devuelve un -cadena con el nombre de la clase del objeto -""" +IO_out_string: +lw $t0 0($sp) #Guarda en $t0 la direccion del self +lw $t1 0($t0) #La primera posicion de self es la propiedad type_name +lw $t2 0($t1) #La propiedad type_name apunta a la definicion del tipo +la $t3 0($t2) #La definicion de tipo tiene en la primera poscion su nombre +#Allocate a una class String puntero en sp + 12 +#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 $t4, String +sw $t4, 0($v0) # Asigna el tipo String al string +sw $t3, 4($v0) # Asigan el nombre de la clase a la propiededa value del string + +addi $sp, $sp, 4 +move $s0, $v0 +jr $ra""" From 3d0884df3ed1ef751b854d8b78a476c714692b1f Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 21:40:33 -0500 Subject: [PATCH 61/91] al2 --- src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 024159426..575e44bd2 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -10,7 +10,8 @@ def __init__(self, errors) -> None: "IO_out_string": ASTR.Out_String, "IO_in_int":ASTR.In_Int, "IO_in_string":ASTR.In_String, - "IO_out_int":ASTR.Out_Int + "IO_out_int":ASTR.Out_Int, + "String_length":ASTR.Length } @visitor.on('node') From 371ebeff9d77326a6ff58685af149525770ea76b Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 24 Feb 2022 21:41:12 -0500 Subject: [PATCH 62/91] al22 --- .../v1_mips_generate/mipsgenerate_ast.py | 2 +- src/test.mips | 408 ++++++++++++------ 2 files changed, 270 insertions(+), 140 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 6316f57e0..6ab6e87d8 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -350,7 +350,7 @@ class Length: def __str__(self) -> str: return """ - legnht: + String_length: li $t0 , 0 lw $s2 , ($sp) loop: diff --git a/src/test.mips b/src/test.mips index ddc81d92e..94bdcb412 100644 --- a/src/test.mips +++ b/src/test.mips @@ -12,22 +12,24 @@ 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, Main_fib, -string_0: .asciiz "Enter n to find nth fibonacci number!\n" -string_1: .asciiz "\n" +Main: .word 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 20 -addi $sp, $sp, -4 #Push local var instance stackpointer 16 -addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -addi $sp, $sp, -4 #Push local var $ra stackpointer 4 +addi $sp, $sp, -4 #Push local var self stackpointer 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_name en puntero + 0 -li $a0, 4 +#atributo i en puntero + 4 +li $a0, 8 li $v0, 9 syscall sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main @@ -47,60 +49,82 @@ li $v0, 10 syscall Main_main: -#Parametro self en stackpoiner + 36 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 +#Parametro self en stackpoiner + 48 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var result@assing@i@0 stackpointer 36 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 32 addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 24 -addi $sp, $sp, -4 #Push local var param_0_to_fib@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 cond@if_else@0 stackpointer 24 +addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 20 +addi $sp, $sp, -4 #Push local var result@if@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 @result stackpointer 8 -addi $sp, $sp, -4 #Push local var $ra stackpointer 4 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 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 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a compl@_unary@0 #Fin de la expresion lista para ser asignada +lw $t0, 48($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 36($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto +lw $t0, 48($sp) #Buscando la instancia de la clase Main en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad i +sw $t1, 44($sp) #Salvando el valor de la propiedad i en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block la $t0, string_0 -sw $t0, 24($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 32($sp) #Saca de la pila self +sw $t0, 28($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 48($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, 28($sp) #Saca de la pila param_0_to_out_string@0 +lw $t0, 32($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, 28($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block -lw $t0, 32($sp) #Saca de la pila self +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +lw $t0, 48($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 in_int -jal IO_in_int #Call a la function IO_in_int -sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch fib -lw $t0, 32($sp) #Saca de la pila self +sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch in_string +jal IO_in_string #Call a la function IO_in_string +sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal +lw $t0, 48($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 fib -lw $t0, 20($sp) #Saca de la pila param_0_to_fib@0 +sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch pal +lw $t0, 24($sp) #Saca de la pila param_0_to_pal@0 addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_fib@0 #Agrega a la pila el paramentro 1 al StaticDispatch fib -jal Main_fib #Call a la function Main_fib -sw $s0, 12($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch out_int -lw $t0, 32($sp) #Saca de la pila self +sw $t0, 0($sp) #Mete para la pila param_0_to_pal@0 #Agrega a la pila el paramentro 1 al StaticDispatch pal +jal Main_pal #Call a la function Main_pal +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 24($sp) #Cargar el valor de la pos 24 a $t1 pa comparar +beq $t0 $t1 then_Main_main_0 #if $t1==$t0 then jump then_Main_main_0 #Else case +la $t0, string_1 +sw $t0, 12($sp) #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 48($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_int -lw $t0, 16($sp) #Saca de la pila param_0_to_out_int@0 +sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch out_string +lw $t0, 16($sp) #Saca de la pila param_0_to_out_string@1 addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_out_int@0 #Agrega a la pila el paramentro 1 al StaticDispatch out_int -jal IO_out_int #Call a la function IO_out_int -sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block -la $t0, string_1 +sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #Agrega a la pila el paramentro 1 al StaticDispatch out_string +jal IO_out_string #Call a la function IO_out_string +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +j fin_Main_main_0 #Salta para f{label} +then_Main_main_0 : #Crea el label then_Main_main_0 #Then case +la $t0, string_2 sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 32($sp) #Saca de la pila self +lw $t0, 48($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@1 +lw $t0, 12($sp) #Saca de la pila param_0_to_out_string@2 addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #Agrega a la pila el paramentro 1 al StaticDispatch out_string +sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@2 #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 +sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +fin_Main_main_0 : #Crea el label fin_Main_main_0 #Fin de un If +lw $t0, 16($sp) #Lee de la pila result@if@0 en 16 para assignar +sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 36 #Limpia la pila +addi $sp, $sp, 52 #Limpia la pila jr $ra #Final de la function main @@ -112,113 +136,219 @@ lw $a0, 4($sp) addi $sp, $sp, 8 jr $ra -IO_in_int: -li $v0,5 +IO_in_string: +li $v0,8 +li $a1 , 10000 syscall -move $s0 , $v0 -addi $sp ,$sp ,4 +move $s0 , $a0 +addi $sp, $sp, 4 jr $ra -Main_fib: -#Parametro self en stackpoiner + 96 -#Parametro i@0 en stackpoiner + 92 -addi $sp, $sp, -4 #Push local var a stackpointer 88 -addi $sp, $sp, -4 #Push local var b stackpointer 84 -addi $sp, $sp, -4 #Push local var c stackpointer 80 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 76 -addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 72 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 68 -addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 60 -addi $sp, $sp, -4 #Push local var result@assing@c@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var step@block@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 result@assing@i@0 stackpointer 40 -addi $sp, $sp, -4 #Push local var step@block@3 stackpointer 36 -addi $sp, $sp, -4 #Push local var result@assing@b@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var result@assing@a@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var neg@_unary@0 stackpointer 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 @result stackpointer 8 -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 Main_fib -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 84($sp) #Escribe en la pila el numero que se le asigno a a #Fin de la asignacion Let a +Main_pal: +#Parametro self en stackpoiner + 132 +#Parametro s@0 en stackpoiner + 128 +addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 124 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 120 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 116 +addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 112 +addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 108 +addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 104 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 100 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_to_call_length@1 stackpointer 92 +addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 88 +addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 84 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 80 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 76 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 68 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@1 stackpointer 60 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var instance_to_call_length@2 stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 44 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 40 +addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 36 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@2 stackpointer 32 +addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 28 +addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var instance_to_call_length@3 stackpointer 16 +addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var param_0_to_pal@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_pal +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 112($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length +lw $t0, 112($sp) #Saca de la pila instance_to_call_length@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_length@0 +lw $t0, 116($sp) #Sacando la instancia de la pila (en 112) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length + +li $v0 , 10 +syscall + +jal $t3 #Call a la function $t3 +sw $s0, 120($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 80($sp) #Escribe en la pila el numero que se le asigno a b #Fin de la asignacion Let b +sw $t0, 116($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 120($sp) #carga en $t1 lo que hay en 120 +lw $t2, 116($sp) #carga en $t2 lo que hay en 116 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 124($sp) #Pon en la posicion 124 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 124($sp) #Cargar el valor de la pos 124 a $t1 pa comparar +beq $t0 $t1 then_Main_pal_0 #if $t1==$t0 then jump then_Main_pal_0 #Else case +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 92($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@1 #Fin de la exprecion previa al Dispatch length +lw $t0, 92($sp) #Saca de la pila instance_to_call_length@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_length@1 +lw $t0, 96($sp) #Sacando la instancia de la pila (en 92) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 #Call a la function $t3 +sw $s0, 100($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 96($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq +lw $t1, 100($sp) #carga en $t1 lo que hay en 100 +lw $t2, 96($sp) #carga en $t2 lo que hay en 96 +seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 +sw $t3, 104($sp) #Pon en la posicion 104 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +li $t0, 1 #Cargar 1 a $t0 pa comparar +lw $t1, 104($sp) #Cargar el valor de la pos 104 a $t1 pa comparar +beq $t0 $t1 then_Main_pal_1 #if $t1==$t0 then jump then_Main_pal_1 #Else case +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 76($sp) #Escribe en la pila el numero que se le asigno a c #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 #Salta para f{label} -while_back_0 : #Crea el label while_back_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 84($sp) #Lee de la pila a en 84 para assignar -sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum -lw $t0, 80($sp) #Lee de la pila b en 80 para assignar -sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum -lw $t0, 60($sp) #poner en registro $t0 lo que hay en 60 -lw $t1, 56($sp) #poner en registro $t1 lo que hay en 56 -add $t0, $t0, $t1 #en $t0 pon el resultado de la suma -sw $t0, 52($sp) #poner en la posicion 52 el resultado #Fin de la expresion lista para ser asignada -lw $t0, 52($sp) #Lee de la pila result@assing@c@0 en 52 para assignar -sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a c -lw $t0, 76($sp) #Lee de la pila c en 76 para assignar -sw $t0, 64($sp) #Escribe en la pila el valor que se le asigno a step@block@1 #Inicio del paso 1 de una sequencia Block -lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar -sw $t0, 44($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest +sw $t0, 68($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 64($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr +lw $t0, 72($sp) #Saca de la pila instance_to_call_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@0 +lw $t0, 72($sp) #Saca de la pila param_0_to_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_substr@0 +lw $t0, 72($sp) #Saca de la pila param_1_to_substr@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_substr@0 +lw $t0, 84($sp) #Sacando la instancia de la pila (en 72) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 #Call a la function $t3 +li $s0 ,3 +sw $s0, 80($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@1 #Fin de la exprecion previa al Dispatch substr +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@2 #Fin de la exprecion previa al Dispatch length +lw $t0, 48($sp) #Saca de la pila instance_to_call_length@2 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_length@2 +lw $t0, 52($sp) #Sacando la instancia de la pila (en 48) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 #Call a la function $t3 +sw $s0, 56($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 44($sp) #poner en registro $t0 lo que hay en 44 -lw $t1, 40($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 56($sp) #poner en registro $t0 lo que hay en 56 +lw $t1, 52($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 36($sp) #poner en 36 el resultado de la suma #Fin de la expresion lista para ser asignada -lw $t0, 36($sp) #Lee de la pila result@assing@i@0 en 36 para assignar -sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a i@0 -lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar -sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a step@block@2 #Inicio del paso 2 de una sequencia Block -lw $t0, 84($sp) #Lee de la pila a en 84 para assignar -sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a result@assing@b@0 #Fin de la expresion lista para ser asignada -lw $t0, 28($sp) #Lee de la pila result@assing@b@0 en 28 para assignar -sw $t0, 80($sp) #Escribe en la pila el valor que se le asigno a b -lw $t0, 80($sp) #Lee de la pila b en 80 para assignar -sw $t0, 32($sp) #Escribe en la pila el valor que se le asigno a step@block@3 #Inicio del paso 3 de una sequencia Block -lw $t0, 76($sp) #Lee de la pila c en 76 para assignar -sw $t0, 24($sp) #Escribe en la pila el valor que se le asigno a result@assing@a@0 #Fin de la expresion lista para ser asignada -lw $t0, 24($sp) #Lee de la pila result@assing@a@0 en 24 para assignar -sw $t0, 84($sp) #Escribe en la pila el valor que se le asigno a a -lw $t0, 84($sp) #Lee de la pila a en 84 para assignar -sw $t0, 68($sp) #Escribe en la pila el valor que se le asigno a result@while@0 -while_cond_0 : #Crea el label while_cond_0 #Fin del cuerpo e inicio de la condicion de un While -lw $t0, 88($sp) #Lee de la pila i@0 en 88 para assignar -sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 12($sp) #carga en $t1 lo que hay en 12 -lw $t2, 8($sp) #carga en $t2 lo que hay en 8 +sw $t0, 44($sp) #poner en 44 el resultado de la suma #Fin del paramentro 0 al Dispatch substr +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@1 #Fin del paramentro 1 al Dispatch substr +lw $t0, 60($sp) #Saca de la pila instance_to_call_substr@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@1 +lw $t0, 48($sp) #Saca de la pila param_0_to_substr@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_substr@1 +lw $t0, 48($sp) #Saca de la pila param_1_to_substr@1 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_substr@1 +lw $t0, 72($sp) #Sacando la instancia de la pila (en 60) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 #Call a la function $t3 +sw $s0, 76($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq +lw $t1, 80($sp) #carga en $t1 lo que hay en 80 +lw $t2, 76($sp) #carga en $t2 lo que hay en 76 seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 16($sp) #Pon en la posicion 16 el valor de $t3 -lw $t0, 16($sp) #Carga la pos 16 en $t0 -addi $t1, $t0, -1 #$t1 = $t0 + (-1) -mul $t0, $t1, -1 #$t0 = $t1 * (-1) -sw $t0, 20($sp) #poner en la posicion 20 el contenido de $t0 +sw $t3, 84($sp) #Pon en la posicion 84 el valor de $t3 #Fin de la evaluacion de la condicion de un IF li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 20($sp) #Cargar el valor de la pos 20 a $t1 pa comparar -beq $t0 $t1 while_back_0 #if $t1==$t0 then jump while_back_0 #Fin de la condicion de un While -lw $t0, 92($sp) #Lee de la pila self en 92 para assignar -sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a step@block@0 #Inicio del paso 1 de una sequencia Block -lw $t0, 76($sp) #Lee de la pila c en 76 para assignar +lw $t1, 84($sp) #Cargar el valor de la pos 84 a $t1 pa comparar +beq $t0 $t1 then_Main_pal_2 #if $t1==$t0 then jump then_Main_pal_2 #Else case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 36($sp) #Escribe en la pila el numero que se le asigno a result@if@2 +j fin_Main_pal_2 #Salta para f{label} +then_Main_pal_2 : #Crea el label then_Main_pal_2 #Then case +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 32($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@2 #Fin de la exprecion previa al Dispatch substr +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@2 #Fin del paramentro 0 al Dispatch substr +lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar +sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@3 #Fin de la exprecion previa al Dispatch length +lw $t0, 16($sp) #Saca de la pila instance_to_call_length@3 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_length@3 +lw $t0, 20($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +jal $t3 #Call a la function $t3 +sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +li $t0, 2 #Guarda el numbero que se va a asignar +sw $t0, 20($sp) #Escribe en la pila el numero que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest +lw $t0, 24($sp) #poner en registro $t0 lo que hay en 24 +lw $t1, 20($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la suma +sw $t0, 12($sp) #poner en 12 el resultado de la suma #Fin del paramentro 1 al Dispatch substr +lw $t0, 32($sp) #Saca de la pila instance_to_call_substr@2 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@2 +lw $t0, 32($sp) #Saca de la pila param_0_to_substr@2 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_substr@2 +lw $t0, 20($sp) #Saca de la pila param_1_to_substr@2 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_1_to_substr@2 +lw $t0, 44($sp) #Sacando la instancia de la pila (en 32) de una clase que hereda de String +lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String +lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +jal $t3 #Call a la function $t3 +sw $s0, 8($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal +lw $t0, 132($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 pal +lw $t0, 12($sp) #Saca de la pila param_0_to_pal@0 +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila param_0_to_pal@0 #Agrega a la pila el paramentro 1 al StaticDispatch pal +jal Main_pal #Call a la function Main_pal +sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +fin_Main_pal_2 : #Crea el label fin_Main_pal_2 #Fin de un If +lw $t0, 36($sp) #Lee de la pila result@if@2 en 36 para assignar +sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a result@if@1 +j fin_Main_pal_1 #Salta para f{label} +then_Main_pal_1 : #Crea el label then_Main_pal_1 #Then case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a result@if@1 +fin_Main_pal_1 : #Crea el label fin_Main_pal_1 #Fin de un If +lw $t0, 88($sp) #Lee de la pila result@if@1 en 88 para assignar +sw $t0, 108($sp) #Escribe en la pila el valor que se le asigno a result@if@0 +j fin_Main_pal_0 #Salta para f{label} +then_Main_pal_0 : #Crea el label then_Main_pal_0 #Then case +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 108($sp) #Escribe en la pila el numero que se le asigno a result@if@0 +fin_Main_pal_0 : #Crea el label fin_Main_pal_0 #Fin de un If +lw $t0, 108($sp) #Lee de la pila result@if@0 en 108 para assignar sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 96 #Limpia la pila -jr $ra #Final de la function fib +addi $sp, $sp, 136 #Limpia la pila +jr $ra #Final de la function pal - -IO_out_int: -li $v0, 1 -lw $a0, 0($sp) -syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 -jr $ra From 191eb3b808e87dd3bdf4afc26164405acbf6d67b Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 21:48:28 -0500 Subject: [PATCH 63/91] mira a ver --- .../codegen/v1_mips_generate/mipsgenerate.py | 4 +- .../v1_mips_generate/mipsgenerate_ast.py | 44 ++++++++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index e2b4d8776..79df3be6b 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -14,9 +14,9 @@ def __init__(self, errors) -> None: "String_length":ASTR.Length, "String_concat":1, "String_substr":1, - "Object_copy":1, + "Object_copy": ASTR.Copy, "Object_type_name":ASTR.Type_Name, - "Object_abort":1 + "Object_abort": ASTR.Abort } @visitor.on('node') diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index fa8356dfd..47cc54e44 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -294,22 +294,13 @@ class In_Int: def __str__(self) -> str: return """ IO_in_int: -li $v0,5 +li $v0, 5 syscall move $s0 , $v0 addi $sp, $sp, 4 jr $ra """ -class In_Float: - def __str__(self) -> str: - return """ -In_Float: -li $v0,6 -syscall -move $s0 , $a0 -""" - class Contain: def __str__(self) -> str: return """ @@ -414,16 +405,36 @@ def __str__(self) -> str: class Copy: def __str__(self) -> str: return """ - El método de copia, sabemos que el resultado de la copia es el -igual que el tipo del autoparámetro - - +Object_copy: +lw $t0, 0($sp) #Guarda en $t0 self +lw $t1, 0($t0) #Guarda definicion del tipo +lw $t3, 4($t1) #En la segunda posicion la definicion de tipo contiene el +move $a0, $t3 #tamaño que ocupa en la pila +li $v0, 9 +syscall #En $v0 la nueva instancia +move $s0, $v0 +copy_loop: + beq $t3, $zero, end_copy + lw $t1, 0($t0) + sw $t1, 0($v0) + addi $t3, $t3, -4 + add $t0, $t0, 4 + add $v0, $v0, 4 + jr copy_loop +end_copy: +addi $sp, $sp, 4 +jr $ra """ class Abort: def __str__(self) -> str: return """ - El método abortar detiene la ejecución del programa con un mensaje de error. +Object_abort: +li $v0, 4 # system call #4 - print string +la $a0, _______error______ +syscall +li $v0, 10 +syscall # execute """ class Type_Name: @@ -446,6 +457,7 @@ def __str__(self) -> str: addi $sp, $sp, 4 move $s0, $v0 -jr $ra""" +jr $ra +""" From 13f90e60b96d6704679621de5a05f18cf3f5ce13 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Thu, 24 Feb 2022 22:03:52 -0500 Subject: [PATCH 64/91] los que faltan --- .../type_data_code_visitor.py | 18 ++++++++---- .../codegen/v1_mips_generate/mipsgenerate.py | 29 +++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 0f397a85b..202423c69 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -53,6 +53,8 @@ def visit(node, scope: Scope): def visit(self, node: AST.Program, scope: Scope = None): self.program = ASTR.Program() self.program.try_add_data('_______error______', 'runtime error') + self.program.try_add_data('_______null_______', 'null') + scope = Scope() _dictt = CoolTypeBuildInManager().dictt @@ -142,7 +144,14 @@ def visit(self, node: AST.AtrDef, scope: Scope): exp_list.append(ASTR.Comment(f"Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}")) self.new_type_func.expr += exp_list self.currentFunc = save_current_func - + elif node.type in [CoolInt, CoolBool]: + default = self.new_type_func.local_push('default_prop', self.new_class_scope) + self.new_type_func.expr_push(ASTR.Assign(default, 0)) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], default)) + else: + null = self.new_type_func.local_push('null') + self.new_type_func.expr_push(ASTR.Load(null, '_______null_______')) + self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], null)) @visitor.when(AST.FuncDef) def visit(self, node: AST.FuncDef, scope: Scope): @@ -431,7 +440,7 @@ def visit(self, node: AST.Equals, scope: Scope): if node.static_type == CoolStr: return self.binary_op('str_eq', node, ASTR.CmpStr, scope) - return self.binary_op('req_eq', node, ASTR.CmpRef, scope) + return self.binary_op('req_eq', node, ASTR.CmpInt, scope) @visitor.when(AST.New) def visit(self, node: AST.New, scope: Scope): @@ -464,11 +473,10 @@ def visit(self, node: AST.Void, scope: Scope): unary_list = self.visit(node.item, scope) unary_list[-1].set_value(op_1) - self.program.try_add_data('NULL', 'null') return ( - [ASTR.Load(null, "NULL")] + [ASTR.Load(null, "_______null_______")] + unary_list - + [ASTR.CmpRef(super_value, null, op_1)] + + [ASTR.CmpInt(super_value, null, op_1)] ) @visitor.when(AST.Id) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 79df3be6b..3def0b45e 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -179,6 +179,7 @@ def call(self, func, memory_dest): ASTR.SW('$s0', f'{stack_plus}($sp)' ), ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), ] + @visitor.when(AST.SimpleCall) def visit(self, node: AST.SimpleCall): if not node.x in self.func_list: self.func_list.append(node.x) @@ -276,6 +277,10 @@ def visit(self,node:AST.CmpInt): ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") ] + @visitor.when(AST.CmpStr) + def visit(self, node: AST.CmpStr): + pass + @visitor.when(AST.Assign) def visit(self,node:AST.Assign): memory_dest = node.x @@ -318,7 +323,11 @@ def visit(self,node:AST.Neg): ] - @ visitor.when(AST.Sum) + @visitor.when(AST.Complemnet) + def visit(self, node: AST.Complemnet): + pass + + @visitor.when(AST.Sum) def visit(self,node:AST.Sum): memory_dest=node.x memory_op1=node.y @@ -338,7 +347,7 @@ def visit(self,node:AST.Sum): ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el resultado ") ] - @ visitor.when(AST.Rest) + @visitor.when(AST.Rest) def visit(self,node:AST.Rest): memory_dest=node.x memory_op1=node.y @@ -359,6 +368,22 @@ def visit(self,node:AST.Rest): ] + @visitor.when(AST.Mult) + def visit(self, node: AST.Mult): + pass + + @visitor.when(AST.Div) + def visit(self, node: AST.Div): + pass + + @visitor.when(AST.Less) + def visit(self, node: AST.Less): + pass + + @visitor.when(AST.LessOrEqual) + def visit(self, node: AST.LessOrEqual): + pass + @ visitor.when(AST.IfGoTo) def visit(self,node:AST.IfGoTo): memory_cmp = node.x From fff7ec94766d30ca832646f94d8f360ace3917e8 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 09:46:06 -0500 Subject: [PATCH 65/91] ultimodia --- src/cool_compiler/__main__.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 142 ++++++++++++++++-- .../v1_mips_generate/mipsgenerate_ast.py | 65 +++++--- 3 files changed, 176 insertions(+), 33 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 3a1b97a12..df42ae3ca 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +#path = "test.cl" with open(path, 'r') as _file: text = _file.read() diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index f47bce9f6..d245d80db 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -11,8 +11,8 @@ def __init__(self, errors) -> None: "IO_in_int":ASTR.In_Int, "IO_in_string":ASTR.In_String, "IO_out_int":ASTR.Out_Int, - "String_length":ASTR.Length "String_length":ASTR.Length, + #"String_length":ASTR.Length, "String_concat":1, "String_substr":1, "Object_copy": ASTR.Copy, @@ -180,6 +180,7 @@ def call(self, func, memory_dest): ASTR.SW('$s0', f'{stack_plus}($sp)' ), ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), ] + @visitor.when(AST.SimpleCall) def visit(self, node: AST.SimpleCall): if not node.x in self.func_list: self.func_list.append(node.x) @@ -268,20 +269,82 @@ def visit(self,node:AST.CmpInt): stack_plus_dest = self.stack.index(memory_dest) return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , - ASTR.Comment(f"carga en $t1 lo que hay en {stack_plus_opr_1} "), + ASTR.Comment(f"carga en $t1 {dir_cmp1} de la pos {stack_plus_opr_1} "), ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"carga en $t2 lo que hay en {stack_plus_opr_2} "), + ASTR.Comment(f"carga en $t2 {dir_cmp2} de la pos {stack_plus_opr_2} "), ASTR.SEQ ('$t3','$t2','$t1'), - ASTR.Comment("$t3 = $t2 == $ t1" ), + ASTR.Comment(f"$t3 = {dir_cmp1} $t0 == {dir_cmp2} $ t1" ), ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") ] + @visitor.when(AST.CmpStr) + def visit(self,node:AST.CmpStr): + memory_dest = node.x + memory_str1 = node.y + memory_str2 = node.z + + stack_plus_str1 = self.stack.index(memory_str1) + stack_plus_str2 = self.stack.index(memory_str2) + stack_plus_dest = self.stack.index(memory_dest) + + return [ASTR.LW('$a0',f'{stack_plus_str1}'), + ASTR.Comment(f"Si no viene como funcion pon el string {memory_str1} de la posicion {stack_plus_str1}"), + ASTR.LW('$a1',f'{stack_plus_str2}'), + ASTR.Comment(f"Si no viene como funcion pon el string {memory_str2} de la posicion {stack_plus_str2}"), + ASTR.Compare_String(), + ASTR.SW ('$s0', f'{stack_plus_dest}'), + ASTR.Comment(f"Como no retorna sigue lineal entoces en $s0 esta el resultado y se pone en {stack_plus_dest}") + + + ] + + @visitor.when(AST.Less) + def visit (self,node:AST.Less): + memory_dest = node.x + dir_cmp1 = node.y + dir_cmp2 = node.z + + stack_plus_opr_1 = self.stack.index(dir_cmp1) + stack_plus_opr_2 = self.stack.index(dir_cmp2) + stack_plus_dest = self.stack.index(memory_dest) + + return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , + ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), + ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), + ASTR.SLT ('$t3','$t2','$t1'), + ASTR.Comment("$t3 = $t2 < $ t1" ), + ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), + ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") + ] + + @visitor.when(AST.LessOrEqual) + def visit (self,node:AST.LessOrEqual): + memory_dest = node.x + dir_cmp1 = node.y + dir_cmp2 = node.z + + stack_plus_opr_1 = self.stack.index(dir_cmp1) + stack_plus_opr_2 = self.stack.index(dir_cmp2) + stack_plus_dest = self.stack.index(memory_dest) + + return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , + ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), + ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), + ASTR.SLE ('$t3','$t2','$t1'), + ASTR.Comment("$t3 = $t2 <= $ t1" ), + ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), + ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") + ] + @visitor.when(AST.Assign) def visit(self,node:AST.Assign): memory_dest = node.x dir_value = node.y stack_plus = self.stack.index(memory_dest) + print(dir_value) if type(dir_value) in [type(int()), type(float())]: return [ @@ -330,9 +393,9 @@ def visit(self,node:AST.Sum): stack_plus_opr_2 = self.stack.index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), + ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"poner en registro $t1 lo que hay en {stack_plus_opr_2}"), + ASTR.Comment(f"poner en registro $t1 {memory_op2} lo que hay en {stack_plus_opr_2}"), ASTR.Add('$t0' , '$t0','$t1'), ASTR.Comment("en $t0 pon el resultado de la suma"), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), @@ -350,9 +413,9 @@ def visit(self,node:AST.Rest): stack_plus_opr_2 = self.stack.index(memory_op2) return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 lo que hay en {stack_plus_opr_1}"), + ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment("poner en registro $t1 lo que hay en f'{stack_plus_opr_2}"), + ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), ASTR.SUB('$t0' , '$t0','$t1'), ASTR.Comment("poner en registro $t0 la suma "), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), @@ -360,6 +423,52 @@ def visit(self,node:AST.Rest): ] + @visitor.when(AST.Mult) + def visit(self , node :AST.Mult): + memory_dest=node.x + memory_op1=node.y + memory_op2=node.z + + stack_plus_memory_dest = self.stack.index(memory_dest) + stack_plus_opr_1 = self.stack.index(memory_op1) + stack_plus_opr_2 = self.stack.index(memory_op2) + + return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), + ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), + ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment(f"poner en registro $t1 {memory_op2} lo que hay en {stack_plus_opr_2}"), + ASTR.MUL('$t0' , '$t0','$t1'), + ASTR.Comment("poner en registro $t0 la suma "), + ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), + ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la multiplicacion "), + + ] + + + @visitor.when(AST.Div) + def visit (self,node:AST.Div): + memory_dest=node.x + memory_op1=node.y + memory_op2=node.z + + stack_plus_memory_dest = self.stack.index(memory_dest) + stack_plus_opr_1 = self.stack.index(memory_op1) + stack_plus_opr_2 = self.stack.index(memory_op2) + + return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), + ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), + ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), + ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), + ASTR.DIV('$t0' , '$t0','$t1'), + ASTR.Comment("poner en registro $t0 la suma "), + ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), + ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la Division entera el resto esta en LO "), + ] + + + + + @ visitor.when(AST.IfGoTo) def visit(self,node:AST.IfGoTo): memory_cmp = node.x @@ -370,7 +479,7 @@ def visit(self,node:AST.IfGoTo): return [ASTR.LI("$t0" ,1), ASTR.Comment("Cargar 1 a $t0 pa comparar"), ASTR.LW("$t1", f'{stack_plus_memory_cmp}($sp)' ), - ASTR.Comment(f"Cargar el valor de la pos {stack_plus_memory_cmp} a $t1 pa comparar"), + ASTR.Comment(f"Cargar el valor {memory_cmp} de la pos {stack_plus_memory_cmp} a $t1 pa comparar"), ASTR.BEQ("$t0","$t1", label_memory), ASTR.Comment(f"if $t1==$t0 then jump {label_memory}") ] @@ -392,7 +501,7 @@ def visit(self,node:AST.CheckType): return [ ASTR.LW('$s2',f'{stack_plus_memory_instance}($sp)'), - ASTR.Comment(f' pon en $s2 el contenido de {stack_plus_memory_instance}($sp)'), + ASTR.Comment(f' pon en $s2 {memory_instance} el contenido de {stack_plus_memory_instance}($sp)'), ASTR.LW('$a1', type_name), ASTR.Comment(f"guarda en $a1 {type_name} "), ASTR.JAL('Contain'), @@ -405,5 +514,16 @@ def visit(self,node:AST.CheckType): def visit(self,node:AST.GoTo): label = node.x return [ASTR.Jump (label), - ASTR.Comment("Salta para f{label} ") + ASTR.Comment(f"Salta para {label} ") ] + + + @visitor.when(AST.Complemnet) + def visit (self,node:AST.Complemnet): + memory_dest = node.x + memory_number = node.y + + stack_plus_memory_dest= self.stack.index(memory_dest) + stack_plus_memory_number = self.stack.index(memory_number) + + diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 3eaa28b61..1cfa3f8da 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -59,7 +59,10 @@ def __init__(self) -> None: def __str__(self) -> str: return """ -compare_String: # compare str1 ($a0), str2 ($a1) salida en $s0 + # compare str1 0($sp), str2 4($sp) salida en $s0 +#lw $a0 , (sp) si viene x la pila +#lw $a1 , 4(sp) si viene por la pila + LOOP: lb $t0, ($a0) lb $t1, ($a1) @@ -69,7 +72,8 @@ def __str__(self) -> str: beqz $t1, LOOP_END beq $t0, $t1, LOOP li $s0 , 0 - jr $ra + j End +# jr $ra EQUAL: li $s0, 1 @@ -78,9 +82,10 @@ def __str__(self) -> str: LOOP_END: beq $t0, $t1, EQUAL li $s0 , 0 - jr $ra + +# jr $ra END: - jr $ra""" +# jr $ra""" class Comment: @@ -172,6 +177,25 @@ def __str__(self) -> str: return f'{self.cmd} {self.dest}, {self.op_1}, {self.op_2}' +class Move : + def __init__(self,cmd ,Rds) -> None: + self.cmd = cmd + self.Rds = Rds + + def __str__(self) -> str: + return f'{self.cmd} {self.Rds}' + + +############################# Move ################################################### + +class MFHI(Move): + def __init__(self,Rds) -> None: + super().__init__('mfhi', Rds) + +class MFLO(Move): + def __init__(self,Rds) -> None: + super().__init__('mflo', Rds) + ############################ Loads ################################################## class LW(Load): def __init__(self, registry, memory_dir) -> None: @@ -200,22 +224,27 @@ class SEQ(CmpNotJump): #comparacion igualdad def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'seq' ,r_dest, r_src_1, r_src_2) -class SGE(CmpNotJump): +class SGE(CmpNotJump): #>= def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sge' ,r_dest, r_src_1, r_src_2) -class SLT (CmpNotJump): +class SGT (CmpNotJump): #> + def __init__(self, r_dest, r_src_1, r_src_2) -> None: + super().__init__('sgt', r_dest, r_src_1, r_src_2) + +class SLT (CmpNotJump): #< def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'slt' ,r_dest, r_src_1, r_src_2) -class SLE(CmpNotJump): +class SLE(CmpNotJump): # <= def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) + ########################### Jump ##################################################### class JAL(JumpInconditional): def __init__(self,dest) -> None: @@ -237,6 +266,8 @@ def __init__(self ,register1, register2, label) -> None: + + ################################# Operator ############################################## class AddI(Operation): @@ -255,6 +286,10 @@ class SUB (Operation): def __init__(self,dest,op1,op2) -> None: super().__init__('sub',dest,op1,op2) +class DIV (Operation): + def __init__(self, dest, op1, op2) -> None: + super().__init__('div', dest, op1, op2) + ################################# Native Func IO ################################################ class Out_String: @@ -345,21 +380,7 @@ def __str__(self) -> str: addi $sp, $sp, 4 jr $ra return """ -String_length: -li $t0 , 0 -lw $s2 , ($sp) - loop: - lb $s0 , ($s2) - beq $s0 , $zero, END - add $t0 , $t0 ,1 - add $s2,$s2,4 - j loop -END: - move $s0 , $t0 - addi $sp, $sp, 4 - jr $ra -""" class Concat: def __str__(self) -> str: @@ -367,6 +388,8 @@ def __str__(self) -> str: Concat: lw $s2 , 4($sp) lw $s1 , 0($sp) + lw $s2 ,4($s2) + lw $s1 ,4($s1) li $v0 , 9 li $a0 , 100 From b0c5b29ae03f6188f0fb0c4c05f3ecc3b3379f4c Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 09:54:24 -0500 Subject: [PATCH 66/91] fladjnf --- doc/report.md | 52 +++++++++++++++++-- src/cool_compiler/__main__.py | 2 +- .../v1_mips_generate/mipsgenerate_ast.py | 3 -- src/cool_compiler/parser/cool_parser.py | 1 + 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/doc/report.md b/doc/report.md index 5b6bb73f8..045301f03 100644 --- a/doc/report.md +++ b/doc/report.md @@ -37,11 +37,11 @@ realizarón pequeñas modificaciones para ajustarlas, más aun, a las necesidade Módulo que comienza con el analisis 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 sintácticamente significativas y según +que se le aplica al código, estos son subcadenas que son lexicograficamente significativas y según este significado se les asigan un tipo (literal, keyword, type, identificador, number, string, etc). El desarrollo de este módulo se apoyo en la libreria **sly**; expecificamente la clase **Lexer**, la cual -brinda la facilidad de definir un automata que reconozca las subcadenas significativas para una -sintaxis dada. Heredando de la clase **Lexer** y definiendo las propiedades _literals_ y _tokens_ se +brinda la facilidad de definir un automata que reconozca las subcadenas significativas para un +lenguaje dad. Heredando de la clase **Lexer** y definiendo las propiedades _literals_ y _tokens_ se puede expersar la lista de expersiones regulares que el automata debe reconocer, en este caso en particular se definieron de la siguiente manera: @@ -101,3 +101,49 @@ Estos fragmentos de código tiene un comportamientos similares al lenguaje `(ab) cual no basta con un automata finito determinista para reconocer todo el lenguaje. Para completar el reconocimiento de estos fragmentos, apoyados en **sly**, se impelmentaro automatas 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 checkear la consistencia sintáxtica del código en cuestión. Dicho módulo tambien fue +implementado con la ayuda de **sly**, expecificamente con su clase **Parser**. Esta clase facilita la definición de +gramáticas atributadas de manera extremadamente comoda. Heredando de **Parser** se pueden definir métodos como +atributo de cada produccion de la gramatica y mediante el decorador **@\_** se expecifica la produccion 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 teminal cclass + # en prod.epsilon se encuentra el teminal 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 cabezera el no terminal `expressionn`. 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 presedencias 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 +redefinir, en el caso particular del compilador de cool se redefinio de la manera siguiente: + +```python + ... + precedence = ( + ('right', 'ARROW'), + ('left','NOT'), + ('nonassoc', '=','<','LESS_OR'), + ('left', '+', '-'), + ('left', '*', '/'), + ('left', "ISVOID"), + ('left', '~'), + ('left', '@'), + ('right', 'IN'), + ('left', '.'), + ) + ... +``` + +Aprovechando la caracteristica de que la gramatica se encuentra recogida en una clase, se desarrollaro algunas herramientas +para realizar la inversion de la dependencia entre la gramatica y el ast, mediante el patrón **Factory**. Desde el módulo +parser se definio un enum con los nombres de los nodos que la clase parser le pasara a la fatoria de nodos, además de un +decorador que enlace un metodo con el nombre del nodo que el mismo creará diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 3a1b97a12..7098dfaa6 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +# path = "test.cl" with open(path, 'r') as _file: text = _file.read() diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 47cc54e44..6187d4e4b 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -234,9 +234,6 @@ class BEQ (JumpConditional): def __init__(self ,register1, register2, label) -> None: super().__init__( 'beq' ,register1, register2,label) - - - ################################# Operator ############################################## class AddI(Operation): diff --git a/src/cool_compiler/parser/cool_parser.py b/src/cool_compiler/parser/cool_parser.py index 1365ed49a..516ef50a2 100755 --- a/src/cool_compiler/parser/cool_parser.py +++ b/src/cool_compiler/parser/cool_parser.py @@ -40,6 +40,7 @@ def error(self, token): self.cool_error.add_syntactic(f"ERROR at or near {char}") self.lte = tok return tok + @_("") def epsilon(self, prod): pass From 3564f6cb3c8d9d9e26fb63f88e6d9907cf494133 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 11:31:52 -0500 Subject: [PATCH 67/91] bug en las comparaciones --- .../type_data_code_visitor.py | 6 ++--- .../codegen/v1_mips_generate/mipsgenerate.py | 27 ++++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 202423c69..5588976ea 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -137,7 +137,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): except AttributeError: save_current_func = None self.currentFunc = self.new_type_func - attr_name = self.new_type_func.local_push(node.name, self.new_class_scope) + attr_name = self.new_type_func.local_push(f'value_to_set_{node.name}', self.new_class_scope) exp_list = self.visit(node.expr, self.new_class_scope) exp_list[-1].set_value(attr_name) exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.name], attr_name)) @@ -494,9 +494,9 @@ def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: @visitor.when(AST.Bool) def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: - if node.item == 'True': value = 1 + if node.item == 'true': value = 1 else: value = 0 - return [ASTR.Assign(super_value, value)] + return [ ASTR.Comment(f"Boolean value next {node.item}"),ASTR.Assign(super_value, value)] @visitor.when(AST.Str) def visit(self, node: AST.Str, scope: Scope): diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index c9dcdbfdd..f38e284be 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -134,6 +134,8 @@ def visit(self, node: AST.GetAttr): def visit(self, node: AST.SetAttr): if node.y == 'type_name': attr_plus = 0 + attr = 'type_name' + _type = "SELF" else: attr_name = node.y.split('@') _type = attr_name[0] @@ -152,7 +154,7 @@ def visit(self, node: AST.SetAttr): ASTR.LW('$t1', f'{stack_plus_dir_value}($sp)'), ASTR.Comment(f'Buscando el valor que se va a guardar en la propiedad'), ASTR.SW('$t1', f'{attr_plus}($t0)'), - ASTR.Comment(f'Seteando el valor en la direccion de la memoria del objeto'), + ASTR.Comment(f'Seteando el valor {memory_dir_value} en la direccion de la memoria del la propiedad {attr} del objeto de typo {_type}'), ] @visitor.when(AST.Arg) @@ -313,8 +315,8 @@ def visit (self,node:AST.Less): ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), - ASTR.SLT ('$t3','$t2','$t1'), - ASTR.Comment("$t3 = $t2 < $ t1" ), + ASTR.SLT ('$t3','$t1','$t2'), + ASTR.Comment(f"$t3 = $t1 < $ t2 osea {dir_cmp1} < {dir_cmp2}" ), ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") ] @@ -333,8 +335,8 @@ def visit (self,node:AST.LessOrEqual): ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), - ASTR.SLE ('$t3','$t2','$t1'), - ASTR.Comment("$t3 = $t2 <= $ t1" ), + ASTR.SLE ('$t3','$t1','$t2'), + ASTR.Comment(f"$t3 = $t1 <= $t2 osea {dir_cmp1} <= {dir_cmp2}" ), ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") ] @@ -344,7 +346,6 @@ def visit(self,node:AST.Assign): memory_dest = node.x dir_value = node.y stack_plus = self.stack.index(memory_dest) - print(dir_value) if type(dir_value) in [type(int()), type(float())]: return [ @@ -378,8 +379,6 @@ def visit(self,node:AST.Neg): ASTR.Comment("$t0 = $t1 * (-1)"), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el contenido de $t0") - - ] @visitor.when(AST.Complemnet) @@ -421,9 +420,9 @@ def visit(self,node:AST.Rest): ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), ASTR.SUB('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la suma "), + ASTR.Comment("poner en registro $t0 la RESTA"), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la suma "), + ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la RESTA "), ] @@ -442,7 +441,7 @@ def visit(self , node :AST.Mult): ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), ASTR.Comment(f"poner en registro $t1 {memory_op2} lo que hay en {stack_plus_opr_2}"), ASTR.MUL('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la suma "), + ASTR.Comment("poner en registro $t0 la MULT "), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la multiplicacion "), @@ -464,15 +463,11 @@ def visit (self,node:AST.Div): ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), ASTR.DIV('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la suma "), + ASTR.Comment("poner en registro $t0 la DIV "), ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la Division entera el resto esta en LO "), ] - - - - @ visitor.when(AST.IfGoTo) def visit(self,node:AST.IfGoTo): memory_cmp = node.x From 1bbad081074db061bbfa291293555c6fabe86b13 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 11:34:11 -0500 Subject: [PATCH 68/91] complemte --- .../codegen/v1_mips_generate/mipsgenerate.py | 18 +++++++- .../v1_mips_generate/mipsgenerate_ast.py | 44 ++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index c9dcdbfdd..869c07c5e 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -288,9 +288,9 @@ def visit(self,node:AST.CmpStr): stack_plus_str2 = self.stack.index(memory_str2) stack_plus_dest = self.stack.index(memory_dest) - return [ASTR.LW('$a0',f'{stack_plus_str1}'), + return [ASTR.LW('$t0',f'{stack_plus_str1}'), ASTR.Comment(f"Si no viene como funcion pon el string {memory_str1} de la posicion {stack_plus_str1}"), - ASTR.LW('$a1',f'{stack_plus_str2}'), + ASTR.LW('$t1',f'{stack_plus_str2}'), ASTR.Comment(f"Si no viene como funcion pon el string {memory_str2} de la posicion {stack_plus_str2}"), ASTR.Compare_String(), ASTR.SW ('$s0', f'{stack_plus_dest}'), @@ -530,4 +530,18 @@ def visit (self,node:AST.Complemnet): stack_plus_memory_dest= self.stack.index(memory_dest) stack_plus_memory_number = self.stack.index(memory_number) + # return [ASTR.LW('$t1', f'{stack_plus_memory_number}($sp)'), + # ASTR.MUL('$s0','$t1',-1), + # ASTR.SW ('$s0', f'{stack_plus_memory_dest}($sp)') + + + + # ] + return [ASTR.LI ('$t0',4294967295), + ASTR.LW ('$t1', f'{stack_plus_memory_number}($sp)'), + ASTR.XOR ("$s0" , '$t0','$t1'), + ASTR.Add ('$s0' ,'$s0' ,'1'), + ASTR.SW ('$s0', f'{stack_plus_memory_dest}($sp)') + ] + diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 1cfa3f8da..26a998eb0 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -60,8 +60,8 @@ def __init__(self) -> None: def __str__(self) -> str: return """ # compare str1 0($sp), str2 4($sp) salida en $s0 -#lw $a0 , (sp) si viene x la pila -#lw $a1 , 4(sp) si viene por la pila +lw $a0 , 4($t0) +lw $a1 , 4($t1) LOOP: lb $t0, ($a0) @@ -288,7 +288,12 @@ def __init__(self,dest,op1,op2) -> None: class DIV (Operation): def __init__(self, dest, op1, op2) -> None: - super().__init__('div', dest, op1, op2) + super().__init__('div', dest, op1, op2) + + +class XOR(Operation): + def __init__(self, dest, op1, op2) -> None: + super().__init__('xor', dest, op1, op2) ################################# Native Func IO ################################################ @@ -365,8 +370,10 @@ def __str__(self) -> str: return """ String_length: - li $t0 , 0 - lw $s2 , ($sp) + lw $t4 , ($sp) #self + li $t0 , 0 #contador + lw $s2 , 4($t4) # propiedad value + loop: lb $s0 , ($s2) beq $s0 , $zero, END @@ -386,13 +393,13 @@ class Concat: def __str__(self) -> str: return """ Concat: - lw $s2 , 4($sp) - lw $s1 , 0($sp) - lw $s2 ,4($s2) - lw $s1 ,4($s1) + lw $t2 , 4($sp) #self + lw $t1 , 0($sp) # str1 + lw $s2 ,4($t2) # propiedad value + lw $s1 ,4($t1) # propiedad value li $v0 , 9 - li $a0 , 100 + li $a0 , 100 # reservar memoria pal proximo string syscall move $s3 , $v0 @@ -420,11 +427,23 @@ def __str__(self) -> str: class SubStr: def __str__(self) -> str: - return """ + return """ + + lw $s1 , (sp) # guarda el indice + lw $t4 , 4(sp) # guarda el j + lw $s5 , 8(sp) # self. + lw $s3 , 4($s5) # tomar la propiedad value del string + add $a0 , $s1 , $t4 #tamano a reservar + + li $v0 , 9 + syscall + move $s4 , $v0 # $s4 direciion de destino + + Substring: li $t0 ,0 find_index: - beq $t0, $s1, find_length # if $t0 == $t1 then target + beq $t0, $s1, find_length # if $t0 == $s1 then estas en el indice add $s3, $s3, 1 #s2 = s2 + 1 add $t0, $t0, 1 # $t0 = $t0 + 1 j find_index @@ -440,6 +459,7 @@ def __str__(self) -> str: j find_length END_Substring: + move s0 , $a0 addi $sp, $sp, 12 jr $ra """ From edd4f1281345a82f68b54e84c4631d2846924973 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 14:04:18 -0500 Subject: [PATCH 69/91] refactor basics --- .../type_data_code_visitor.py | 105 ++++++++++++------ .../codegen/v1_mips_generate/mipsgenerate.py | 4 +- .../v1_mips_generate/mipsgenerate_ast.py | 6 + .../types/build_in_types/bool.py | 7 +- src/cool_compiler/types/build_in_types/int.py | 7 +- 5 files changed, 89 insertions(+), 40 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 5588976ea..ffc0e65c7 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -3,7 +3,7 @@ from ...cmp import visitor from ...semantic.v2_semantic_checking import semantic_checking_ast as AST from . import type_data_code_ast as ASTR -from .type_data_code_ast import Arg, result, super_value +from .type_data_code_ast import Arg, CmpInt, result, super_value CoolInt = CoolTypeBuildInManager().find("Int") CoolBool = CoolTypeBuildInManager().find("Bool") @@ -52,7 +52,7 @@ def visit(node, scope: Scope): @visitor.when(AST.Program) def visit(self, node: AST.Program, scope: Scope = None): self.program = ASTR.Program() - self.program.try_add_data('_______error______', 'runtime error') + self.program.try_add_data('_______error______', 'Abort called from class ') self.program.try_add_data('_______null_______', 'null') scope = Scope() @@ -131,27 +131,32 @@ def create_new_func_by_type(self, _type, scope): @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, []]: - try: - save_current_func = self.currentFunc - except AttributeError: - save_current_func = None - self.currentFunc = self.new_type_func attr_name = self.new_type_func.local_push(f'value_to_set_{node.name}', self.new_class_scope) exp_list = self.visit(node.expr, self.new_class_scope) exp_list[-1].set_value(attr_name) exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.name], attr_name)) exp_list.append(ASTR.Comment(f"Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}")) self.new_type_func.expr += exp_list - self.currentFunc = save_current_func elif node.type in [CoolInt, CoolBool]: default = self.new_type_func.local_push('default_prop', self.new_class_scope) self.new_type_func.expr_push(ASTR.Assign(default, 0)) + self.new_type_func.expr += self.value_def(default, node.type.name, scope) + self.new_type_func.expr[-1].set_value(default) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], default)) else: null = self.new_type_func.local_push('null') self.new_type_func.expr_push(ASTR.Load(null, '_______null_______')) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], null)) + + self.currentFunc = save_current_func + @visitor.when(AST.FuncDef) def visit(self, node: AST.FuncDef, scope: Scope): @@ -202,7 +207,6 @@ def visit(self, node: AST.Dispatch, scope: Scope): instance_expr_list.append(ASTR.Comment(f"Fin de la exprecion previa al Dispatch {node.id}")) arg_list = [instance_name] - for i, param in enumerate(node.params): instance_expr_list += self.visit(param, scope) param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) @@ -263,6 +267,7 @@ def visit(self, node: AST.IfThenElse, scope: Scope): label_then = new_name(f'then_{self.currentFunc.name}', self.label_list) label_fin = new_name(f'fin_{self.currentFunc.name}', self.label_list) + self.get_value(cond_result, 'Bool') expr_list.append(ASTR.IfGoTo(cond_result, label_then)) expr_list.append(ASTR.Comment(f'Else case')) @@ -295,6 +300,7 @@ def visit(self, node: AST.While, scope: Scope): cond_local = self.currentFunc.local_push('cond@while', scope) result_list += self.visit(node.condition, scope) result_list[-1].set_value(cond_local) + self.get_value(cond_local, 'Bool') result_list.append(ASTR.IfGoTo(cond_local, while_back)) result_list.append(ASTR.Comment(f'Fin de la condicion de un While')) @@ -395,19 +401,22 @@ def visit(self, node: AST.Case, scope: Scope): return self.general_case(node, scope, expr_cond_list) - def binary_op(self, name, node, astr_node, scope: Scope): + def binary_op(self, name, node, astr_node, scope: Scope, _type = 'Int', type_result = 'Int'): op_1 = self.currentFunc.local_push(f'{name}@_a', scope) op_2 = self.currentFunc.local_push(f'{name}@_b', scope) 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 opercion {name}')) + result_list.append(self.get_value(op_1, _type)) 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 opercion {name}')) + result_list.append(self.get_value(op_2, _type)) - return result_list + [astr_node(super_value, op_1, op_2)] + op_result = self.currentFunc.local_push(f'{name}@_result', scope) + return result_list + [astr_node(op_result, op_1, op_2)] + self.value_def(op_result, type_result, scope) @visitor.when(AST.Sum) def visit(self, node: AST.Sum, scope: Scope): @@ -427,20 +436,32 @@ def visit(self, node: AST.Div, scope: Scope): @visitor.when(AST.Less) def visit(self, node: AST.Less, scope: Scope): - return self.binary_op('less', node, ASTR.Less, scope) + return self.binary_op('less', node, ASTR.Less, scope, type_result='Bool') @visitor.when(AST.LessOrEquals) def visit(self, node: AST.LessOrEquals, scope: Scope): - return self.binary_op('le', node, ASTR.LessOrEqual, scope) + return self.binary_op('le', node, ASTR.LessOrEqual, scope, type_result='Bool') @visitor.when(AST.Equals) def visit(self, node: AST.Equals, scope: Scope): if node.static_type in [CoolInt, CoolBool]: return self.binary_op('int_eq', node, ASTR.CmpInt, scope) if node.static_type == CoolStr: - return self.binary_op('str_eq', node, ASTR.CmpStr, scope) + return self.binary_op('str_eq', node, ASTR.CmpStr, scope, 'String', 'Boolena') - return self.binary_op('req_eq', node, ASTR.CmpInt, scope) + op_1 = self.currentFunc.local_push(f'ref@_a', scope) + op_2 = self.currentFunc.local_push(f'ref@_b', scope) + + 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 opercion cmpref')) + + 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 opercion cmpref')) + + op_result = self.currentFunc.local_push(f'ref@_result', scope) + return result_list + [CmpInt(op_result, op_1, op_2)] + self.value_def(op_result, 'Bool', scope) @visitor.when(AST.New) def visit(self, node: AST.New, scope: Scope): @@ -451,20 +472,20 @@ def visit(self, node: AST.New, scope: Scope): ASTR.New(super_value, node.item.name) ] - def unary_op(self, name, node, astr_node, scope: Scope): + def unary_op(self, name, node, astr_node, scope: Scope, _type): op = self.currentFunc.local_push(f'{name}@_unary', scope) result_list = self.visit(node.item, scope) result_list[-1].set_value(op) - return result_list + [astr_node(super_value, op)] + return result_list + [self.get_value(op, _type), astr_node(super_value, op)] @visitor.when(AST.Complement) def visit(self, node: AST.Complement, scope: Scope): - return self.unary_op('compl', node, ASTR.Complemnet, scope) + return self.unary_op('compl', node, ASTR.Complemnet, scope, 'Int') @visitor.when(AST.Neg) def visit(self, node: AST.Neg, scope: Scope): - return self.unary_op('neg', node, ASTR.Neg, scope) + return self.unary_op('neg', node, ASTR.Neg, scope, 'Bool') @visitor.when(AST.Void) def visit(self, node: AST.Void, scope: Scope): @@ -483,36 +504,52 @@ def visit(self, node: AST.Void, scope: Scope): def visit(self, node: AST.Id, scope: Scope): var = scope.find_variable(node.item) if not var is None: - return [ASTR.Assign(super_value, var.type)] - + return [ASTR.Assign(super_value, var.type)] else: - return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] + return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] + + def get_value(self, memory_dir, _type): + return [ASTR.GetAttr(memory_dir, memory_dir, f'{_type}@value')] + + def value_def(self, _value, type_name, scope): + upper_type = type_name.upper() + _type = self.currentFunc.local_push(f'type_{upper_type}', scope) + _instance = self.currentFunc.local_push(f'{upper_type}_instance', scope) + + return [ + # ASTR.Load(string_value, name), + # ASTR.Comment("Carga la referecia a string"), + ASTR.ALLOCATE(_instance, type_name), + ASTR.SetAttr(_instance, f'{type_name}@value', _value), + ASTR.Comment(f"Setear la propiedad value al {upper_type} en la variable {_value}"), + ASTR.Load(_type, type_name), + ASTR.SetAttr(_instance, 'type_name', _type), + ASTR.Comment(f"Setear la propiedad type_name al string en la variable {_value}"), + ASTR.Assign(super_value, _instance), + ] @visitor.when(AST.Int) def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: - return [ASTR.Assign(super_value, node.item)] + int_value = self.currentFunc.local_push('value_boolean', scope) + return [ + ASTR.Assign(int_value, node.item), ASTR.Comment(f"Int value {node.item}") + ] + self.value_def(int_value, 'Int', scope) @visitor.when(AST.Bool) def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: + boolean_value = self.currentFunc.local_push('value_boolean', scope) if node.item == 'true': value = 1 else: value = 0 - return [ ASTR.Comment(f"Boolean value next {node.item}"),ASTR.Assign(super_value, value)] + return [ + ASTR.Assign(boolean_value, value), ASTR.Comment(f"Bool value {node.item}") + ] + self.value_def(boolean_value, 'Bool', scope) @visitor.when(AST.Str) def visit(self, node: AST.Str, scope: Scope): name = self.program.add_data('string', node.item) string_value = self.currentFunc.local_push('value_string', scope) - string_type = self.currentFunc.local_push('type_string', scope) - string_instance = self.currentFunc.local_push('string_instance', scope) return [ ASTR.Load(string_value, name), ASTR.Comment("Carga la referecia a string"), - ASTR.ALLOCATE(string_instance, 'String'), - ASTR.SetAttr(string_instance, 'String@value', string_value), - ASTR.Comment(f"Setear la propiedad value al string en la variable {string_value}"), - ASTR.Load(string_type, 'String'), - ASTR.SetAttr(string_instance, 'type_name', string_type), - ASTR.Comment(f"Setear la propiedad type_name al string en la variable {string_value}"), - ASTR.Assign(super_value, string_instance), - ] \ No newline at end of file + ] + self.value_def(string_value, 'String', scope) \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index f38e284be..8e13ccd1a 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -297,9 +297,7 @@ def visit(self,node:AST.CmpStr): ASTR.Compare_String(), ASTR.SW ('$s0', f'{stack_plus_dest}'), ASTR.Comment(f"Como no retorna sigue lineal entoces en $s0 esta el resultado y se pone en {stack_plus_dest}") - - - ] + ] @visitor.when(AST.Less) def visit (self,node:AST.Less): diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 62445896e..51b5b9eef 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -470,6 +470,12 @@ def __str__(self) -> str: li $v0, 4 # system call #4 - print string la $a0, _______error______ syscall +lw $t0 0($sp) #Guarda en $t0 self +lw $t1 0($t0) #Guarga en tipo de self +lw $t2 0($t1) +li $v0, 4 # system call #4 - print string +la $a0, ($t2) +syscall li $v0, 10 syscall # execute """ diff --git a/src/cool_compiler/types/build_in_types/bool.py b/src/cool_compiler/types/build_in_types/bool.py index 0cb7b5d51..1031c2ed2 100755 --- a/src/cool_compiler/types/build_in_types/bool.py +++ b/src/cool_compiler/types/build_in_types/bool.py @@ -6,8 +6,11 @@ class Bool(Type): def __init__(self): super().__init__("Bool") - type_body_def(self.__class__) + type_body_def(self) @property def is_shield(self): - return True \ No newline at end of file + 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 index d95a4f8a5..8391a6510 100755 --- a/src/cool_compiler/types/build_in_types/int.py +++ b/src/cool_compiler/types/build_in_types/int.py @@ -1,11 +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 \ No newline at end of file + return True + + def value(self): + self.define_attribute("value", self) \ No newline at end of file From 170d03cd9d116c66ec206f5edc9c5e1a8054d226 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 14:06:49 -0500 Subject: [PATCH 70/91] fxdghjkl --- src/cool_compiler/__main__.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 3 +- .../v1_mips_generate/mipsgenerate_ast.py | 57 ++++++++++++++----- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 7098dfaa6..3a1b97a12 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -# path = "test.cl" +path = "test.cl" with open(path, 'r') as _file: text = _file.read() diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 7b326dd4c..f9edd1415 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -17,7 +17,8 @@ def __init__(self, errors) -> None: "String_substr":1, "Object_copy": ASTR.Copy, "Object_type_name":ASTR.Type_Name, - "Object_abort": ASTR.Abort + "Object_abort": ASTR.Abort, + "String_substr":ASTR.SubStr } @visitor.on('node') diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 38b785286..ff316cf3c 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -296,11 +296,16 @@ class Out_String: def __str__(self) -> str: return """ IO_out_string: -lw $t0 0($sp) #Guarda en $t0 la direccion del string + +lw $t1 , 4($sp) +lw $t0, 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 lw $a0, 4($t0) #Pintando la propiedad value del string syscall + addi $sp, $sp, 8 +move $s0,$t1 + jr $ra""" class Out_Int: @@ -423,39 +428,57 @@ def __str__(self) -> str: class SubStr: def __str__(self) -> str: return """ - - lw $s1 , (sp) # guarda el indice - lw $t4 , 4(sp) # guarda el j - lw $s5 , 8(sp) # self. +String_substr: + + li $t0 ,0 + li $s6 ,1 + lw $s1 , 4($sp) # guarda el indice + lw $t4 , ($sp) # guarda el j + lw $s5 , 8($sp) # self. lw $s3 , 4($s5) # tomar la propiedad value del string - add $a0 , $s1 , $t4 #tamano a reservar + #add $a0 , $s1 , $t4 #tamano a reservar + + li $a0,8 li $v0 , 9 syscall - move $s4 , $v0 # $s4 direciion de destino + move $t7 , $v0 # $t4 direciion de destino + move $t5 , $v0 #guarde la dir de la clase string # + la $s7 , String #primer atributo de la calse + sw $s7 , ($t5) + add $t5,$t5,4 #posicion de la direccion del valor del string + + + li $a0 ,100 + li $v0,9 + syscall #genere espacio para crear string + move $s4,$v0 + -Substring: - li $t0 ,0 find_index: beq $t0, $s1, find_length # if $t0 == $s1 then estas en el indice add $s3, $s3, 1 #s2 = s2 + 1 add $t0, $t0, 1 # $t0 = $t0 + 1 + j find_index find_length: lb $t1, ($s3) # sb $t1, ($s4) - beq $t0, $s2, END_Substring # if $t0 == $t1 then target - add $s4, $s4, 1 # $S4 = s41 1t2 - # + beq $s6, $t4, END_Substring # if $t0 == $t1 then target + add $s4, $s4, 1 # $S4 = s41 1t2 # add $s3, $s3, 1 #s2 = s2 + 1 - add $t0, $t0, 1 # $t0 = $t0 + 1 + add $s6, $s6, 1 # $t0 = $t0 + 1 j find_length END_Substring: - move s0 , $a0 + move $s0 , $v0 + sw $s0 , ($t5) + move $s0 , $t7 addi $sp, $sp, 12 + + jr $ra """ ################################# Native Func Obj ################################################ @@ -480,6 +503,7 @@ def __str__(self) -> str: jr copy_loop end_copy: addi $sp, $sp, 4 + jr $ra """ @@ -497,7 +521,7 @@ def __str__(self) -> str: class Type_Name: def __str__(self) -> str: return """ -IO_out_string: +Object_type_name: lw $t0 0($sp) #Guarda en $t0 la direccion del self lw $t1 0($t0) #La primera posicion de self es la propiedad type_name lw $t2 0($t1) #La propiedad type_name apunta a la definicion del tipo @@ -514,6 +538,9 @@ def __str__(self) -> str: addi $sp, $sp, 4 move $s0, $v0 + + + jr $ra """ From 02d4b816bf36ef8378d838680351d3dfed28193c Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 14:53:44 -0500 Subject: [PATCH 71/91] refactor los tipos basicos --- .../type_data_code_visitor.py | 8 +-- .../v1_mips_generate/mipsgenerate_ast.py | 64 ++++++++++--------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index ffc0e65c7..eb9d52bdf 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -267,7 +267,7 @@ def visit(self, node: AST.IfThenElse, scope: Scope): label_then = new_name(f'then_{self.currentFunc.name}', self.label_list) label_fin = new_name(f'fin_{self.currentFunc.name}', self.label_list) - self.get_value(cond_result, 'Bool') + expr_list.append(self.get_value(cond_result, 'Bool')) expr_list.append(ASTR.IfGoTo(cond_result, label_then)) expr_list.append(ASTR.Comment(f'Else case')) @@ -300,7 +300,7 @@ def visit(self, node: AST.While, scope: Scope): cond_local = self.currentFunc.local_push('cond@while', scope) result_list += self.visit(node.condition, scope) result_list[-1].set_value(cond_local) - self.get_value(cond_local, 'Bool') + result_list.append(self.get_value(cond_local, 'Bool')) result_list.append(ASTR.IfGoTo(cond_local, while_back)) result_list.append(ASTR.Comment(f'Fin de la condicion de un While')) @@ -509,7 +509,7 @@ def visit(self, node: AST.Id, scope: Scope): return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] def get_value(self, memory_dir, _type): - return [ASTR.GetAttr(memory_dir, memory_dir, f'{_type}@value')] + return ASTR.GetAttr(memory_dir, memory_dir, f'{_type}@value') def value_def(self, _value, type_name, scope): upper_type = type_name.upper() @@ -530,7 +530,7 @@ def value_def(self, _value, type_name, scope): @visitor.when(AST.Int) def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: - int_value = self.currentFunc.local_push('value_boolean', scope) + int_value = self.currentFunc.local_push('value_int', scope) return [ ASTR.Assign(int_value, node.item), ASTR.Comment(f"Int value {node.item}") ] + self.value_def(int_value, 'Int', scope) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index e30b954d3..0276f9020 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -103,7 +103,6 @@ def __init__(self, msg) -> None: def __str__(self) -> str: return f'#{self.msg}' - class Label: def __init__(self,label) -> None: self.label = label @@ -157,8 +156,7 @@ def __init__(self,cmd,reg1,reg2,label) -> None: def __str__(self) -> str: return f'{self.cmd} {self.reg1} {self.reg2} {self.label}' - - + class SysCall : def __init__(self) -> None: pass @@ -176,7 +174,6 @@ def __init__(self,cmd,dest,op1,op2) -> None: def __str__(self) -> str: return f'{self.cmd} {self.dest}, {self.op_1}, {self.op_2}' - class Move : def __init__(self,cmd ,Rds) -> None: self.cmd = cmd @@ -185,9 +182,7 @@ def __init__(self,cmd ,Rds) -> None: def __str__(self) -> str: return f'{self.cmd} {self.Rds}' - ############################# Move ################################################### - class MFHI(Move): def __init__(self,Rds) -> None: super().__init__('mfhi', Rds) @@ -195,7 +190,6 @@ def __init__(self,Rds) -> None: class MFLO(Move): def __init__(self,Rds) -> None: super().__init__('mflo', Rds) - ############################ Loads ################################################## class LW(Load): def __init__(self, registry, memory_dir) -> None: @@ -208,18 +202,11 @@ def __init__(self, registry, memory_dir) -> None: class LA(Load): def __init__(self, registry, memory_dir) -> None: super().__init__('la', registry, memory_dir) - - - ############################ Store ################################################## class SW(Store): def __init__(self, registry, memory_dir) -> None: super().__init__('sw', registry, memory_dir) - - - ############################ Cmp ################################################## - class SEQ(CmpNotJump): #comparacion igualdad def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'seq' ,r_dest, r_src_1, r_src_2) @@ -241,10 +228,6 @@ class SLE(CmpNotJump): # <= def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) - - - - ########################### Jump ##################################################### class JAL(JumpInconditional): def __init__(self,dest) -> None: @@ -258,13 +241,10 @@ class Jump(JumpInconditional): def __init__(self,dest) -> None: super().__init__('j',dest) ################################# JUMPConditional ####################################### - class BEQ (JumpConditional): def __init__(self ,register1, register2, label) -> None: super().__init__( 'beq' ,register1, register2,label) - ################################# Operator ############################################## - class AddI(Operation): def __init__(self,dest,op1,op2) -> None: super().__init__('addi',dest,op1,op2) @@ -285,12 +265,10 @@ class DIV (Operation): def __init__(self, dest, op1, op2) -> None: super().__init__('div', dest, op1, op2) - class XOR(Operation): def __init__(self, dest, op1, op2) -> None: super().__init__('xor', dest, op1, op2) - ################################# Native Func IO ################################################ class Out_String: def __str__(self) -> str: @@ -302,30 +280,43 @@ def __str__(self) -> str: li $v0, 4 lw $a0, 4($t0) #Pintando la propiedad value del string syscall - addi $sp, $sp, 8 -move $s0,$t1 - +move $s0, $t1 jr $ra""" class Out_Int: def __str__(self) -> str: return """ IO_out_int: +lw $t1 , 4($sp) +lw $t0, 0($sp) #Guarda en $t0 la direccion del int li $v0, 1 -lw $a0, 0($sp) +lw $a0, 4($t0) #Pintando la propiedad value del int syscall addi $sp, $sp, 8 +move $s0, $t1 jr $ra""" class In_String: def __str__(self) -> str: return """ IO_in_string: -li $v0,8 +li $v0, 8 li $a1 , 10000 syscall -move $s0 , $a0 +move $t6 $v0 + +#Allocate a una class String puntero en sp + 12 +#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 $t4, String +sw $t4, 0($v0) # Asigna el tipo String al string +sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del string + +move $s0 , $v0 addi $sp, $sp, 4 jr $ra """ @@ -336,6 +327,18 @@ def __str__(self) -> str: IO_in_int: li $v0, 5 syscall +move $t6 $v0 + +#Allocate a una class Int puntero en sp + 12 +#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 $t4, Int +sw $t4, 0($v0) # Asigna el tipo Int al int +sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del int + move $s0 , $v0 addi $sp, $sp, 4 jr $ra @@ -532,6 +535,7 @@ def __str__(self) -> str: lw $t1 0($t0) #La primera posicion de self es la propiedad type_name lw $t2 0($t1) #La propiedad type_name apunta a la definicion del tipo la $t3 0($t2) #La definicion de tipo tiene en la primera poscion su nombre + #Allocate a una class String puntero en sp + 12 #atributo type_name en puntero + 0 #atributo value en puntero + 4 @@ -545,8 +549,6 @@ def __str__(self) -> str: addi $sp, $sp, 4 move $s0, $v0 - - jr $ra """ From 09cb5a3189ce3041ebd7cab4deb903f6cfde8356 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 14:54:43 -0500 Subject: [PATCH 72/91] kkk --- .../v1_mips_generate/mipsgenerate_ast.py | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index ff316cf3c..2db6964df 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -312,10 +312,12 @@ class Out_Int: def __str__(self) -> str: return """ IO_out_int: +lw $t1 , 4($sp) #cargar self li $v0, 1 lw $a0, 0($sp) syscall addi $sp, $sp, 8 +move $s0, $t1 jr $ra""" class In_String: @@ -325,7 +327,7 @@ def __str__(self) -> str: li $v0,8 li $a1 , 10000 syscall -move $s0 , $a0 +move $s0 , $v0 addi $sp, $sp, 4 jr $ra """ @@ -370,6 +372,14 @@ def __str__(self) -> str: return """ String_length: + + li $v0,1 + li $a0,4 + syscall + + li $v0,10 + syscall + lw $t4 , ($sp) #self li $t0 , 0 #contador lw $s2 , 4($t4) # propiedad value @@ -386,7 +396,7 @@ def __str__(self) -> str: move $s0 , $t0 addi $sp, $sp, 4 jr $ra - return """ + """ class Concat: @@ -398,10 +408,21 @@ def __str__(self) -> str: lw $s2 ,4($t2) # propiedad value lw $s1 ,4($t1) # propiedad value + + li $a0,12 li $v0 , 9 - li $a0 , 100 # reservar memoria pal proximo string syscall - move $s3 , $v0 + move $t7 , $v0 # $t7 direciion de destino de la clase + move $t5 , $v0 #guarde la dir de la clase string # + la $s7 , String #primer atributo de la calse + sw $s7 , ($t5) + add $t5,$t5,4 #posicion de la direccion del valor del string + + + li $a0 ,100 + li $v0,9 + syscall #genere espacio para crear string + move $s3,$v0 loop_str1: lb $t0 , ($s1) @@ -420,7 +441,9 @@ def __str__(self) -> str: j loop_str1 ENDConcat: - move $s0, $v0 + move $s0 , $v0 + sw $s0 , ($t5) + move $s0 , $t7 addi $sp, $sp, 8 jr $ra """ @@ -497,7 +520,7 @@ def __str__(self) -> str: beq $t3, $zero, end_copy lw $t1, 0($t0) sw $t1, 0($v0) - addi $t3, $t3, -4 + addi $t3, $t3, -1 add $t0, $t0, 4 add $v0, $v0, 4 jr copy_loop From e893829609511f9c47752b7da3c31ad8b2a230ec Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 15:08:59 -0500 Subject: [PATCH 73/91] complex --- .../codegen/v0_type_data_code/type_data_code_visitor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index eb9d52bdf..bb559c989 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -477,7 +477,8 @@ def unary_op(self, name, node, astr_node, scope: Scope, _type): result_list = self.visit(node.item, scope) result_list[-1].set_value(op) - return result_list + [self.get_value(op, _type), astr_node(super_value, op)] + op_result = self.currentFunc.local_push(f'ref@_result', scope) + return result_list + [self.get_value(op, _type), astr_node(op_result, op)] + self.value_def(op_result, _type, scope) @visitor.when(AST.Complement) def visit(self, node: AST.Complement, scope: Scope): From 773370d89cf0de74434ff0d2ec341a844d3d3586 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 15:41:12 -0500 Subject: [PATCH 74/91] refactor native --- doc/report.md | 4 +- .../type_data_code_visitor.py | 7 +- .../v1_mips_generate/mipsgenerate_ast.py | 127 ++++++++++-------- 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/doc/report.md b/doc/report.md index 045301f03..262729bf2 100644 --- a/doc/report.md +++ b/doc/report.md @@ -145,5 +145,5 @@ redefinir, en el caso particular del compilador de cool se redefinio de la maner Aprovechando la caracteristica de que la gramatica se encuentra recogida en una clase, se desarrollaro algunas herramientas para realizar la inversion de la dependencia entre la gramatica y el ast, mediante el patrón **Factory**. Desde el módulo -parser se definio un enum con los nombres de los nodos que la clase parser le pasara a la fatoria de nodos, además de un -decorador que enlace un metodo con el nombre del nodo que el mismo creará +parser se definió un enum con los nombres de los nodos que la clase parser le pasará a la fatoria de nodos, además de un +decorador que enlace un método con el nombre del nodo que el mismo creará diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index bb559c989..0b5764420 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -494,11 +494,12 @@ def visit(self, node: AST.Void, scope: Scope): null = self.currentFunc.local_push('void@_null', scope) unary_list = self.visit(node.item, scope) unary_list[-1].set_value(op_1) - + op_result = self.currentFunc.local_push(f'void@_result', scope) return ( - [ASTR.Load(null, "_______null_______")] + [ASTR.Load(null, "_______null_______"), ASTR.Comment("void check")] + unary_list - + [ASTR.CmpInt(super_value, null, op_1)] + + [ASTR.CmpInt(op_result, null, op_1)] + + self.value_def(op_result, 'Bool', scope) ) @visitor.when(AST.Id) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 0276f9020..59079ad9b 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -275,36 +275,42 @@ def __str__(self) -> str: return """ IO_out_string: -lw $t1 , 4($sp) +lw $t1 , 4($sp) #Guardando self lw $t0, 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 lw $a0, 4($t0) #Pintando la propiedad value del string syscall addi $sp, $sp, 8 -move $s0, $t1 +move $s0, $t1 #return self jr $ra""" class Out_Int: def __str__(self) -> str: return """ IO_out_int: -lw $t1 , 4($sp) +lw $t1 , 4($sp) #guarda self lw $t0, 0($sp) #Guarda en $t0 la direccion del int li $v0, 1 lw $a0, 4($t0) #Pintando la propiedad value del int syscall addi $sp, $sp, 8 -move $s0, $t1 +move $s0, $t1 #return self jr $ra""" class In_String: def __str__(self) -> str: return """ IO_in_string: + +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 , 10000 +li $a1 , 1000 syscall -move $t6 $v0 +move $s0 $a0 # Restun string #Allocate a una class String puntero en sp + 12 #atributo type_name en puntero + 0 @@ -314,7 +320,7 @@ def __str__(self) -> str: syscall # En $v0 la instancia del nuevo string la $t4, String sw $t4, 0($v0) # Asigna el tipo String al string -sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del string +sw $s0, 4($v0) # Asigan el nombre de la clase a la propiededa value del string move $s0 , $v0 addi $sp, $sp, 4 @@ -370,62 +376,69 @@ def __str__(self) -> str: ################################# Native Func Str ################################################ class Length: def __str__(self) -> str: - return """ - - String_length: - lw $t4 , ($sp) #self - li $t0 , 0 #contador - lw $s2 , 4($t4) # propiedad value - - loop: - lb $s0 , ($s2) - beq $s0 , $zero, END - add $t0 , $t0 ,1 - add $s2,$s2,4 - j loop - - - END: - move $s0 , $t0 - addi $sp, $sp, 4 - jr $ra return """ +String_length: +lw $t4 , ($sp) #self +li $t0 , 0 #contador +lw $s2 , 4($t4) # propiedad value + +loop_len: +lb $s0 , ($s2) # Guarda la primara letra +beq $s0 , $zero, end_len +add $t0 , $t0, 1 # Suma al contador +add $s2, $s2, 1 # Mueve el punteron del string en 1 +j loop_len + +end_len: +#Allocate a una class Int puntero en sp + 12 +#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 $t4, Int +sw $t4, 0($v0) # Asigna el tipo Int al int +sw $t0, 4($v0) # Asigan el nombre de la clase a la propiededa value del int + +move $s0 , $v0 +addi $sp, $sp, 4 +jr $ra""" class Concat: def __str__(self) -> str: return """ - Concat: - lw $t2 , 4($sp) #self - lw $t1 , 0($sp) # str1 - lw $s2 ,4($t2) # propiedad value - lw $s1 ,4($t1) # propiedad value - - li $v0 , 9 - li $a0 , 100 # reservar memoria pal proximo string - syscall - move $s3 , $v0 - - loop_str1: - lb $t0 , ($s1) - beq $t0 , $zero, loop_str2 - add $s1 , $s1 ,1 - sb $t0,($s3) - add $s3 , $s3 , 1 - j loop_str1 - - loop_str2: - lb $t0 , ($s2) - beq $t0 , $zero, ENDConcat - add $s2 , $s2 ,1 - sb $t0,($s3) - add $s3 , $s3 , 1 - j loop_str1 - - ENDConcat: - move $s0, $v0 - addi $sp, $sp, 8 - jr $ra +Concat: +lw $t2 , 4($sp) #self +lw $t1 , 0($sp) # str1 +lw $s2 , 4($t2) # propiedad value de self +lw $s1 , 4($t1) # propiedad value de str1 + +li $v0 , 9 +li $a0 , 100 # reservar memoria pal proximo string +syscall +move $s3 , $v0 + +loop_str1: + lb $t0 , ($s1) + beq $t0 , $zero, loop_str2 + add $s1 , $s1 ,1 + sb $t0,($s3) + add $s3 , $s3 , 1 + j loop_str1 + +loop_str2: + lb $t0 , ($s2) + beq $t0 , $zero, ENDConcat + add $s2 , $s2 ,1 + sb $t0,($s3) + add $s3 , $s3 , 1 + j loop_str1 + +ENDConcat: + move $s0, $v0 + addi $sp, $sp, 8 + jr $ra """ class SubStr: From 525a7965bf7771dce97b0eff5cfa3e9a16814684 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 15:41:13 -0500 Subject: [PATCH 75/91] unio --- .../v1_mips_generate/mipsgenerate_ast.py | 30 +- src/test.mips | 1043 ++++++++++++++--- 2 files changed, 868 insertions(+), 205 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index aecbdc6e0..4063fcd2d 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -301,10 +301,21 @@ class In_String: def __str__(self) -> str: return """ IO_in_string: + li $v0, 8 li $a1 , 10000 syscall -move $t6 $v0 +move $t6 ,$v0 + + li $v0 ,4 + move $a0,$t6 + syscall + + li $v0,10 + syscall + + +move $s0 , $v0 #Allocate a una class String puntero en sp + 12 #atributo type_name en puntero + 0 @@ -316,7 +327,7 @@ def __str__(self) -> str: sw $t4, 0($v0) # Asigna el tipo String al string sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del string -move $s0 , $v0 + addi $sp, $sp, 4 jr $ra """ @@ -374,28 +385,27 @@ def __str__(self) -> str: String_length: - li $v0,1 - li $a0,4 - syscall - - li $v0,10 - syscall - lw $t4 , ($sp) #self li $t0 , 0 #contador lw $s2 , 4($t4) # propiedad value + loop: lb $s0 , ($s2) + li $v0,4 + beq $s0 , $zero, END add $t0 , $t0 ,1 - add $s2,$s2,4 + add $s2,$s2,1 j loop END: move $s0 , $t0 addi $sp, $sp, 4 + + + jr $ra """ diff --git a/src/test.mips b/src/test.mips index 94bdcb412..c4b7bb654 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,18 +1,27 @@ .data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" Bool_parents: .word 1, 2, 0, -Bool: .word Bool_parents, Object_abort, Object_copy, Object_type_name, +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: .word Int_parents, Object_abort, Object_copy, Object_type_name, +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: .word String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +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: .word SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +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: .word Object_parents, Object_abort, Object_copy, Object_type_name, +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: .word IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +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: .word 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, +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" @@ -20,335 +29,979 @@ string_2: .asciiz "that was a palindrome\n" .text .globl main main: -addi $sp, $sp, -4 #Push local var self stackpointer 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 self 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 +sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion main +#Allocate a una class Main puntero en sp + 8 #atributo type_name en puntero + 0 #atributo i en puntero + 4 li $a0, 8 li $v0, 9 syscall -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, Main -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data -lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -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 +sw $v0, 8($sp) #Guardando en la pila el pintero de la instancia de la clase Main +lw $t0, 8($sp) #Saca de la pila self addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance +sw $t0, 0($sp) #Mete para la pila self +jal new_ctr_Main #Call a la function new_ctr_Main +lw $t0, 8($sp) #Saca de la pila self +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila self 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 +new_ctr_Main: +#Parametro self en stackpoiner + 20 +addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 16 +addi $sp, $sp, -4 #Push local var default_prop@0 stackpointer 12 +addi $sp, $sp, -4 #Push local var type_INT@0 stackpointer 8 +addi $sp, $sp, -4 #Push local var INT_instance@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) #Saca de la pila self +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila self +jal new_ctr_IO #Call a la function new_ctr_IO +la $t0, Main +sw $t0, 16($sp) #Cargando el nombre del tipo desde el data +lw $t0, 20($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 16($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_name@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Assignando el nombre del tipo en el campo type +li $t0, 0 #Guarda el numbero que se va a asignar +sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a default_prop@0 +#Allocate a una class Int puntero en sp + 4 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 4($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 4($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 12($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor default_prop@0 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable default_prop@0 +la $t0, Int +sw $t0, 8($sp) +lw $t0, 4($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable default_prop@0 +lw $t0, 4($sp) #Lee de la pila INT_instance@0 en 4 para assignar +sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a default_prop@0 +lw $t0, 20($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 12($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor default_prop@0 en la direccion de la memoria del la propiedad i del objeto de typo Main +lw $s0, 20($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 24 #Limpia la pila +jr $ra + Main_main: -#Parametro self en stackpoiner + 48 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 44 -addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 40 -addi $sp, $sp, -4 #Push local var result@assing@i@0 stackpointer 36 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 32 -addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 12 +#Parametro self en stackpoiner + 96 +addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 92 +addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 88 +addi $sp, $sp, -4 #Push local var value_int@0 stackpointer 84 +addi $sp, $sp, -4 #Push local var type_INT@0 stackpointer 80 +addi $sp, $sp, -4 #Push local var INT_instance@0 stackpointer 76 +addi $sp, $sp, -4 #Push local var result@assing@i@0 stackpointer 72 +addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var value_string@0 stackpointer 64 +addi $sp, $sp, -4 #Push local var type_STRING@0 stackpointer 60 +addi $sp, $sp, -4 #Push local var STRING_instance@0 stackpointer 56 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 52 +addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 48 +addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 44 +addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 40 +addi $sp, $sp, -4 #Push local var value_string@1 stackpointer 36 +addi $sp, $sp, -4 #Push local var type_STRING@1 stackpointer 32 +addi $sp, $sp, -4 #Push local var STRING_instance@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var param_0_to_out_string@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var value_string@2 stackpointer 20 +addi $sp, $sp, -4 #Push local var type_STRING@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var STRING_instance@2 stackpointer 12 addi $sp, $sp, -4 #Push local var param_0_to_out_string@2 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 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a compl@_unary@0 #Fin de la expresion lista para ser asignada -lw $t0, 48($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta -lw $t1, 36($sp) #Buscando el valor que se va a guardar en la propiedad -sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto -lw $t0, 48($sp) #Buscando la instancia de la clase Main en la pila +sw $t0, 84($sp) #Escribe en la pila el numero que se le asigno a value_int@0 #Int value 1 +#Allocate a una class Int puntero en sp + 76 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 76($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 76($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 84($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@0 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@0 +la $t0, Int +sw $t0, 80($sp) +lw $t0, 76($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 80($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@0 +lw $t0, 76($sp) #Lee de la pila INT_instance@0 en 76 para assignar +sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a compl@_unary@0 +lw $t0, 88($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 88($sp) #Salvando el valor de la propiedad value en la pila en el valor local compl@_unary@0 +li $t0, 4294967295 +lw $t1, 88($sp) +xor $s0, $t0, $t1 +add $s0, $s0, 1 +sw $s0, 72($sp) #Fin de la expresion lista para ser asignada +lw $t0, 96($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 72($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor result@assing@i@0 en la direccion de la memoria del la propiedad i del objeto de typo Main +lw $t0, 96($sp) #Buscando la instancia de la clase Main en la pila lw $t1, 4($t0) #Buscando el valor de la propiedad i -sw $t1, 44($sp) #Salvando el valor de la propiedad i en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block +sw $t1, 92($sp) #Salvando el valor de la propiedad i en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block la $t0, string_0 -sw $t0, 28($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 48($sp) #Saca de la pila self +sw $t0, 64($sp) #Carga la referecia a string +#Allocate a una class String puntero en sp + 56 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 56($sp) #Guardando en la pila el pintero de la instancia de la clase String +lw $t0, 56($sp) #Buscando en la pila la variable STRING_instance@0 y guarda la direccion a la que apunta +lw $t1, 64($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_string@0 en la direccion de la memoria del la propiedad value del objeto de typo String #Setear la propiedad value al STRING en la variable value_string@0 +la $t0, String +sw $t0, 60($sp) +lw $t0, 56($sp) #Buscando en la pila la variable STRING_instance@0 y guarda la direccion a la que apunta +lw $t1, 60($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_STRING@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_string@0 +lw $t0, 56($sp) #Lee de la pila STRING_instance@0 en 56 para assignar +sw $t0, 52($sp) #Escribe en la pila el valor que se le asigno a param_0_to_out_string@0 #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 96($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, 32($sp) #Saca de la pila param_0_to_out_string@0 +lw $t0, 56($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, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block -lw $t0, 48($sp) #Saca de la pila self +sw $s0, 68($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block +lw $t0, 96($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 in_string jal IO_in_string #Call a la function IO_in_string -sw $s0, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal -lw $t0, 48($sp) #Saca de la pila self +sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal +lw $t0, 96($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 pal -lw $t0, 24($sp) #Saca de la pila param_0_to_pal@0 +lw $t0, 48($sp) #Saca de la pila param_0_to_pal@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_pal@0 #Agrega a la pila el paramentro 1 al StaticDispatch pal jal Main_pal #Call a la function Main_pal -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la evaluacion de la condicion de un IF +sw $s0, 48($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la evaluacion de la condicion de un IF +lw $t0, 48($sp) #Buscando la instancia de la clase Bool en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 48($sp) #Salvando el valor de la propiedad value en la pila en el valor local cond@if_else@0 li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 24($sp) #Cargar el valor de la pos 24 a $t1 pa comparar +lw $t1, 48($sp) #Cargar el valor cond@if_else@0 de la pos 48 a $t1 pa comparar beq $t0 $t1 then_Main_main_0 #if $t1==$t0 then jump then_Main_main_0 #Else case la $t0, string_1 -sw $t0, 12($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 48($sp) #Saca de la pila self +sw $t0, 36($sp) #Carga la referecia a string +#Allocate a una class String puntero en sp + 28 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 28($sp) #Guardando en la pila el pintero de la instancia de la clase String +lw $t0, 28($sp) #Buscando en la pila la variable STRING_instance@1 y guarda la direccion a la que apunta +lw $t1, 36($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_string@1 en la direccion de la memoria del la propiedad value del objeto de typo String #Setear la propiedad value al STRING en la variable value_string@1 +la $t0, String +sw $t0, 32($sp) +lw $t0, 28($sp) #Buscando en la pila la variable STRING_instance@1 y guarda la direccion a la que apunta +lw $t1, 32($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_STRING@1 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_string@1 +lw $t0, 28($sp) #Lee de la pila STRING_instance@1 en 28 para assignar +sw $t0, 24($sp) #Escribe en la pila el valor que se le asigno a param_0_to_out_string@1 #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 96($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, 16($sp) #Saca de la pila param_0_to_out_string@1 +lw $t0, 28($sp) #Saca de la pila param_0_to_out_string@1 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #Agrega a la pila el paramentro 1 al StaticDispatch out_string jal IO_out_string #Call a la function IO_out_string -sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -j fin_Main_main_0 #Salta para f{label} +sw $s0, 40($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +j fin_Main_main_0 #Salta para fin_Main_main_0 then_Main_main_0 : #Crea el label then_Main_main_0 #Then case la $t0, string_2 -sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 48($sp) #Saca de la pila self +sw $t0, 20($sp) #Carga la referecia a string +#Allocate a una class String puntero en sp + 12 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 12($sp) #Guardando en la pila el pintero de la instancia de la clase String +lw $t0, 12($sp) #Buscando en la pila la variable STRING_instance@2 y guarda la direccion a la que apunta +lw $t1, 20($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_string@2 en la direccion de la memoria del la propiedad value del objeto de typo String #Setear la propiedad value al STRING en la variable value_string@2 +la $t0, String +sw $t0, 16($sp) +lw $t0, 12($sp) #Buscando en la pila la variable STRING_instance@2 y guarda la direccion a la que apunta +lw $t1, 16($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_STRING@2 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_string@2 +lw $t0, 12($sp) #Lee de la pila STRING_instance@2 en 12 para assignar +sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a param_0_to_out_string@2 #Fin del paramentro 0 al StaticDispatch out_string +lw $t0, 96($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@2 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@2 #Agrega a la pila el paramentro 1 al StaticDispatch out_string jal IO_out_string #Call a la function IO_out_string -sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +sw $s0, 40($sp) #Save el resultado de la funcion que esta en $s0 pa la pila fin_Main_main_0 : #Crea el label fin_Main_main_0 #Fin de un If -lw $t0, 16($sp) #Lee de la pila result@if@0 en 16 para assignar +lw $t0, 40($sp) #Lee de la pila result@if@0 en 40 para assignar sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 52 #Limpia la pila +addi $sp, $sp, 100 #Limpia la pila jr $ra #Final de la function main +new_ctr_IO: +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var type_name@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_IO +lw $t0, 8($sp) #Saca de la pila self +addi $sp, $sp, -4 +sw $t0, 0($sp) #Mete para la pila self +jal new_ctr_Object #Call a la function new_ctr_Object +la $t0, IO +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 4($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_name@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Assignando el nombre del tipo en el campo type +lw $s0, 8($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 #Limpia la pila +jr $ra + IO_out_string: + +lw $t1 , 4($sp) +lw $t0, 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 -lw $a0, 0($sp) +lw $a0, 4($t0) #Pintando la propiedad value del string syscall -lw $a0, 4($sp) addi $sp, $sp, 8 +move $s0, $t1 jr $ra IO_in_string: -li $v0,8 +li $v0, 8 li $a1 , 10000 syscall -move $s0 , $a0 +move $t6 ,$v0 + + li $v0 ,4 + move $a0,$t6 + syscall + + li $v0,10 + syscall + + +move $s0 , $v0 + +#Allocate a una class String puntero en sp + 12 +#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 $t4, String +sw $t4, 0($v0) # Asigna el tipo String al string +sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del string + + addi $sp, $sp, 4 jr $ra Main_pal: -#Parametro self en stackpoiner + 132 -#Parametro s@0 en stackpoiner + 128 -addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 124 -addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 120 -addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 116 -addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 112 -addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 108 -addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 104 -addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 100 -addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 96 -addi $sp, $sp, -4 #Push local var instance_to_call_length@1 stackpointer 92 -addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 88 -addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 84 -addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 80 -addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 76 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 72 -addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 68 -addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@1 stackpointer 60 -addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 52 -addi $sp, $sp, -4 #Push local var instance_to_call_length@2 stackpointer 48 -addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 44 -addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 40 -addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 36 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@2 stackpointer 32 -addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 28 -addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 24 -addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 20 -addi $sp, $sp, -4 #Push local var instance_to_call_length@3 stackpointer 16 -addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 12 -addi $sp, $sp, -4 #Push local var param_0_to_pal@0 stackpointer 8 +#Parametro self en stackpoiner + 324 +#Parametro s@0 en stackpoiner + 320 +addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 316 +addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 312 +addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 308 +addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 304 +addi $sp, $sp, -4 #Push local var value_int@0 stackpointer 300 +addi $sp, $sp, -4 #Push local var type_INT@0 stackpointer 296 +addi $sp, $sp, -4 #Push local var INT_instance@0 stackpointer 292 +addi $sp, $sp, -4 #Push local var int_eq@_result@0 stackpointer 288 +addi $sp, $sp, -4 #Push local var type_INT@1 stackpointer 284 +addi $sp, $sp, -4 #Push local var INT_instance@1 stackpointer 280 +addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 276 +addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 272 +addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 268 +addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 264 +addi $sp, $sp, -4 #Push local var instance_to_call_length@1 stackpointer 260 +addi $sp, $sp, -4 #Push local var value_int@1 stackpointer 256 +addi $sp, $sp, -4 #Push local var type_INT@2 stackpointer 252 +addi $sp, $sp, -4 #Push local var INT_instance@2 stackpointer 248 +addi $sp, $sp, -4 #Push local var int_eq@_result@1 stackpointer 244 +addi $sp, $sp, -4 #Push local var type_INT@3 stackpointer 240 +addi $sp, $sp, -4 #Push local var INT_instance@3 stackpointer 236 +addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 232 +addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 228 +addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 224 +addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 220 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 216 +addi $sp, $sp, -4 #Push local var value_int@2 stackpointer 212 +addi $sp, $sp, -4 #Push local var type_INT@4 stackpointer 208 +addi $sp, $sp, -4 #Push local var INT_instance@4 stackpointer 204 +addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 200 +addi $sp, $sp, -4 #Push local var value_int@3 stackpointer 196 +addi $sp, $sp, -4 #Push local var type_INT@5 stackpointer 192 +addi $sp, $sp, -4 #Push local var INT_instance@5 stackpointer 188 +addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 184 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@1 stackpointer 180 +addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 176 +addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 172 +addi $sp, $sp, -4 #Push local var instance_to_call_length@2 stackpointer 168 +addi $sp, $sp, -4 #Push local var value_int@4 stackpointer 164 +addi $sp, $sp, -4 #Push local var type_INT@6 stackpointer 160 +addi $sp, $sp, -4 #Push local var INT_instance@6 stackpointer 156 +addi $sp, $sp, -4 #Push local var rest@_result@0 stackpointer 152 +addi $sp, $sp, -4 #Push local var type_INT@7 stackpointer 148 +addi $sp, $sp, -4 #Push local var INT_instance@7 stackpointer 144 +addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 140 +addi $sp, $sp, -4 #Push local var value_int@5 stackpointer 136 +addi $sp, $sp, -4 #Push local var type_INT@8 stackpointer 132 +addi $sp, $sp, -4 #Push local var INT_instance@8 stackpointer 128 +addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 124 +addi $sp, $sp, -4 #Push local var int_eq@_result@2 stackpointer 120 +addi $sp, $sp, -4 #Push local var type_INT@9 stackpointer 116 +addi $sp, $sp, -4 #Push local var INT_instance@9 stackpointer 112 +addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 108 +addi $sp, $sp, -4 #Push local var value_boolean@0 stackpointer 104 +addi $sp, $sp, -4 #Push local var type_BOOL@0 stackpointer 100 +addi $sp, $sp, -4 #Push local var BOOL_instance@0 stackpointer 96 +addi $sp, $sp, -4 #Push local var instance_to_call_substr@2 stackpointer 92 +addi $sp, $sp, -4 #Push local var value_int@6 stackpointer 88 +addi $sp, $sp, -4 #Push local var type_INT@10 stackpointer 84 +addi $sp, $sp, -4 #Push local var INT_instance@10 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@1 stackpointer 72 +addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 68 +addi $sp, $sp, -4 #Push local var instance_to_call_length@3 stackpointer 64 +addi $sp, $sp, -4 #Push local var value_int@7 stackpointer 60 +addi $sp, $sp, -4 #Push local var type_INT@11 stackpointer 56 +addi $sp, $sp, -4 #Push local var INT_instance@11 stackpointer 52 +addi $sp, $sp, -4 #Push local var rest@_result@1 stackpointer 48 +addi $sp, $sp, -4 #Push local var type_INT@12 stackpointer 44 +addi $sp, $sp, -4 #Push local var INT_instance@12 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_pal@0 stackpointer 32 +addi $sp, $sp, -4 #Push local var value_boolean@1 stackpointer 28 +addi $sp, $sp, -4 #Push local var type_BOOL@1 stackpointer 24 +addi $sp, $sp, -4 #Push local var BOOL_instance@1 stackpointer 20 +addi $sp, $sp, -4 #Push local var value_boolean@2 stackpointer 16 +addi $sp, $sp, -4 #Push local var type_BOOL@2 stackpointer 12 +addi $sp, $sp, -4 #Push local var BOOL_instance@2 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_pal -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 112($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length -lw $t0, 112($sp) #Saca de la pila instance_to_call_length@0 +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 304($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length +lw $t0, 304($sp) #Saca de la pila instance_to_call_length@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_length@0 -lw $t0, 116($sp) #Sacando la instancia de la pila (en 112) de una clase que hereda de String +lw $t0, 308($sp) #Sacando la instancia de la pila (en 304) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length - -li $v0 , 10 -syscall - +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length jal $t3 #Call a la function $t3 -sw $s0, 120($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +sw $s0, 312($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 312($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 312($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_a@0 li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 116($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 120($sp) #carga en $t1 lo que hay en 120 -lw $t2, 116($sp) #carga en $t2 lo que hay en 116 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 124($sp) #Pon en la posicion 124 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +sw $t0, 300($sp) #Escribe en la pila el numero que se le asigno a value_int@0 #Int value 0 +#Allocate a una class Int puntero en sp + 292 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 292($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 292($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 300($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@0 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@0 +la $t0, Int +sw $t0, 296($sp) +lw $t0, 292($sp) #Buscando en la pila la variable INT_instance@0 y guarda la direccion a la que apunta +lw $t1, 296($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@0 +lw $t0, 292($sp) #Lee de la pila INT_instance@0 en 292 para assignar +sw $t0, 308($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq +lw $t0, 308($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 308($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_b@0 +lw $t1, 312($sp) #carga en $t1 int_eq@_a@0 de la pos 312 +lw $t2, 308($sp) #carga en $t2 int_eq@_b@0 de la pos 308 +seq $t3, $t2, $t1 #$t3 = int_eq@_a@0 $t0 == int_eq@_b@0 $ t1 +sw $t3, 288($sp) #Pon en la posicion 288 el valor de $t3 +#Allocate a una class Int puntero en sp + 280 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 280($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 280($sp) #Buscando en la pila la variable INT_instance@1 y guarda la direccion a la que apunta +lw $t1, 288($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor int_eq@_result@0 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable int_eq@_result@0 +la $t0, Int +sw $t0, 284($sp) +lw $t0, 280($sp) #Buscando en la pila la variable INT_instance@1 y guarda la direccion a la que apunta +lw $t1, 284($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@1 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable int_eq@_result@0 +lw $t0, 280($sp) #Lee de la pila INT_instance@1 en 280 para assignar +sw $t0, 316($sp) #Escribe en la pila el valor que se le asigno a cond@if_else@0 #Fin de la evaluacion de la condicion de un IF +lw $t0, 316($sp) #Buscando la instancia de la clase Bool en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 316($sp) #Salvando el valor de la propiedad value en la pila en el valor local cond@if_else@0 li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 124($sp) #Cargar el valor de la pos 124 a $t1 pa comparar +lw $t1, 316($sp) #Cargar el valor cond@if_else@0 de la pos 316 a $t1 pa comparar beq $t0 $t1 then_Main_pal_0 #if $t1==$t0 then jump then_Main_pal_0 #Else case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 92($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@1 #Fin de la exprecion previa al Dispatch length -lw $t0, 92($sp) #Saca de la pila instance_to_call_length@1 +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 260($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@1 #Fin de la exprecion previa al Dispatch length +lw $t0, 260($sp) #Saca de la pila instance_to_call_length@1 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_length@1 -lw $t0, 96($sp) #Sacando la instancia de la pila (en 92) de una clase que hereda de String +lw $t0, 264($sp) #Sacando la instancia de la pila (en 260) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length jal $t3 #Call a la function $t3 -sw $s0, 100($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +sw $s0, 268($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 268($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 268($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_a@1 li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 96($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 100($sp) #carga en $t1 lo que hay en 100 -lw $t2, 96($sp) #carga en $t2 lo que hay en 96 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 104($sp) #Pon en la posicion 104 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +sw $t0, 256($sp) #Escribe en la pila el numero que se le asigno a value_int@1 #Int value 1 +#Allocate a una class Int puntero en sp + 248 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 248($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 248($sp) #Buscando en la pila la variable INT_instance@2 y guarda la direccion a la que apunta +lw $t1, 256($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@1 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@1 +la $t0, Int +sw $t0, 252($sp) +lw $t0, 248($sp) #Buscando en la pila la variable INT_instance@2 y guarda la direccion a la que apunta +lw $t1, 252($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@2 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@1 +lw $t0, 248($sp) #Lee de la pila INT_instance@2 en 248 para assignar +sw $t0, 264($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq +lw $t0, 264($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 264($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_b@1 +lw $t1, 268($sp) #carga en $t1 int_eq@_a@1 de la pos 268 +lw $t2, 264($sp) #carga en $t2 int_eq@_b@1 de la pos 264 +seq $t3, $t2, $t1 #$t3 = int_eq@_a@1 $t0 == int_eq@_b@1 $ t1 +sw $t3, 244($sp) #Pon en la posicion 244 el valor de $t3 +#Allocate a una class Int puntero en sp + 236 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 236($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 236($sp) #Buscando en la pila la variable INT_instance@3 y guarda la direccion a la que apunta +lw $t1, 244($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor int_eq@_result@1 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable int_eq@_result@1 +la $t0, Int +sw $t0, 240($sp) +lw $t0, 236($sp) #Buscando en la pila la variable INT_instance@3 y guarda la direccion a la que apunta +lw $t1, 240($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@3 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable int_eq@_result@1 +lw $t0, 236($sp) #Lee de la pila INT_instance@3 en 236 para assignar +sw $t0, 272($sp) #Escribe en la pila el valor que se le asigno a cond@if_else@1 #Fin de la evaluacion de la condicion de un IF +lw $t0, 272($sp) #Buscando la instancia de la clase Bool en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 272($sp) #Salvando el valor de la propiedad value en la pila en el valor local cond@if_else@1 li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 104($sp) #Cargar el valor de la pos 104 a $t1 pa comparar +lw $t1, 272($sp) #Cargar el valor cond@if_else@1 de la pos 272 a $t1 pa comparar beq $t0 $t1 then_Main_pal_1 #if $t1==$t0 then jump then_Main_pal_1 #Else case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 216($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 68($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr +sw $t0, 212($sp) #Escribe en la pila el numero que se le asigno a value_int@2 #Int value 0 +#Allocate a una class Int puntero en sp + 204 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 204($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 204($sp) #Buscando en la pila la variable INT_instance@4 y guarda la direccion a la que apunta +lw $t1, 212($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@2 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@2 +la $t0, Int +sw $t0, 208($sp) +lw $t0, 204($sp) #Buscando en la pila la variable INT_instance@4 y guarda la direccion a la que apunta +lw $t1, 208($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@4 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@2 +lw $t0, 204($sp) #Lee de la pila INT_instance@4 en 204 para assignar +sw $t0, 200($sp) #Escribe en la pila el valor que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 64($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr -lw $t0, 72($sp) #Saca de la pila instance_to_call_substr@0 +sw $t0, 196($sp) #Escribe en la pila el numero que se le asigno a value_int@3 #Int value 1 +#Allocate a una class Int puntero en sp + 188 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 188($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 188($sp) #Buscando en la pila la variable INT_instance@5 y guarda la direccion a la que apunta +lw $t1, 196($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@3 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@3 +la $t0, Int +sw $t0, 192($sp) +lw $t0, 188($sp) #Buscando en la pila la variable INT_instance@5 y guarda la direccion a la que apunta +lw $t1, 192($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@5 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@3 +lw $t0, 188($sp) #Lee de la pila INT_instance@5 en 188 para assignar +sw $t0, 184($sp) #Escribe en la pila el valor que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr +lw $t0, 216($sp) #Saca de la pila instance_to_call_substr@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@0 -lw $t0, 72($sp) #Saca de la pila param_0_to_substr@0 +lw $t0, 204($sp) #Saca de la pila param_0_to_substr@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_substr@0 -lw $t0, 72($sp) #Saca de la pila param_1_to_substr@0 +lw $t0, 192($sp) #Saca de la pila param_1_to_substr@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_1_to_substr@0 -lw $t0, 84($sp) #Sacando la instancia de la pila (en 72) de una clase que hereda de String +lw $t0, 228($sp) #Sacando la instancia de la pila (en 216) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr jal $t3 #Call a la function $t3 -li $s0 ,3 -sw $s0, 80($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@1 #Fin de la exprecion previa al Dispatch substr -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@2 #Fin de la exprecion previa al Dispatch length -lw $t0, 48($sp) #Saca de la pila instance_to_call_length@2 +sw $s0, 224($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq +lw $t0, 224($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 224($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_a@2 +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 180($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@1 #Fin de la exprecion previa al Dispatch substr +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 168($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@2 #Fin de la exprecion previa al Dispatch length +lw $t0, 168($sp) #Saca de la pila instance_to_call_length@2 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_length@2 -lw $t0, 52($sp) #Sacando la instancia de la pila (en 48) de una clase que hereda de String +lw $t0, 172($sp) #Sacando la instancia de la pila (en 168) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length jal $t3 #Call a la function $t3 -sw $s0, 56($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +sw $s0, 176($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +lw $t0, 176($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 176($sp) #Salvando el valor de la propiedad value en la pila en el valor local rest@_a@0 li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 56($sp) #poner en registro $t0 lo que hay en 56 -lw $t1, 52($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 44($sp) #poner en 44 el resultado de la suma #Fin del paramentro 0 al Dispatch substr +sw $t0, 164($sp) #Escribe en la pila el numero que se le asigno a value_int@4 #Int value 1 +#Allocate a una class Int puntero en sp + 156 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 156($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 156($sp) #Buscando en la pila la variable INT_instance@6 y guarda la direccion a la que apunta +lw $t1, 164($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@4 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@4 +la $t0, Int +sw $t0, 160($sp) +lw $t0, 156($sp) #Buscando en la pila la variable INT_instance@6 y guarda la direccion a la que apunta +lw $t1, 160($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@6 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@4 +lw $t0, 156($sp) #Lee de la pila INT_instance@6 en 156 para assignar +sw $t0, 172($sp) #Escribe en la pila el valor que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest +lw $t0, 172($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 172($sp) #Salvando el valor de la propiedad value en la pila en el valor local rest@_b@0 +lw $t0, 176($sp) #poner en registro $t0 rest@_a@0 lo que hay en 176 +lw $t1, 172($sp) #poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la RESTA +sw $t0, 152($sp) #poner en 152 el resultado de la RESTA +#Allocate a una class Int puntero en sp + 144 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 144($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 144($sp) #Buscando en la pila la variable INT_instance@7 y guarda la direccion a la que apunta +lw $t1, 152($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor rest@_result@0 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable rest@_result@0 +la $t0, Int +sw $t0, 148($sp) +lw $t0, 144($sp) #Buscando en la pila la variable INT_instance@7 y guarda la direccion a la que apunta +lw $t1, 148($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@7 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable rest@_result@0 +lw $t0, 144($sp) #Lee de la pila INT_instance@7 en 144 para assignar +sw $t0, 140($sp) #Escribe en la pila el valor que se le asigno a param_0_to_substr@1 #Fin del paramentro 0 al Dispatch substr li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@1 #Fin del paramentro 1 al Dispatch substr -lw $t0, 60($sp) #Saca de la pila instance_to_call_substr@1 +sw $t0, 136($sp) #Escribe en la pila el numero que se le asigno a value_int@5 #Int value 1 +#Allocate a una class Int puntero en sp + 128 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 128($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 128($sp) #Buscando en la pila la variable INT_instance@8 y guarda la direccion a la que apunta +lw $t1, 136($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@5 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@5 +la $t0, Int +sw $t0, 132($sp) +lw $t0, 128($sp) #Buscando en la pila la variable INT_instance@8 y guarda la direccion a la que apunta +lw $t1, 132($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@8 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@5 +lw $t0, 128($sp) #Lee de la pila INT_instance@8 en 128 para assignar +sw $t0, 124($sp) #Escribe en la pila el valor que se le asigno a param_1_to_substr@1 #Fin del paramentro 1 al Dispatch substr +lw $t0, 180($sp) #Saca de la pila instance_to_call_substr@1 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@1 -lw $t0, 48($sp) #Saca de la pila param_0_to_substr@1 +lw $t0, 144($sp) #Saca de la pila param_0_to_substr@1 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_substr@1 -lw $t0, 48($sp) #Saca de la pila param_1_to_substr@1 +lw $t0, 132($sp) #Saca de la pila param_1_to_substr@1 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_1_to_substr@1 -lw $t0, 72($sp) #Sacando la instancia de la pila (en 60) de una clase que hereda de String +lw $t0, 192($sp) #Sacando la instancia de la pila (en 180) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr jal $t3 #Call a la function $t3 -sw $s0, 76($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq -lw $t1, 80($sp) #carga en $t1 lo que hay en 80 -lw $t2, 76($sp) #carga en $t2 lo que hay en 76 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 84($sp) #Pon en la posicion 84 el valor de $t3 #Fin de la evaluacion de la condicion de un IF +sw $s0, 220($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq +lw $t0, 220($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 220($sp) #Salvando el valor de la propiedad value en la pila en el valor local int_eq@_b@2 +lw $t1, 224($sp) #carga en $t1 int_eq@_a@2 de la pos 224 +lw $t2, 220($sp) #carga en $t2 int_eq@_b@2 de la pos 220 +seq $t3, $t2, $t1 #$t3 = int_eq@_a@2 $t0 == int_eq@_b@2 $ t1 +sw $t3, 120($sp) #Pon en la posicion 120 el valor de $t3 +#Allocate a una class Int puntero en sp + 112 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 112($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 112($sp) #Buscando en la pila la variable INT_instance@9 y guarda la direccion a la que apunta +lw $t1, 120($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor int_eq@_result@2 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable int_eq@_result@2 +la $t0, Int +sw $t0, 116($sp) +lw $t0, 112($sp) #Buscando en la pila la variable INT_instance@9 y guarda la direccion a la que apunta +lw $t1, 116($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@9 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable int_eq@_result@2 +lw $t0, 112($sp) #Lee de la pila INT_instance@9 en 112 para assignar +sw $t0, 228($sp) #Escribe en la pila el valor que se le asigno a cond@if_else@2 #Fin de la evaluacion de la condicion de un IF +lw $t0, 228($sp) #Buscando la instancia de la clase Bool en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 228($sp) #Salvando el valor de la propiedad value en la pila en el valor local cond@if_else@2 li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 84($sp) #Cargar el valor de la pos 84 a $t1 pa comparar +lw $t1, 228($sp) #Cargar el valor cond@if_else@2 de la pos 228 a $t1 pa comparar beq $t0 $t1 then_Main_pal_2 #if $t1==$t0 then jump then_Main_pal_2 #Else case li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 36($sp) #Escribe en la pila el numero que se le asigno a result@if@2 -j fin_Main_pal_2 #Salta para f{label} +sw $t0, 104($sp) #Escribe en la pila el numero que se le asigno a value_boolean@0 #Bool value false +#Allocate a una class Bool puntero en sp + 96 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 96($sp) #Guardando en la pila el pintero de la instancia de la clase Bool +lw $t0, 96($sp) #Buscando en la pila la variable BOOL_instance@0 y guarda la direccion a la que apunta +lw $t1, 104($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_boolean@0 en la direccion de la memoria del la propiedad value del objeto de typo Bool #Setear la propiedad value al BOOL en la variable value_boolean@0 +la $t0, Bool +sw $t0, 100($sp) +lw $t0, 96($sp) #Buscando en la pila la variable BOOL_instance@0 y guarda la direccion a la que apunta +lw $t1, 100($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_BOOL@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_boolean@0 +lw $t0, 96($sp) #Lee de la pila BOOL_instance@0 en 96 para assignar +sw $t0, 108($sp) #Escribe en la pila el valor que se le asigno a result@if@2 +j fin_Main_pal_2 #Salta para fin_Main_pal_2 then_Main_pal_2 : #Crea el label then_Main_pal_2 #Then case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 32($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@2 #Fin de la exprecion previa al Dispatch substr +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 92($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@2 #Fin de la exprecion previa al Dispatch substr li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@2 #Fin del paramentro 0 al Dispatch substr -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@3 #Fin de la exprecion previa al Dispatch length -lw $t0, 16($sp) #Saca de la pila instance_to_call_length@3 +sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a value_int@6 #Int value 1 +#Allocate a una class Int puntero en sp + 80 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 80($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 80($sp) #Buscando en la pila la variable INT_instance@10 y guarda la direccion a la que apunta +lw $t1, 88($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@6 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@6 +la $t0, Int +sw $t0, 84($sp) +lw $t0, 80($sp) #Buscando en la pila la variable INT_instance@10 y guarda la direccion a la que apunta +lw $t1, 84($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@10 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@6 +lw $t0, 80($sp) #Lee de la pila INT_instance@10 en 80 para assignar +sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a param_0_to_substr@2 #Fin del paramentro 0 al Dispatch substr +lw $t0, 320($sp) #Lee de la pila s@0 en 320 para assignar +sw $t0, 64($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@3 #Fin de la exprecion previa al Dispatch length +lw $t0, 64($sp) #Saca de la pila instance_to_call_length@3 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_length@3 -lw $t0, 20($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String +lw $t0, 68($sp) #Sacando la instancia de la pila (en 64) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +lw $t3, 28($t1) #Buscando el metodo dinamico para la funcion length jal $t3 #Call a la function $t3 -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +sw $s0, 72($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest +lw $t0, 72($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 72($sp) #Salvando el valor de la propiedad value en la pila en el valor local rest@_a@1 li $t0, 2 #Guarda el numbero que se va a asignar -sw $t0, 20($sp) #Escribe en la pila el numero que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest -lw $t0, 24($sp) #poner en registro $t0 lo que hay en 24 -lw $t1, 20($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 12($sp) #poner en 12 el resultado de la suma #Fin del paramentro 1 al Dispatch substr -lw $t0, 32($sp) #Saca de la pila instance_to_call_substr@2 +sw $t0, 60($sp) #Escribe en la pila el numero que se le asigno a value_int@7 #Int value 2 +#Allocate a una class Int puntero en sp + 52 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 52($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 52($sp) #Buscando en la pila la variable INT_instance@11 y guarda la direccion a la que apunta +lw $t1, 60($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_int@7 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable value_int@7 +la $t0, Int +sw $t0, 56($sp) +lw $t0, 52($sp) #Buscando en la pila la variable INT_instance@11 y guarda la direccion a la que apunta +lw $t1, 56($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@11 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_int@7 +lw $t0, 52($sp) #Lee de la pila INT_instance@11 en 52 para assignar +sw $t0, 68($sp) #Escribe en la pila el valor que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest +lw $t0, 68($sp) #Buscando la instancia de la clase Int en la pila +lw $t1, 4($t0) #Buscando el valor de la propiedad value +sw $t1, 68($sp) #Salvando el valor de la propiedad value en la pila en el valor local rest@_b@1 +lw $t0, 72($sp) #poner en registro $t0 rest@_a@1 lo que hay en 72 +lw $t1, 68($sp) #poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2} +sub $t0, $t0, $t1 #poner en registro $t0 la RESTA +sw $t0, 48($sp) #poner en 48 el resultado de la RESTA +#Allocate a una class Int puntero en sp + 40 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 40($sp) #Guardando en la pila el pintero de la instancia de la clase Int +lw $t0, 40($sp) #Buscando en la pila la variable INT_instance@12 y guarda la direccion a la que apunta +lw $t1, 48($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor rest@_result@1 en la direccion de la memoria del la propiedad value del objeto de typo Int #Setear la propiedad value al INT en la variable rest@_result@1 +la $t0, Int +sw $t0, 44($sp) +lw $t0, 40($sp) #Buscando en la pila la variable INT_instance@12 y guarda la direccion a la que apunta +lw $t1, 44($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_INT@12 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable rest@_result@1 +lw $t0, 40($sp) #Lee de la pila INT_instance@12 en 40 para assignar +sw $t0, 36($sp) #Escribe en la pila el valor que se le asigno a param_1_to_substr@2 #Fin del paramentro 1 al Dispatch substr +lw $t0, 92($sp) #Saca de la pila instance_to_call_substr@2 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@2 -lw $t0, 32($sp) #Saca de la pila param_0_to_substr@2 +lw $t0, 80($sp) #Saca de la pila param_0_to_substr@2 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_substr@2 -lw $t0, 20($sp) #Saca de la pila param_1_to_substr@2 +lw $t0, 44($sp) #Saca de la pila param_1_to_substr@2 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_1_to_substr@2 -lw $t0, 44($sp) #Sacando la instancia de la pila (en 32) de una clase que hereda de String +lw $t0, 104($sp) #Sacando la instancia de la pila (en 92) de una clase que hereda de String lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr +lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion substr jal $t3 #Call a la function $t3 -sw $s0, 8($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal -lw $t0, 132($sp) #Saca de la pila self +sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal +lw $t0, 324($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 pal -lw $t0, 12($sp) #Saca de la pila param_0_to_pal@0 +lw $t0, 36($sp) #Saca de la pila param_0_to_pal@0 addi $sp, $sp, -4 sw $t0, 0($sp) #Mete para la pila param_0_to_pal@0 #Agrega a la pila el paramentro 1 al StaticDispatch pal jal Main_pal #Call a la function Main_pal -sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila +sw $s0, 108($sp) #Save el resultado de la funcion que esta en $s0 pa la pila fin_Main_pal_2 : #Crea el label fin_Main_pal_2 #Fin de un If -lw $t0, 36($sp) #Lee de la pila result@if@2 en 36 para assignar -sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a result@if@1 -j fin_Main_pal_1 #Salta para f{label} +lw $t0, 108($sp) #Lee de la pila result@if@2 en 108 para assignar +sw $t0, 232($sp) #Escribe en la pila el valor que se le asigno a result@if@1 +j fin_Main_pal_1 #Salta para fin_Main_pal_1 then_Main_pal_1 : #Crea el label then_Main_pal_1 #Then case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a result@if@1 +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a value_boolean@1 #Bool value true +#Allocate a una class Bool puntero en sp + 20 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 20($sp) #Guardando en la pila el pintero de la instancia de la clase Bool +lw $t0, 20($sp) #Buscando en la pila la variable BOOL_instance@1 y guarda la direccion a la que apunta +lw $t1, 28($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_boolean@1 en la direccion de la memoria del la propiedad value del objeto de typo Bool #Setear la propiedad value al BOOL en la variable value_boolean@1 +la $t0, Bool +sw $t0, 24($sp) +lw $t0, 20($sp) #Buscando en la pila la variable BOOL_instance@1 y guarda la direccion a la que apunta +lw $t1, 24($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_BOOL@1 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_boolean@1 +lw $t0, 20($sp) #Lee de la pila BOOL_instance@1 en 20 para assignar +sw $t0, 232($sp) #Escribe en la pila el valor que se le asigno a result@if@1 fin_Main_pal_1 : #Crea el label fin_Main_pal_1 #Fin de un If -lw $t0, 88($sp) #Lee de la pila result@if@1 en 88 para assignar -sw $t0, 108($sp) #Escribe en la pila el valor que se le asigno a result@if@0 -j fin_Main_pal_0 #Salta para f{label} +lw $t0, 232($sp) #Lee de la pila result@if@1 en 232 para assignar +sw $t0, 276($sp) #Escribe en la pila el valor que se le asigno a result@if@0 +j fin_Main_pal_0 #Salta para fin_Main_pal_0 then_Main_pal_0 : #Crea el label then_Main_pal_0 #Then case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 108($sp) #Escribe en la pila el numero que se le asigno a result@if@0 +li $t0, 1 #Guarda el numbero que se va a asignar +sw $t0, 16($sp) #Escribe en la pila el numero que se le asigno a value_boolean@2 #Bool value true +#Allocate a una class Bool puntero en sp + 8 +#atributo type_name en puntero + 0 +#atributo value en puntero + 4 +li $a0, 8 +li $v0, 9 +syscall +sw $v0, 8($sp) #Guardando en la pila el pintero de la instancia de la clase Bool +lw $t0, 8($sp) #Buscando en la pila la variable BOOL_instance@2 y guarda la direccion a la que apunta +lw $t1, 16($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 4($t0) #Seteando el valor value_boolean@2 en la direccion de la memoria del la propiedad value del objeto de typo Bool #Setear la propiedad value al BOOL en la variable value_boolean@2 +la $t0, Bool +sw $t0, 12($sp) +lw $t0, 8($sp) #Buscando en la pila la variable BOOL_instance@2 y guarda la direccion a la que apunta +lw $t1, 12($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_BOOL@2 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Setear la propiedad type_name al string en la variable value_boolean@2 +lw $t0, 8($sp) #Lee de la pila BOOL_instance@2 en 8 para assignar +sw $t0, 276($sp) #Escribe en la pila el valor que se le asigno a result@if@0 fin_Main_pal_0 : #Crea el label fin_Main_pal_0 #Fin de un If -lw $t0, 108($sp) #Lee de la pila result@if@0 en 108 para assignar +lw $t0, 276($sp) #Lee de la pila result@if@0 en 276 para assignar sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 136 #Limpia la pila +addi $sp, $sp, 328 #Limpia la pila jr $ra #Final de la function pal +new_ctr_Object: +#Parametro self en stackpoiner + 8 +addi $sp, $sp, -4 #Push local var type_name@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_Object +la $t0, Object +sw $t0, 4($sp) #Cargando el nombre del tipo desde el data +lw $t0, 8($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta +lw $t1, 4($sp) #Buscando el valor que se va a guardar en la propiedad +sw $t1, 0($t0) #Seteando el valor type_name@0 en la direccion de la memoria del la propiedad type_name del objeto de typo SELF #Assignando el nombre del tipo en el campo type +lw $s0, 8($sp) #Envia el resultado de la funcion en $s0 +lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior +addi $sp, $sp, 12 #Limpia la pila +jr $ra + + + + String_length: + + lw $t4 , ($sp) #self + li $t0 , 0 #contador + lw $s2 , 4($t4) # propiedad value + + + loop: + lb $s0 , ($s2) + li $v0,4 + + beq $s0 , $zero, END + add $t0 , $t0 ,1 + add $s2,$s2,1 + j loop + + + END: + move $s0 , $t0 + addi $sp, $sp, 4 + + + + jr $ra + + +String_substr: + + li $t0 ,0 + li $s6 ,1 + lw $s1 , 4($sp) # guarda el indice + lw $t4 , ($sp) # guarda el j + lw $s5 , 8($sp) # self. + lw $s3 , 4($s5) # tomar la propiedad value del string + #add $a0 , $s1 , $t4 #tamano a reservar + + li $a0,8 + + li $v0 , 9 + syscall + + move $t7 , $v0 # $t4 direciion de destino + move $t5 , $v0 #guarde la dir de la clase string # + la $s7 , String #primer atributo de la calse + sw $s7 , ($t5) + add $t5,$t5,4 #posicion de la direccion del valor del string + + + li $a0 ,100 + li $v0,9 + syscall #genere espacio para crear string + move $s4,$v0 + + + find_index: + beq $t0, $s1, find_length # if $t0 == $s1 then estas en el indice + add $s3, $s3, 1 #s2 = s2 + 1 + add $t0, $t0, 1 # $t0 = $t0 + 1 + + j find_index + + find_length: + lb $t1, ($s3) # + sb $t1, ($s4) + beq $s6, $t4, END_Substring # if $t0 == $t1 then target + add $s4, $s4, 1 # $S4 = s41 1t2 # + add $s3, $s3, 1 #s2 = s2 + 1 + add $s6, $s6, 1 # $t0 = $t0 + 1 + j find_length + + END_Substring: + move $s0 , $v0 + sw $s0 , ($t5) + move $s0 , $t7 + 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_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 + From 22583f65716c2c6e137ee2bfeea4c59f850ab08b Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 17:10:32 -0500 Subject: [PATCH 76/91] acm --- .../v0_type_data_code/type_data_code_visitor.py | 2 +- .../codegen/v1_mips_generate/mipsgenerate.py | 7 +++++-- .../codegen/v1_mips_generate/mipsgenerate_ast.py | 11 ++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 0b5764420..72c0c2071 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -151,7 +151,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): self.new_type_func.expr[-1].set_value(default) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], default)) else: - null = self.new_type_func.local_push('null') + null = self.new_type_func.local_push('null', scope) self.new_type_func.expr_push(ASTR.Load(null, '_______null_______')) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], null)) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 1f7f8f1db..05e211bb1 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -13,8 +13,11 @@ def __init__(self, errors) -> None: "IO_out_int":ASTR.Out_Int, "String_length":ASTR.Length, #"String_length":ASTR.Length, - "String_concat":1, - "String_substr":1, + "String_concat": ASTR.Concat, + + + "String_substr":ASTR.SubStr +, "Object_copy": ASTR.Copy, "Object_type_name":ASTR.Type_Name, "Object_abort": ASTR.Abort, diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index acf769039..415609ff0 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -274,7 +274,6 @@ class Out_String: def __str__(self) -> str: return """ IO_out_string: - lw $t1 , 4($sp) #Guardando self lw $t0, 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 @@ -457,8 +456,10 @@ def __str__(self) -> str: return """ String_substr: lw $s5, 8($sp) # self. -lw $s1, 4($sp) # guarda el indice -lw $t4, ($sp) #guarda el j +lw $t0, 4($sp) # lee el int indice +lw $s1, 4($t0) # guarda el value de indece +lw $t0, ($sp) # lee el int j +lw $t4, 4($t0) # guarda el value de indece li $t0, 0 # Inicia el contador en 0 li $s6, 1 # Contador de tamaño @@ -476,8 +477,8 @@ def __str__(self) -> str: li $a0,8 li $v0 , 9 syscall -la $t4, String -sw $t4, 0($v0) # Asigna el tipo String al string +la $t9, String +sw $t9, 0($v0) # Asigna el tipo String al string sw $s4, 4($v0) # Asigan el nombre de la clase a la propiededa value del string From f6e014b8b9ad493b38e6a7bc2e3396e32ec48c9b Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 17:57:16 -0500 Subject: [PATCH 77/91] comparestr --- .../v1_mips_generate/mipsgenerate_ast.py | 97 +++++++++++++------ 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index acf769039..795e7d491 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -59,34 +59,63 @@ def __init__(self) -> None: def __str__(self) -> str: return """ - # compare str1 0($sp), str2 4($sp) salida en $s0 -lw $a0 , 4($t0) -lw $a1 , 4($t1) - -LOOP: - lb $t0, ($a0) - lb $t1, ($a1) - add $a0, $a0, 1 - add $a1, $a1, 1 - beqz $t0, LOOP_END - beqz $t1, LOOP_END - beq $t0, $t1, LOOP - li $s0 , 0 - j End -# jr $ra - -EQUAL: - li $s0, 1 - j END - -LOOP_END: - beq $t0, $t1, EQUAL - li $s0 , 0 - -# jr $ra -END: -# jr $ra""" - + +Compare_String: + +lw $t0 , 0($sp) # primer str1 a comparar +lw $t1 , 4($sp) # segundo str2 a comparar +lw $s1 , 8($sp) # parametro self + +lw $a0 , 4($t0) #toma la propiedad value de str1 +lw $a1 , 4($t1) #toma la propieda value de str2 + +#Allocate a una class Bool puntero en sp + 12 +#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 $t4, Bool +sw $t4, 0($v0) # Asigna el tipo Int al int +sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del int + +LOOP_Str: + lb $t0, ($a0) # primera letra str1 + lb $t1, ($a1) # primera letra de str2 + add $a0, $a0, 1 # proximo caracter de str1 + add $a1, $a1, 1 #proximo caracter de str2 + beqz $t0, LOOP_END_Str # temrino de analizar str1 + beqz $t1, LOOP_END_Str # temrino de analizar str2 + beq $t0, $t1, LOOP_Str # Alguno de los caracteres son diferentes + li $s0 , 0 # devuelve false + j End_Str + + +EQUAL_Str: + li $s0, 1 #Devuelve True + j END_Str + +LOOP_END_Str: + beq $t0, $t1, EQUAL_Str # si ambos terminaron en son iguales + li $s0 , 0 # else false + j END_Str + +END_Str: + +#Allocate a una class Bool puntero en sp + 12 +#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 $t4, Bool +sw $t4, 0($v0) # Asigna el tipo Int al int +sw $s0, 4($v0) # Asigan el nombre de la clase a la propiededa value del int +move $s0 , $v0 + + add $sp,$sp,8 #saca str1,str2 + jr $ra + """ class Comment: def __init__(self, msg) -> None: @@ -272,9 +301,8 @@ def __init__(self, dest, op1, op2) -> None: ################################# Native Func IO ################################################ class Out_String: def __str__(self) -> str: - return """ + return """ IO_out_string: - lw $t1 , 4($sp) #Guardando self lw $t0, 0($sp) #Guarda en $t0 la direccion del string li $v0, 4 @@ -282,7 +310,8 @@ def __str__(self) -> str: syscall addi $sp, $sp, 8 move $s0, $t1 #return self -jr $ra""" +jr $ra +""" class Out_Int: def __str__(self) -> str: @@ -302,6 +331,10 @@ def __str__(self) -> str: return """ IO_in_string: + + + + li $a0, 1000 # reserva memoria para el string li $v0, 9 syscall # En $v0 la instancia del nuevo string @@ -324,6 +357,7 @@ def __str__(self) -> str: addi $sp, $sp, 4 + jr $ra """ @@ -458,6 +492,7 @@ def __str__(self) -> str: String_substr: lw $s5, 8($sp) # self. lw $s1, 4($sp) # guarda el indice + lw $t4, ($sp) #guarda el j li $t0, 0 # Inicia el contador en 0 From 28828d3db0deb298bc6e489d13a6daf0e3a21eeb Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 17:57:45 -0500 Subject: [PATCH 78/91] sa --- .../type_data_code_visitor.py | 7 ++-- .../codegen/v1_mips_generate/mipsgenerate.py | 34 +++++++++++-------- .../v1_mips_generate/mipsgenerate_ast.py | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 72c0c2071..e210eaba5 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -157,7 +157,6 @@ def visit(self, node: AST.AtrDef, scope: Scope): self.currentFunc = save_current_func - @visitor.when(AST.FuncDef) def visit(self, node: AST.FuncDef, scope: Scope): func_scope = scope.create_child(node.name) @@ -444,10 +443,10 @@ def visit(self, node: AST.LessOrEquals, scope: Scope): @visitor.when(AST.Equals) def visit(self, node: AST.Equals, scope: Scope): - if node.static_type in [CoolInt, CoolBool]: + if node.left.static_type in [CoolInt, CoolBool]: return self.binary_op('int_eq', node, ASTR.CmpInt, scope) - if node.static_type == CoolStr: - return self.binary_op('str_eq', node, ASTR.CmpStr, scope, 'String', 'Boolena') + if node.left.static_type == CoolStr: + return self.binary_op('str_eq', node, ASTR.CmpStr, scope, 'String', 'Bool') op_1 = self.currentFunc.local_push(f'ref@_a', scope) op_2 = self.currentFunc.local_push(f'ref@_b', scope) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py index 05e211bb1..8507318ce 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py @@ -12,12 +12,9 @@ def __init__(self, errors) -> None: "IO_in_string":ASTR.In_String, "IO_out_int":ASTR.Out_Int, "String_length":ASTR.Length, - #"String_length":ASTR.Length, "String_concat": ASTR.Concat, - - - "String_substr":ASTR.SubStr -, + "String_substr":ASTR.SubStr, + 'Compare_String': ASTR.Compare_String, "Object_copy": ASTR.Copy, "Object_type_name":ASTR.Type_Name, "Object_abort": ASTR.Abort, @@ -291,17 +288,26 @@ def visit(self,node:AST.CmpStr): memory_str2 = node.z stack_plus_str1 = self.stack.index(memory_str1) + self.stack.push(memory_str1) stack_plus_str2 = self.stack.index(memory_str2) - stack_plus_dest = self.stack.index(memory_dest) + self.stack.push(memory_str2) - return [ASTR.LW('$t0',f'{stack_plus_str1}'), - ASTR.Comment(f"Si no viene como funcion pon el string {memory_str1} de la posicion {stack_plus_str1}"), - ASTR.LW('$t1',f'{stack_plus_str2}'), - ASTR.Comment(f"Si no viene como funcion pon el string {memory_str2} de la posicion {stack_plus_str2}"), - ASTR.Compare_String(), - ASTR.SW ('$s0', f'{stack_plus_dest}'), - ASTR.Comment(f"Como no retorna sigue lineal entoces en $s0 esta el resultado y se pone en {stack_plus_dest}") - ] + func = 'Compare_String' + if not func in self.func_list: self.func_list.append(func) + + return [ + ASTR.Header_Comment("COMPARACION DE STR\n"), + ASTR.LW('$t0', f'{stack_plus_str1}($sp)'), + ASTR.Comment(f'Saca de la pila {node.y}'), + ASTR.AddI('$sp', '$sp', -4), + ASTR.SW('$t0', '0($sp)'), + ASTR.Comment(f'Mete para la pila {node.y}'), + ASTR.LW('$t0', f'{stack_plus_str2}($sp)'), + ASTR.Comment(f'Saca de la pila {node.z}'), + ASTR.AddI('$sp', '$sp', -4), + ASTR.SW('$t0', '0($sp)'), + ASTR.Comment(f'Mete para la pila {node.z}'), + ] + self.call('Compare_String', memory_dest) + [ASTR.Header_Comment("Fin de la Comparacion\n")] @visitor.when(AST.Less) def visit (self,node:AST.Less): diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 415609ff0..349187359 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -321,7 +321,7 @@ def __str__(self) -> str: sw $t4, 0($v0) # Asigna el tipo String al string sw $s0, 4($v0) # Asigan el nombre de la clase a la propiededa value del string - +move $s0, $v0 addi $sp, $sp, 4 jr $ra """ From 779a054eb054f1e8f6051aca0d6808b0484776fe Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Fri, 25 Feb 2022 17:58:52 -0500 Subject: [PATCH 79/91] llkj --- .../codegen/v0_type_data_code/type_data_code_visitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py index 0b5764420..83c9c79d4 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py @@ -151,7 +151,7 @@ def visit(self, node: AST.AtrDef, scope: Scope): self.new_type_func.expr[-1].set_value(default) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], default)) else: - null = self.new_type_func.local_push('null') + null = self.new_type_func.local_push('null',scope) self.new_type_func.expr_push(ASTR.Load(null, '_______null_______')) self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], null)) From b4a0abb0b6387e3246b5a9fc0603fd3645cadab4 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Fri, 25 Feb 2022 19:17:07 -0500 Subject: [PATCH 80/91] skjab --- .../v1_mips_generate/mipsgenerate_ast.py | 56 +++++-------------- 1 file changed, 13 insertions(+), 43 deletions(-) diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py index 9f33120ff..2e4014531 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py @@ -59,62 +59,36 @@ def __init__(self) -> None: def __str__(self) -> str: return """ - Compare_String: -lw $t0 , 0($sp) # primer str1 a comparar -lw $t1 , 4($sp) # segundo str2 a comparar -lw $s1 , 8($sp) # parametro self - -lw $a0 , 4($t0) #toma la propiedad value de str1 -lw $a1 , 4($t1) #toma la propieda value de str2 - -#Allocate a una class Bool puntero en sp + 12 -#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 $t4, Bool -sw $t4, 0($v0) # Asigna el tipo Int al int -sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del int +lw $t4 , 4($sp) # segundo str2 a comparar +lw $t5 , 0($sp) # primer str1 a comparar LOOP_Str: - lb $t0, ($a0) # primera letra str1 - lb $t1, ($a1) # primera letra de str2 - add $a0, $a0, 1 # proximo caracter de str1 - add $a1, $a1, 1 #proximo caracter de str2 + lb $t0, 0($t4) # primera letra str1 + lb $t1, 0($t5) # primera letra de str2 + add $t4, $t4, 1 # proximo caracter de str1 + add $t5, $t5, 1 #proximo caracter de str2 + beqz $t0, LOOP_END_Str # temrino de analizar str1 beqz $t1, LOOP_END_Str # temrino de analizar str2 beq $t0, $t1, LOOP_Str # Alguno de los caracteres son diferentes li $s0 , 0 # devuelve false - j End_Str + j END_Str - EQUAL_Str: li $s0, 1 #Devuelve True j END_Str -LOOP_END_Str: +LOOP_END_Str: + beq $t0, $t1, EQUAL_Str # si ambos terminaron en son iguales li $s0 , 0 # else false j END_Str END_Str: - -#Allocate a una class Bool puntero en sp + 12 -#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 $t4, Bool -sw $t4, 0($v0) # Asigna el tipo Int al int -sw $s0, 4($v0) # Asigan el nombre de la clase a la propiededa value del int -move $s0 , $v0 - - add $sp,$sp,8 #saca str1,str2 - jr $ra +add $sp, $sp, 8 #saca str1,str2 +jr $ra """ class Comment: @@ -331,10 +305,6 @@ def __str__(self) -> str: return """ IO_in_string: - - - - li $a0, 1000 # reserva memoria para el string li $v0, 9 syscall # En $v0 la instancia del nuevo string @@ -413,7 +383,7 @@ def __str__(self) -> str: return """ String_length: lw $t4 , ($sp) #self -li $t0 , 0 #contador +li $t0 , -1 #contador lw $s2 , 4($t4) # propiedad value loop_len: From a092c7c67c1410b023544e0ae48cd33f6b31e50b Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Sat, 26 Feb 2022 06:43:56 -0500 Subject: [PATCH 81/91] error con el path --- src/cool_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 3a1b97a12..7098dfaa6 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +# path = "test.cl" with open(path, 'r') as _file: text = _file.read() From 8febee13a111bbb5354a061395353ae5ce6ee8ef Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Mon, 28 Feb 2022 21:23:42 -0500 Subject: [PATCH 82/91] faltan 6 --- src/cool_compiler/__main__.py | 13 +- src/cool_compiler/codegen/__init__.py | 4 +- .../codegen/mips_code/in_string.mips | 21 + .../codegen/v0_cool_to_cil/cool_to_cil_ast.py | 269 ++++++++++ .../v0_cool_to_cil/cool_to_cil_visitor.py | 479 ++++++++++++++++++ .../codegen/v0_cool_to_cil/tools.py | 40 ++ .../type_data_code_ast.py | 0 .../type_data_code_visitor.py | 20 - .../codegen/v1_mips_generate/__init__.py | 0 .../general_macros/__init__.py | 14 + .../general_macros/__registry_legend | 3 + .../v1_mips_generate/general_macros/bool.mips | 152 ++++++ .../v1_mips_generate/general_macros/int.mips | 327 ++++++++++++ .../v1_mips_generate/general_macros/str.mips | 337 ++++++++++++ .../v1_mips_generate/mips_generate_ast.py | 164 ++++++ .../v1_mips_generate/mips_generate_visitor.py | 291 +++++++++++ .../v1_mips_generate/native_funcion.py | 165 ++++++ .../codegen/v1_mips_generate/stack.py | 39 +- .../mipsgenerate.py | 19 +- .../mipsgenerate_ast.py | 1 - 20 files changed, 2310 insertions(+), 48 deletions(-) create mode 100644 src/cool_compiler/codegen/mips_code/in_string.mips create mode 100644 src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_ast.py create mode 100644 src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_visitor.py create mode 100644 src/cool_compiler/codegen/v0_cool_to_cil/tools.py rename src/cool_compiler/codegen/{v0_type_data_code => v0_type_data_code-odd}/type_data_code_ast.py (100%) rename src/cool_compiler/codegen/{v0_type_data_code => v0_type_data_code-odd}/type_data_code_visitor.py (98%) create mode 100644 src/cool_compiler/codegen/v1_mips_generate/__init__.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/__init__.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/__registry_legend create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/int.mips create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips create mode 100644 src/cool_compiler/codegen/v1_mips_generate/mips_generate_ast.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py create mode 100644 src/cool_compiler/codegen/v1_mips_generate/native_funcion.py rename src/cool_compiler/codegen/{v1_mips_generate => v1_mips_generate_old}/mipsgenerate.py (96%) rename src/cool_compiler/codegen/{v1_mips_generate => v1_mips_generate_old}/mipsgenerate_ast.py (99%) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 7098dfaa6..d9106a1f4 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -1,13 +1,14 @@ import sys -from cool_compiler.codegen.v0_type_data_code.type_data_code_ast import Type -from cool_compiler.codegen.v1_mips_generate.mipsgenerate import MipsGenerate + + from .error import CoolError from .lexer import CoolLexer from .parser import CoolParser +from .codegen import CoolToCIL, MipsGenerate from .semantic import * from .types import CoolTypeBuildInManager -from .codegen import CILGenerate +# from .codegen import CILGenerate path = "" if len(sys.argv) > 1: @@ -23,21 +24,19 @@ 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, CILGenerate,MipsGenerate ] + 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/codegen/__init__.py b/src/cool_compiler/codegen/__init__.py index fb6b00869..b82ef15a0 100755 --- a/src/cool_compiler/codegen/__init__.py +++ b/src/cool_compiler/codegen/__init__.py @@ -1 +1,3 @@ -from .v0_type_data_code.type_data_code_visitor import CILGenerate \ No newline at end of file +# 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/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..5d8a2110a --- /dev/null +++ b/src/cool_compiler/codegen/v0_cool_to_cil/cool_to_cil_visitor.py @@ -0,0 +1,479 @@ +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') + + 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.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.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 in [CoolInt, CoolBool]: + self.new_type_func.expr_push(ASTR.Assign('_', 0)) + self.new_type_func.expr_push(ASTR.VCall('_', f'__{node.type.name.lower()}__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, _, 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}')) + + + 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) + for name, atype , expr in node.case_list: + 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): + return [ + ASTR.ALLOCATE('_', node.item.name), + ASTR.Arg('_'), + 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/v0_type_data_code/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py similarity index 100% rename from src/cool_compiler/codegen/v0_type_data_code/type_data_code_ast.py rename to src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py diff --git a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py similarity index 98% rename from src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py rename to src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py index e210eaba5..92553aa67 100644 --- a/src/cool_compiler/codegen/v0_type_data_code/type_data_code_visitor.py +++ b/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py @@ -10,26 +10,6 @@ CoolStr = CoolTypeBuildInManager().find("String") CoolObject = CoolTypeBuildInManager().find(OBJECT_NAME) -def parent_list(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(name, _dict): - index = 0 - while True: - try: - _ = _dict[f'{name}_{index}'] - index += 1 - except KeyError: - _dict[f'{name}_{index}'] = 1 - return f'{name}_{index}' class CILGenerate: def __init__(self, errors) -> None: 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..81df33fe6 --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips @@ -0,0 +1,152 @@ +.data +Bool_Name: .asciiz "Bool" +Bool: .word Bool_Name, 2, +Bool_parents: .word 1, 7, 0 +T: .asciiz "" + +.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/str.mips b/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips new file mode 100644 index 000000000..90bab8f5f --- /dev/null +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips @@ -0,0 +1,337 @@ +.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 + +addi $t0, $t0, -1 #Resta uno al length para eliminar el '\n' +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..e9b2bee63 --- /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 = "SELF" + 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 index 947e38e7e..e97298fa5 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/stack.py +++ b/src/cool_compiler/codegen/v1_mips_generate/stack.py @@ -1,3 +1,6 @@ +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 @@ -7,7 +10,18 @@ def __init__(self, node) -> None: 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): @@ -22,7 +36,30 @@ def clean(self): self.local_push = 0 def close(self): + if not any(self.list): return [] result = len(self.list) * 4 self.local_push self.list = [] - return result \ No newline at end of file + 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/codegen/v1_mips_generate/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py similarity index 96% rename from src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py rename to src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py index 8507318ce..d98e88799 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate.py +++ b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py @@ -72,19 +72,6 @@ def visit(self, node: AST.Function): #stack_pointer = 0 #bsp = self.base_stack_pointer - @visitor.when(AST.Param) - def visit(self, node: AST.Param): - self.stack.list.append(node.x) - return [ASTR.Header_Comment(f'Parametro {node.x} en stackpoiner + {self.stack.initial_index}')] - - @visitor.when(AST.Local) - def visit(self, node: AST.Local): - self.stack.list.append(node.x) - return [ - ASTR.AddI('$sp', '$sp', -4), - ASTR.Comment( - f'Push local var {node.x} stackpointer {self.stack.initial_index}') - ] @visitor.when(AST.ALLOCATE) def visit(self, node: AST.ALLOCATE): @@ -491,11 +478,7 @@ def visit(self,node:AST.IfGoTo): ASTR.Comment(f"if $t1==$t0 then jump {label_memory}") ] - @ visitor.when(AST.Label) - def visit(self,node:AST.Label): - return [ASTR.Label(node.x), - ASTR.Comment(f"Crea el label {node.x} ") - ] + @visitor.when(AST.CheckType) def visit(self,node:AST.CheckType): diff --git a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py similarity index 99% rename from src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py rename to src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py index 2e4014531..9b243655b 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mipsgenerate_ast.py +++ b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py @@ -226,7 +226,6 @@ class SLT (CmpNotJump): #< def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'slt' ,r_dest, r_src_1, r_src_2) - class SLE(CmpNotJump): # <= def __init__(self ,r_dest, r_src_1, r_src_2) -> None: super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) From 978cad80010fd0b2392bbe2c403a9e9b67b50ea4 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Mon, 28 Feb 2022 23:03:50 -0500 Subject: [PATCH 83/91] pull --- src/cool_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index 7098dfaa6..3a1b97a12 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -13,7 +13,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -# path = "test.cl" +path = "test.cl" with open(path, 'r') as _file: text = _file.read() From e6b4201847f4f695c94f9dffe69767070b420757 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 1 Mar 2022 10:36:38 -0500 Subject: [PATCH 84/91] refactor case --- .../v0_cool_to_cil/cool_to_cil_visitor.py | 29 ++++++++++++++----- .../v1_mips_generate/mips_generate_visitor.py | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) 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 index 5d8a2110a..484dc1c74 100644 --- 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 @@ -37,13 +37,21 @@ def visit(self, node: AST.Program, scope: Scope = None): 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')) @@ -99,10 +107,10 @@ def create_new_func_by_type(self, _type, scope): 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')) + # 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): @@ -341,7 +349,9 @@ def visit(self, node: AST.Case, scope: Scope): expr_list = [] end_label = self.new_name('case_end', self.label_list) - for name, atype , expr in node.case_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))) @@ -416,9 +426,14 @@ def visit(self, node: AST.Equals, scope: 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.ALLOCATE('_', node.item.name), - ASTR.Arg('_'), + 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) ] 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 index e9b2bee63..daa104782 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py +++ b/src/cool_compiler/codegen/v1_mips_generate/mips_generate_visitor.py @@ -92,7 +92,7 @@ def visit(self, node: AST.SetAttr): if node.y == 'type_name': attr_plus = 0 attr = 'type_name' - _type = "SELF" + _type = "" else: attr_name = node.y.split('@') _type = attr_name[0] From cbe23aee7ae3d205fee4df50398bf0be59ded4c9 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 1 Mar 2022 10:38:10 -0500 Subject: [PATCH 85/91] aaa --- .../codegen/v1_mips_generate/general_macros/bool.mips | 1 - 1 file changed, 1 deletion(-) 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 index 81df33fe6..a691dd358 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/bool.mips @@ -2,7 +2,6 @@ Bool_Name: .asciiz "Bool" Bool: .word Bool_Name, 2, Bool_parents: .word 1, 7, 0 -T: .asciiz "" .text .globl main From ee9d639fae7140171953fd1691e3e56cb7e10696 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Tue, 1 Mar 2022 15:12:00 -0500 Subject: [PATCH 86/91] sin info --- .../v0_cool_to_cil/cool_to_cil_visitor.py | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) 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 index 484dc1c74..d243d681e 100644 --- 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 @@ -28,6 +28,7 @@ def visit(self, node: AST.Program, scope: Scope = None): 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() @@ -130,9 +131,18 @@ def visit(self, node: AST.AtrDef, scope: Scope): exp_list.append(ASTR.Comment(f"Fin De la Asignacion")) self.new_type_func.expr += exp_list - elif node.type in [CoolInt, CoolBool]: + elif node.type == CoolInt: self.new_type_func.expr_push(ASTR.Assign('_', 0)) - self.new_type_func.expr_push(ASTR.VCall('_', f'__{node.type.name.lower()}__new__', '_')) + 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_______')) @@ -325,13 +335,29 @@ def visit(self, node: AST.Block, scope: Scope): def visit(self, node: AST.LetIn, scope: Scope): result_list = [] let_scope = scope.create_child('let') - for name, _, expr in node.assing_list: + 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) From 6564b0a7d44b5872d7ce28f4a561829e33b2181a Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Wed, 2 Mar 2022 22:24:02 -0500 Subject: [PATCH 87/91] all_test --- src/cool_compiler/__main__.py | 2 +- .../v1_mips_generate/general_macros/str.mips | 3 + src/test.cl | 404 +- src/test.mips | 4445 +++++++++++++++-- 4 files changed, 4505 insertions(+), 349 deletions(-) diff --git a/src/cool_compiler/__main__.py b/src/cool_compiler/__main__.py index dab12cba0..6bb45423b 100755 --- a/src/cool_compiler/__main__.py +++ b/src/cool_compiler/__main__.py @@ -14,7 +14,7 @@ if len(sys.argv) > 1: path = sys.argv[1] -path = "test.cl" +#path = "test.cl" with open(path, 'r') as _file: text = _file.read() 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 index 90bab8f5f..93c3d932a 100644 --- a/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips +++ b/src/cool_compiler/codegen/v1_mips_generate/general_macros/str.mips @@ -123,7 +123,10 @@ 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 diff --git a/src/test.cl b/src/test.cl index f15425a96..7b8bf3363 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,25 +1,381 @@ -class Main inherits IO { - pal(s : String) : Bool { - if s.length() = 0 - then true - else if s.length() = 1 - then true - else if s.substr(0, 1) = s.substr(s.length() - 1, 1) - then pal(s.substr(1, s.length() -2)) - else false - fi fi fi - }; - - i : Int; - - main() : IO { - { - i <- ~1; - out_string("enter a string\n"); - if pal(in_string()) - then out_string("that was a palindrome\n") - else out_string("that was not a palindrome\n") - fi; - } - }; +(* + * 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 # -IO_in_string: -li $v0,8 -li $a1 , 10000 +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 -move $s0 , $a0 -addi $sp, $sp, 4 -jr $ra +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 # -Main_pal: -#Parametro self en stackpoiner + 132 -#Parametro s@0 en stackpoiner + 128 -addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 124 -addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 120 -addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 116 -addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 112 -addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 108 -addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 104 -addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 100 -addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 96 -addi $sp, $sp, -4 #Push local var instance_to_call_length@1 stackpointer 92 -addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 88 -addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 84 -addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 80 -addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 76 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 72 -addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 68 -addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@1 stackpointer 60 -addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 52 -addi $sp, $sp, -4 #Push local var instance_to_call_length@2 stackpointer 48 -addi $sp, $sp, -4 #Push local var param_0_to_substr@1 stackpointer 44 -addi $sp, $sp, -4 #Push local var param_1_to_substr@1 stackpointer 40 -addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 36 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@2 stackpointer 32 -addi $sp, $sp, -4 #Push local var param_0_to_substr@2 stackpointer 28 -addi $sp, $sp, -4 #Push local var rest@_a@1 stackpointer 24 -addi $sp, $sp, -4 #Push local var rest@_b@1 stackpointer 20 -addi $sp, $sp, -4 #Push local var instance_to_call_length@3 stackpointer 16 -addi $sp, $sp, -4 #Push local var param_1_to_substr@2 stackpointer 12 -addi $sp, $sp, -4 #Push local var param_0_to_pal@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_pal -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 112($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length -lw $t0, 112($sp) #Saca de la pila instance_to_call_length@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_length@0 -lw $t0, 116($sp) #Sacando la instancia de la pila (en 112) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length +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 # -li $v0 , 10 +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** -jal $t3 #Call a la function $t3 -sw $s0, 120($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 116($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 120($sp) #carga en $t1 lo que hay en 120 -lw $t2, 116($sp) #carga en $t2 lo que hay en 116 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 124($sp) #Pon en la posicion 124 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 124($sp) #Cargar el valor de la pos 124 a $t1 pa comparar -beq $t0 $t1 then_Main_pal_0 #if $t1==$t0 then jump then_Main_pal_0 #Else case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 92($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@1 #Fin de la exprecion previa al Dispatch length -lw $t0, 92($sp) #Saca de la pila instance_to_call_length@1 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_length@1 -lw $t0, 96($sp) #Sacando la instancia de la pila (en 92) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length -jal $t3 #Call a la function $t3 -sw $s0, 100($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 96($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 100($sp) #carga en $t1 lo que hay en 100 -lw $t2, 96($sp) #carga en $t2 lo que hay en 96 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 104($sp) #Pon en la posicion 104 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 104($sp) #Cargar el valor de la pos 104 a $t1 pa comparar -beq $t0 $t1 then_Main_pal_1 #if $t1==$t0 then jump then_Main_pal_1 #Else case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 68($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 64($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr -lw $t0, 72($sp) #Saca de la pila instance_to_call_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@0 -lw $t0, 72($sp) #Saca de la pila param_0_to_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_substr@0 -lw $t0, 72($sp) #Saca de la pila param_1_to_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_substr@0 -lw $t0, 84($sp) #Sacando la instancia de la pila (en 72) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr -jal $t3 #Call a la function $t3 -li $s0 ,3 -sw $s0, 80($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@1 #Fin de la exprecion previa al Dispatch substr -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@2 #Fin de la exprecion previa al Dispatch length -lw $t0, 48($sp) #Saca de la pila instance_to_call_length@2 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_length@2 -lw $t0, 52($sp) #Sacando la instancia de la pila (en 48) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length -jal $t3 #Call a la function $t3 -sw $s0, 56($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 56($sp) #poner en registro $t0 lo que hay en 56 -lw $t1, 52($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 44($sp) #poner en 44 el resultado de la suma #Fin del paramentro 0 al Dispatch substr -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 40($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@1 #Fin del paramentro 1 al Dispatch substr -lw $t0, 60($sp) #Saca de la pila instance_to_call_substr@1 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@1 -lw $t0, 48($sp) #Saca de la pila param_0_to_substr@1 addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_substr@1 -lw $t0, 48($sp) #Saca de la pila param_1_to_substr@1 +sw $ra ($sp) #Salva $ra en 12($sp) addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_substr@1 -lw $t0, 72($sp) #Sacando la instancia de la pila (en 60) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr -jal $t3 #Call a la function $t3 -sw $s0, 76($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq -lw $t1, 80($sp) #carga en $t1 lo que hay en 80 -lw $t2, 76($sp) #carga en $t2 lo que hay en 76 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 84($sp) #Pon en la posicion 84 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 84($sp) #Cargar el valor de la pos 84 a $t1 pa comparar -beq $t0 $t1 then_Main_pal_2 #if $t1==$t0 then jump then_Main_pal_2 #Else case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 36($sp) #Escribe en la pila el numero que se le asigno a result@if@2 -j fin_Main_pal_2 #Salta para f{label} -then_Main_pal_2 : #Crea el label then_Main_pal_2 #Then case -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 32($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_substr@2 #Fin de la exprecion previa al Dispatch substr -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a param_0_to_substr@2 #Fin del paramentro 0 al Dispatch substr -lw $t0, 128($sp) #Lee de la pila s@0 en 128 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_length@3 #Fin de la exprecion previa al Dispatch length -lw $t0, 16($sp) #Saca de la pila instance_to_call_length@3 +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 $t0, 0($sp) #Mete para la pila instance_to_call_length@3 -lw $t0, 20($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length -jal $t3 #Call a la function $t3 -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest -li $t0, 2 #Guarda el numbero que se va a asignar -sw $t0, 20($sp) #Escribe en la pila el numero que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest -lw $t0, 24($sp) #poner en registro $t0 lo que hay en 24 -lw $t1, 20($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 12($sp) #poner en 12 el resultado de la suma #Fin del paramentro 1 al Dispatch substr -lw $t0, 32($sp) #Saca de la pila instance_to_call_substr@2 +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 $t0, 0($sp) #Mete para la pila instance_to_call_substr@2 -lw $t0, 32($sp) #Saca de la pila param_0_to_substr@2 +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 $t0, 0($sp) #Mete para la pila param_0_to_substr@2 -lw $t0, 20($sp) #Saca de la pila param_1_to_substr@2 +sw $s6, ($sp) #Salva **self** addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_substr@2 -lw $t0, 44($sp) #Sacando la instancia de la pila (en 32) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr -jal $t3 #Call a la function $t3 -sw $s0, 8($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch pal -lw $t0, 132($sp) #Saca de la pila self +sw $a0, ($sp) #Salva el string que se paso como parametro addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch pal -lw $t0, 12($sp) #Saca de la pila param_0_to_pal@0 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_pal@0 #Agrega a la pila el paramentro 1 al StaticDispatch pal -jal Main_pal #Call a la function Main_pal -sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -fin_Main_pal_2 : #Crea el label fin_Main_pal_2 #Fin de un If -lw $t0, 36($sp) #Lee de la pila result@if@2 en 36 para assignar -sw $t0, 88($sp) #Escribe en la pila el valor que se le asigno a result@if@1 -j fin_Main_pal_1 #Salta para f{label} -then_Main_pal_1 : #Crea el label then_Main_pal_1 #Then case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a result@if@1 -fin_Main_pal_1 : #Crea el label fin_Main_pal_1 #Fin de un If -lw $t0, 88($sp) #Lee de la pila result@if@1 en 88 para assignar -sw $t0, 108($sp) #Escribe en la pila el valor que se le asigno a result@if@0 -j fin_Main_pal_0 #Salta para f{label} -then_Main_pal_0 : #Crea el label then_Main_pal_0 #Then case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 108($sp) #Escribe en la pila el numero que se le asigno a result@if@0 -fin_Main_pal_0 : #Crea el label fin_Main_pal_0 #Fin de un If -lw $t0, 108($sp) #Lee de la pila result@if@0 en 108 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 136 #Limpia la pila -jr $ra #Final de la function pal +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 From 3074e0850f43593d98726e722f18c6e7768894e8 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 3 Mar 2022 21:53:36 -0500 Subject: [PATCH 88/91] informe --- doc/report.md | 38 +- tests/codegen/arith.mips | 7076 ++++++++++++++++++++++++++++++++ tests/codegen/atoi.mips | 2751 +++++++++++++ tests/codegen/book_list.mips | 1691 ++++++++ tests/codegen/cells.mips | 2373 ++++++++--- tests/codegen/complex.mips | 1372 +++++-- tests/codegen/fib.mips | 948 +++++ tests/codegen/graph.mips | 4151 +++++++++++++++++++ tests/codegen/hairyscary.mips | 1729 ++++++++ tests/codegen/hello_world.mips | 744 +++- tests/codegen/io.mips | 1064 +++++ tests/codegen/life.mips | 6054 +++++++++++++++++++++++++++ tests/codegen/list.mips | 1338 ++++++ tests/codegen/new_complex.mips | 1367 ++++++ tests/codegen/palindrome.mips | 1176 ++++++ tests/codegen/primes.mips | 1236 ++++++ tests/codegen/print-cool.mips | 894 ++++ tests/codegen/sort-list.mips | 1780 ++++++++ 18 files changed, 36778 insertions(+), 1004 deletions(-) create mode 100644 tests/codegen/arith.mips create mode 100644 tests/codegen/atoi.mips create mode 100644 tests/codegen/book_list.mips create mode 100644 tests/codegen/fib.mips create mode 100644 tests/codegen/graph.mips create mode 100644 tests/codegen/hairyscary.mips create mode 100644 tests/codegen/io.mips create mode 100644 tests/codegen/life.mips create mode 100644 tests/codegen/list.mips create mode 100644 tests/codegen/new_complex.mips create mode 100644 tests/codegen/palindrome.mips create mode 100644 tests/codegen/primes.mips create mode 100644 tests/codegen/print-cool.mips create mode 100644 tests/codegen/sort-list.mips diff --git a/doc/report.md b/doc/report.md index 262729bf2..154c7071a 100644 --- a/doc/report.md +++ b/doc/report.md @@ -143,7 +143,43 @@ redefinir, en el caso particular del compilador de cool se redefinio de la maner ... ``` -Aprovechando la caracteristica de que la gramatica se encuentra recogida en una clase, se desarrollaro algunas herramientas +Aprovechando la caracteristica de que la gramatica se encuentra recogida en una clase, se desarrollaron algunas herramientas para realizar la inversion de la dependencia entre la gramatica 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 fatoria de nodos, además de un decorador que enlace un método con el nombre del nodo que el mismo creará + + + + +#generacion de codigo Mips +Para el inicio de la creación de código Mips partimos de la base de una librería escrita en este lenguaje la cual contendría gran parte de las herramientas con las que no apoyaríamos y así nos evitábamos la doble escritura del código . La librería es una herramienta simple , en ella se encuentra a modo de macro la implementación de todas las funcione de IO , como IO_out_string,IO_in_Int ,entre otras, las cuales tratábamos como funciones nativas o especiales, dado que en la conversión de CIL no teníamos contemplado el desglose de la implementación de estos métodos , solo detectamos que hay un llamado a estos e inmediatamente tenemos preconcebido el código asociado. Además de las de tipo , entrada y salida de información , tenemos otras macros, las correspondientes al tipo string ,como substring , concat, lenght , las cuales se muestran en la documentación como funciones integradas a este tipo. Otras macro en esta librería van asociadas al tipo object y a sus métodos como Copy , Abort y Type Name. +Se utilizó una creación de tipo Int , Bool , String , la cuales contienen en su primera palabra la caracterización del tipo y en la segunda la propiedad value del tipo , por lo que en cada utilización de alguna operación que involucre alguno de estos tipos, son tratados de esta manera y siempre que se tenga una salida de algún dato de este tipo , se reserva memoria y se crea una nueva instancia que sera el valor de retorno. +Las operaciones entre los tipos enteros , no las podiamos realizar de manera natural debido a la representación que describimos anteriormente , por lo que también tenemos predefinidas los métodos básicos de operaciones aritméticas tomando como entrada los registros de propósito general $a0 y $a1 , dentro de esta se enmascara un poco el paso intermedio que se realiza antes de llegar a la manera natural de resolver las operaciones y creando un tipo nuevo de entero como resultado. De manera similar ocurre con las comparaciones que devuelven un valor de verdad. La relevancia de esta manera de tener los datos nos ayudó bastante para tener un chuequeo del tipo utilizado y simplificar algunas especificidades del lenguaje COOL. + +A la hora de recorrer el código intermedio centramos nuestra conversión en crear una definición de cada clase , con sus funciones y atributos, ademas del nombre y luego las instancias de estas, las cuales se salvaban y mantenían validas en el programa a través de la pila. Posteriormente se desarrolla el código especifico de cada función utilizada y se utilizan los saltos para entrelazar mas de una.A continuacion mostramos un ejemplo de la representacion en codigo Mips de la clase Main: + +```python + 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, + + ..... + +``` + +Otro punto importante en la generación de nuestro código Mips fue la utilización de la pila y el mapeo que utilizamos a alto nivel para mantener un orden en esta. La creación de la clase “Stack” es la estructura encargada de que los parámetros recibidos y los puntos de retornos de los saltos fueran los correctos entre llamado, la cueal cuenta con lo siguiente: + +```python + ... + 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 + ..... + +``` + + + La estructura contiene unos métodos los cuales se encargan de su llenado y vaciado siempre teniendo en cuenta que cada dato era insertado de 4 en 4 con respecto al registro $sp. Cada argumento de las funciones son pasados a la pila antes de su llamado siendo luego los métodos los encargados de utilizarlos y dejar la pila , luego de su culminación , sin estos elementos. EL cambio del valor del $ra fue un tema importante con el que nos topamos por lo que también seguimos la linea de ponerlo dentro de la pila y luego asignándoselo al nuevo $ra para que la función pudiera retornar al punto especifico donde fue llamado y no creara conflictos. + 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/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/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/cells.mips b/tests/codegen/cells.mips index d6367fd46..fc8e04383 100644 --- a/tests/codegen/cells.mips +++ b/tests/codegen/cells.mips @@ -1,20 +1,32 @@ .data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" Bool_parents: .word 1, 2, 0, -Bool: .word Bool_parents, Object_abort, Object_copy, Object_type_name, +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: .word Int_parents, Object_abort, Object_copy, Object_type_name, +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: .word String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +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: .word SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +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: .word Object_parents, Object_abort, Object_copy, Object_type_name, +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: .word IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +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: .word 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, +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: .word Main_parents, Object_abort, Object_copy, Object_type_name, Main_main, +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" @@ -25,678 +37,1717 @@ string_6: .asciiz " X " .text .globl main -main: -addi $sp, $sp, -4 #Push local var self stackpointer 20 -addi $sp, $sp, -4 #Push local var instance stackpointer 16 -addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 new_ctr_Main -#Allocate a una class Main puntero en sp + 12 +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 +li $a0, 8 # +li $v0, 9 # syscall -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, Main -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data -lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -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 +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 -Main_main: -#Parametro self en stackpoiner + 88 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 84 -addi $sp, $sp, -4 #Push local var instance_to_call_init@0 stackpointer 80 -addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 76 -addi $sp, $sp, -4 #Push local var result@assing@cells@0 stackpointer 72 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 68 -addi $sp, $sp, -4 #Push local var instance_to_call_print@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var step@block@2 stackpointer 60 -addi $sp, $sp, -4 #Push local var countdown stackpointer 56 -addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 52 -addi $sp, $sp, -4 #Push local var step@block@3 stackpointer 48 -addi $sp, $sp, -4 #Push local var instance_to_call_evolve@0 stackpointer 44 -addi $sp, $sp, -4 #Push local var step@block@4 stackpointer 40 -addi $sp, $sp, -4 #Push local var instance_to_call_print@1 stackpointer 36 -addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var result@assing@countdown@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Main_main #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -jal new_ctr_CellularAutomaton #Call a la function new_ctr_CellularAutomaton -sw $s0, 76($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch init -la $t0, string_6 -sw $t0, 72($sp) #Fin del paramentro 0 al Dispatch init -lw $t0, 76($sp) #Saca de la pila instance_to_call_init@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_init@0 -lw $t0, 76($sp) #Saca de la pila param_0_to_init@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_init@0 -lw $t0, 84($sp) #Sacando la instancia de la pila (en 76) de una clase que hereda de CellularAutomaton -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton -lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion init -jal $t3 #Call a la function $t3 -sw $s0, 68($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada -lw $t0, 84($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta -lw $t1, 68($sp) #Buscando el valor que se va a guardar en la propiedad -sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto -lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad cells -sw $t1, 80($sp) #Salvando el valor de la propiedad cells en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block -lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad cells -sw $t1, 60($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_print@0 #Fin de la exprecion previa al Dispatch print -lw $t0, 60($sp) #Saca de la pila instance_to_call_print@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_print@0 -lw $t0, 64($sp) #Sacando la instancia de la pila (en 60) de una clase que hereda de CellularAutomaton -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton -lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion print -jal $t3 #Call a la function $t3 -sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block -li $t0, 20 #Guarda el numbero que se va a asignar -sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a countdown #Fin de la asignacion Let countdown #Inicio de un While -j while_cond_1 #Salta para f{label} -while_back_1 : #Crea el label while_back_1 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad cells -sw $t1, 40($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_evolve@0 #Fin de la exprecion previa al Dispatch evolve -lw $t0, 40($sp) #Saca de la pila instance_to_call_evolve@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_evolve@0 -lw $t0, 44($sp) #Sacando la instancia de la pila (en 40) de una clase que hereda de CellularAutomaton -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton -lw $t3, 60($t1) #Buscando el metodo dinamico para la funcion evolve -jal $t3 #Call a la function $t3 -sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block -lw $t0, 84($sp) #Buscando la instancia de la clase Main en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad cells -sw $t1, 32($sp) #Salvando el valor de la propiedad cells en la pila en el valor local instance_to_call_print@1 #Fin de la exprecion previa al Dispatch print -lw $t0, 32($sp) #Saca de la pila instance_to_call_print@1 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_print@1 -lw $t0, 36($sp) #Sacando la instancia de la pila (en 32) de una clase que hereda de CellularAutomaton -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de CellularAutomaton -lw $t3, 36($t1) #Buscando el metodo dinamico para la funcion print -jal $t3 #Call a la function $t3 -sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 2 de una sequencia Block -lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar -sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 24($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 28($sp) #poner en registro $t0 lo que hay en 28 -lw $t1, 24($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 20($sp) #poner en 20 el resultado de la suma #Fin de la expresion lista para ser asignada -lw $t0, 20($sp) #Lee de la pila result@assing@countdown@0 en 20 para assignar -sw $t0, 52($sp) #Escribe en la pila el valor que se le asigno a countdown -lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar -sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a result@while@0 -while_cond_1 : #Crea el label while_cond_1 #Fin del cuerpo e inicio de la condicion de un While -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a less@_a@0 #Resolucion del operado izquierdo de una opercion less -lw $t0, 52($sp) #Lee de la pila countdown en 52 para assignar -sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a less@_b@0 #Resolucion del operado derecha de una opercion less -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 16($sp) #Cargar el valor de la pos 16 a $t1 pa comparar -beq $t0 $t1 while_back_1 #if $t1==$t0 then jump while_back_1 #Fin de la condicion de un While -lw $t0, 84($sp) #Lee de la pila self en 84 para assignar -sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a step@block@2 #Inicio del paso 3 de una sequencia Block -lw $t0, 84($sp) #Lee de la pila self en 84 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 88 #Limpia la pila -jr $ra #Final de la function main - -new_ctr_CellularAutomaton: -addi $sp, $sp, -4 #Push local var self stackpointer 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 $ra stackpointer 4 -sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_CellularAutomaton -#Allocate a una class CellularAutomaton puntero en sp + 8 +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 -sw $v0, 8($sp) #Reservando memoria para una instancia de tipo CellularAutomaton -lw $t0, 8($sp) #Lee de la pila instance en 8 para assignar -sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, CellularAutomaton -sw $t0, 4($sp) #Cargando el nombre del tipo desde el data -lw $t0, 8($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -lw $t1, 4($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 $s0, 8($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 16 #Limpia la pila -jr $ra -CellularAutomaton_init: -#Parametro self en stackpoiner + 24 -#Parametro map@0 en stackpoiner + 20 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var result@assing@population_map@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_init #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 16($sp) #Lee de la pila map@0 en 16 para assignar -sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a result@assing@population_map@0 #Fin de la expresion lista para ser asignada -lw $t0, 20($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta -lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad -sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto -lw $t0, 20($sp) #Buscando la instancia de la clase CellularAutomaton en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad population_map -sw $t1, 12($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local step@block@0 #Inicio del paso 1 de una sequencia Block -lw $t0, 20($sp) #Lee de la pila self en 20 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 24 #Limpia la pila -jr $ra #Final de la function init - -CellularAutomaton_print: -#Parametro self en stackpoiner + 28 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var instance_to_call_concat@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var param_0_to_concat@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 @result stackpointer 8 -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 CellularAutomaton_print #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 24($sp) #Buscando la instancia de la clase CellularAutomaton en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad population_map -sw $t1, 16($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_concat@0 #Fin de la exprecion previa al Dispatch concat -la $t0, string_0 -sw $t0, 12($sp) #Fin del paramentro 0 al Dispatch concat -lw $t0, 16($sp) #Saca de la pila instance_to_call_concat@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_concat@0 -lw $t0, 16($sp) #Saca de la pila param_0_to_concat@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_concat@0 -lw $t0, 24($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 16($t1) #Buscando el metodo dinamico para la funcion concat -jal $t3 #Call a la function $t3 -sw $s0, 8($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 24($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, 20($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Inicio del paso 1 de una sequencia Block -lw $t0, 24($sp) #Lee de la pila self en 24 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 28 #Limpia la pila -jr $ra #Final de la function print - -CellularAutomaton_evolve: -#Parametro self en stackpoiner + 84 -addi $sp, $sp, -4 #Push local var position stackpointer 80 -addi $sp, $sp, -4 #Push local var num stackpointer 76 -addi $sp, $sp, -4 #Push local var temp stackpointer 72 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 68 -addi $sp, $sp, -4 #Push local var result@while@0 stackpointer 64 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 60 -addi $sp, $sp, -4 #Push local var instance_to_call_concat@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var param_0_to_cell_at_next_evolution@0 stackpointer 52 -addi $sp, $sp, -4 #Push local var param_0_to_concat@0 stackpointer 48 -addi $sp, $sp, -4 #Push local var result@assing@temp@0 stackpointer 44 -addi $sp, $sp, -4 #Push local var sum@_a@0 stackpointer 40 -addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 36 -addi $sp, $sp, -4 #Push local var result@assing@position@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var cond@while@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var less@_a@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var less@_b@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var step@block@2 stackpointer 16 -addi $sp, $sp, -4 #Push local var result@assing@population_map@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_evolve -lw $t0, 80($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 num_cells -jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells -sw $s0, 72($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let num #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block #Inicio de un While -j while_cond_0 #Salta para f{label} -while_back_0 : #Crea el label while_back_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar -sw $t0, 52($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_concat@0 #Fin de la exprecion previa al Dispatch concat -lw $t0, 76($sp) #Lee de la pila position en 76 para assignar -sw $t0, 48($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_at_next_evolution@0 #Fin del paramentro 0 al StaticDispatch cell_at_next_evolution -lw $t0, 80($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 cell_at_next_evolution -lw $t0, 52($sp) #Saca de la pila param_0_to_cell_at_next_evolution@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell_at_next_evolution@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_at_next_evolution -jal CellularAutomaton_cell_at_next_evolution #Call a la function CellularAutomaton_cell_at_next_evolution -sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin del paramentro 0 al Dispatch concat -lw $t0, 52($sp) #Saca de la pila instance_to_call_concat@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_concat@0 -lw $t0, 48($sp) #Saca de la pila param_0_to_concat@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_concat@0 -lw $t0, 60($sp) #Sacando la instancia de la pila (en 52) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 16($t1) #Buscando el metodo dinamico para la funcion concat -jal $t3 #Call a la function $t3 -sw $s0, 40($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la expresion lista para ser asignada -lw $t0, 40($sp) #Lee de la pila result@assing@temp@0 en 40 para assignar -sw $t0, 68($sp) #Escribe en la pila el valor que se le asigno a temp -lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar -sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a step@block@1 #Inicio del paso 1 de una sequencia Block -lw $t0, 76($sp) #Lee de la pila position en 76 para assignar -sw $t0, 36($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum -lw $t0, 36($sp) #poner en registro $t0 lo que hay en 36 -lw $t1, 32($sp) #poner en registro $t1 lo que hay en 32 -add $t0, $t0, $t1 #en $t0 pon el resultado de la suma -sw $t0, 28($sp) #poner en la posicion 28 el resultado #Fin de la expresion lista para ser asignada -lw $t0, 28($sp) #Lee de la pila result@assing@position@0 en 28 para assignar -sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a position -lw $t0, 76($sp) #Lee de la pila position en 76 para assignar -sw $t0, 60($sp) #Escribe en la pila el valor que se le asigno a result@while@0 -while_cond_0 : #Crea el label while_cond_0 #Fin del cuerpo e inicio de la condicion de un While -lw $t0, 76($sp) #Lee de la pila position en 76 para assignar -sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a less@_a@0 #Resolucion del operado izquierdo de una opercion less -lw $t0, 72($sp) #Lee de la pila num en 72 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a less@_b@0 #Resolucion del operado derecha de una opercion less -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 24($sp) #Cargar el valor de la pos 24 a $t1 pa comparar -beq $t0 $t1 while_back_0 #if $t1==$t0 then jump while_back_0 #Fin de la condicion de un While -lw $t0, 80($sp) #Lee de la pila self en 80 para assignar -sw $t0, 64($sp) #Escribe en la pila el valor que se le asigno a step@block@0 #Inicio del paso 1 de una sequencia Block -lw $t0, 68($sp) #Lee de la pila temp en 68 para assignar -sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a result@assing@population_map@0 #Fin de la expresion lista para ser asignada -lw $t0, 80($sp) #Buscando en la pila la variable self y guarda la direccion a la que apunta -lw $t1, 8($sp) #Buscando el valor que se va a guardar en la propiedad -sw $t1, 4($t0) #Seteando el valor en la direccion de la memoria del objeto -lw $t0, 80($sp) #Buscando la instancia de la clase CellularAutomaton en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad population_map -sw $t1, 12($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local step@block@2 #Inicio del paso 2 de una sequencia Block -lw $t0, 80($sp) #Lee de la pila self en 80 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 84 #Limpia la pila -jr $ra #Final de la function evolve - - -IO_out_string: +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 -lw $a0, 0($sp) +move $a0, $t0 #Pinta el valor la propiedad **value** del String syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 -jr $ra -CellularAutomaton_num_cells: -#Parametro self en stackpoiner + 16 -addi $sp, $sp, -4 #Push local var instance_to_call_length@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_num_cells -lw $t0, 12($sp) #Buscando la instancia de la clase CellularAutomaton en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad population_map -sw $t1, 8($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_length@0 #Fin de la exprecion previa al Dispatch length -lw $t0, 8($sp) #Saca de la pila instance_to_call_length@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_length@0 -lw $t0, 12($sp) #Sacando la instancia de la pila (en 8) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 20($t1) #Buscando el metodo dinamico para la funcion length -jal $t3 #Call a la function $t3 -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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 16 #Limpia la pila -jr $ra #Final de la function num_cells - -CellularAutomaton_cell_at_next_evolution: -#Parametro self en stackpoiner + 108 -#Parametro position@0 en stackpoiner + 104 -addi $sp, $sp, -4 #Push local var cond@if_else@0 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 sum@_a@0 stackpointer 88 -addi $sp, $sp, -4 #Push local var sum@_b@0 stackpointer 84 -addi $sp, $sp, -4 #Push local var sum@_a@1 stackpointer 80 -addi $sp, $sp, -4 #Push local var sum@_b@1 stackpointer 76 -addi $sp, $sp, -4 #Push local var cond@if_else@1 stackpointer 72 -addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 68 -addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 64 -addi $sp, $sp, -4 #Push local var param_0_to_cell@0 stackpointer 60 -addi $sp, $sp, -4 #Push local var result@if@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var cond@if_else@2 stackpointer 52 -addi $sp, $sp, -4 #Push local var int_eq@_a@2 stackpointer 48 -addi $sp, $sp, -4 #Push local var int_eq@_b@2 stackpointer 44 -addi $sp, $sp, -4 #Push local var param_0_to_cell_left_neighbor@0 stackpointer 40 -addi $sp, $sp, -4 #Push local var result@if@1 stackpointer 36 -addi $sp, $sp, -4 #Push local var cond@if_else@3 stackpointer 32 -addi $sp, $sp, -4 #Push local var int_eq@_a@3 stackpointer 28 -addi $sp, $sp, -4 #Push local var int_eq@_b@3 stackpointer 24 -addi $sp, $sp, -4 #Push local var param_0_to_cell_right_neighbor@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var result@if@2 stackpointer 16 -addi $sp, $sp, -4 #Push local var result@if@3 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_cell_at_next_evolution -lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar -sw $t0, 56($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell@0 #Fin del paramentro 0 al StaticDispatch cell -lw $t0, 104($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 cell -lw $t0, 60($sp) #Saca de la pila param_0_to_cell@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell -jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell -sw $s0, 64($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -la $t0, string_1 -sw $t0, 60($sp) #Resolucion del operado derecha de una opercion int_eq -lw $t1, 64($sp) #carga en $t1 lo que hay en 64 -lw $t2, 60($sp) #carga en $t2 lo que hay en 60 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 68($sp) #Pon en la posicion 68 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 68($sp) #Cargar el valor de la pos 68 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_0 #Else case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a result@if@0 -j fin_CellularAutomaton_cell_at_next_evolution_0 #Salta para f{label} -then_CellularAutomaton_cell_at_next_evolution_0 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_0 #Then case -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 52($sp) #Escribe en la pila el numero que se le asigno a result@if@0 -fin_CellularAutomaton_cell_at_next_evolution_0 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_0 #Fin de un If -lw $t0, 52($sp) #Lee de la pila result@if@0 en 52 para assignar -sw $t0, 76($sp) #Escribe en la pila el valor que se le asigno a sum@_a@1 #Resolucion del operado izquierdo de una opercion sum -lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar -sw $t0, 36($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_left_neighbor@0 #Fin del paramentro 0 al StaticDispatch cell_left_neighbor -lw $t0, 104($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 cell_left_neighbor -lw $t0, 40($sp) #Saca de la pila param_0_to_cell_left_neighbor@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell_left_neighbor@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_left_neighbor -jal CellularAutomaton_cell_left_neighbor #Call a la function CellularAutomaton_cell_left_neighbor -sw $s0, 44($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -la $t0, string_2 -sw $t0, 40($sp) #Resolucion del operado derecha de una opercion int_eq -lw $t1, 44($sp) #carga en $t1 lo que hay en 44 -lw $t2, 40($sp) #carga en $t2 lo que hay en 40 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 48($sp) #Pon en la posicion 48 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 48($sp) #Cargar el valor de la pos 48 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_1 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_1 #Else case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a result@if@1 -j fin_CellularAutomaton_cell_at_next_evolution_1 #Salta para f{label} -then_CellularAutomaton_cell_at_next_evolution_1 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_1 #Then case -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 32($sp) #Escribe en la pila el numero que se le asigno a result@if@1 -fin_CellularAutomaton_cell_at_next_evolution_1 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_1 #Fin de un If -lw $t0, 32($sp) #Lee de la pila result@if@1 en 32 para assignar -sw $t0, 72($sp) #Escribe en la pila el valor que se le asigno a sum@_b@1 #Resolucion del operado derecha de una opercion sum -lw $t0, 76($sp) #poner en registro $t0 lo que hay en 76 -lw $t1, 72($sp) #poner en registro $t1 lo que hay en 72 -add $t0, $t0, $t1 #en $t0 pon el resultado de la suma -sw $t0, 84($sp) #poner en la posicion 84 el resultado #Resolucion del operado izquierdo de una opercion sum -lw $t0, 100($sp) #Lee de la pila position@0 en 100 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a param_0_to_cell_right_neighbor@0 #Fin del paramentro 0 al StaticDispatch cell_right_neighbor -lw $t0, 104($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 cell_right_neighbor -lw $t0, 20($sp) #Saca de la pila param_0_to_cell_right_neighbor@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell_right_neighbor@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell_right_neighbor -jal CellularAutomaton_cell_right_neighbor #Call a la function CellularAutomaton_cell_right_neighbor -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -la $t0, string_3 -sw $t0, 20($sp) #Resolucion del operado derecha de una opercion int_eq -lw $t1, 24($sp) #carga en $t1 lo que hay en 24 -lw $t2, 20($sp) #carga en $t2 lo que hay en 20 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 28($sp) #Pon en la posicion 28 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 28($sp) #Cargar el valor de la pos 28 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_2 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_2 #Else case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a result@if@2 -j fin_CellularAutomaton_cell_at_next_evolution_2 #Salta para f{label} -then_CellularAutomaton_cell_at_next_evolution_2 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_2 #Then case -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a result@if@2 -fin_CellularAutomaton_cell_at_next_evolution_2 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_2 #Fin de un If -lw $t0, 12($sp) #Lee de la pila result@if@2 en 12 para assignar -sw $t0, 80($sp) #Escribe en la pila el valor que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum -lw $t0, 84($sp) #poner en registro $t0 lo que hay en 84 -lw $t1, 80($sp) #poner en registro $t1 lo que hay en 80 -add $t0, $t0, $t1 #en $t0 pon el resultado de la suma -sw $t0, 92($sp) #poner en la posicion 92 el resultado #Resolucion del operado izquierdo de una opercion int_eq -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 88($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 92($sp) #carga en $t1 lo que hay en 92 -lw $t2, 88($sp) #carga en $t2 lo que hay en 88 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 96($sp) #Pon en la posicion 96 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 96($sp) #Cargar el valor de la pos 96 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_at_next_evolution_3 #if $t1==$t0 then jump then_CellularAutomaton_cell_at_next_evolution_3 #Else case -la $t0, string_4 -sw $t0, 8($sp) -j fin_CellularAutomaton_cell_at_next_evolution_3 #Salta para f{label} -then_CellularAutomaton_cell_at_next_evolution_3 : #Crea el label then_CellularAutomaton_cell_at_next_evolution_3 #Then case -la $t0, string_5 -sw $t0, 8($sp) -fin_CellularAutomaton_cell_at_next_evolution_3 : #Crea el label fin_CellularAutomaton_cell_at_next_evolution_3 #Fin de un If -lw $t0, 8($sp) #Lee de la pila result@if@3 en 8 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 108 #Limpia la pila -jr $ra #Final de la function cell_at_next_evolution - -CellularAutomaton_cell: -#Parametro self en stackpoiner + 28 -#Parametro position@0 en stackpoiner + 24 -addi $sp, $sp, -4 #Push local var instance_to_call_substr@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var param_0_to_substr@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var param_1_to_substr@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_cell -lw $t0, 24($sp) #Buscando la instancia de la clase CellularAutomaton en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad population_map -sw $t1, 16($sp) #Salvando el valor de la propiedad population_map en la pila en el valor local instance_to_call_substr@0 #Fin de la exprecion previa al Dispatch substr -lw $t0, 20($sp) #Lee de la pila position@0 en 20 para assignar -sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a param_0_to_substr@0 #Fin del paramentro 0 al Dispatch substr -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a param_1_to_substr@0 #Fin del paramentro 1 al Dispatch substr -lw $t0, 16($sp) #Saca de la pila instance_to_call_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_substr@0 -lw $t0, 16($sp) #Saca de la pila param_0_to_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_substr@0 -lw $t0, 16($sp) #Saca de la pila param_1_to_substr@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_1_to_substr@0 -lw $t0, 28($sp) #Sacando la instancia de la pila (en 16) de una clase que hereda de String -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de String -lw $t3, 24($t1) #Buscando el metodo dinamico para la funcion substr -jal $t3 #Call a la function $t3 -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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 28 #Limpia la pila -jr $ra #Final de la function cell - -CellularAutomaton_cell_left_neighbor: -#Parametro self en stackpoiner + 56 -#Parametro position@0 en stackpoiner + 52 -addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 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 result@if@0 stackpointer 36 -addi $sp, $sp, -4 #Push local var rest@_a@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var param_0_to_cell@0 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 param_0_to_cell@1 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_cell_left_neighbor -lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar -sw $t0, 40($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 36($sp) #Escribe en la pila el numero que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 40($sp) #carga en $t1 lo que hay en 40 -lw $t2, 36($sp) #carga en $t2 lo que hay en 36 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 44($sp) #Pon en la posicion 44 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 44($sp) #Cargar el valor de la pos 44 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_left_neighbor_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_left_neighbor_0 #Else case -lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar -sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a rest@_a@0 #Resolucion del operado izquierdo de una opercion rest -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 24($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 28($sp) #poner en registro $t0 lo que hay en 28 -lw $t1, 24($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 20($sp) #poner en 20 el resultado de la suma #Fin del paramentro 0 al StaticDispatch cell -lw $t0, 52($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 cell -lw $t0, 24($sp) #Saca de la pila param_0_to_cell@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell -jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell -sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -j fin_CellularAutomaton_cell_left_neighbor_0 #Salta para f{label} -then_CellularAutomaton_cell_left_neighbor_0 : #Crea el label then_CellularAutomaton_cell_left_neighbor_0 #Then case -lw $t0, 52($sp) #Saca de la pila self + +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 $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch num_cells -jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells -sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 12($sp) #Escribe en la pila el numero que se le asigno a rest@_b@1 #Resolucion del operado derecha de una opercion rest -lw $t0, 16($sp) #poner en registro $t0 lo que hay en 16 -lw $t1, 12($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 8($sp) #poner en 8 el resultado de la suma #Fin del paramentro 0 al StaticDispatch cell -lw $t0, 52($sp) #Saca de la pila self +sw $ra ($sp) #Salva $ra en 12($sp) addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch cell -lw $t0, 12($sp) #Saca de la pila param_0_to_cell@1 +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 $t0, 0($sp) #Mete para la pila param_0_to_cell@1 #Agrega a la pila el paramentro 1 al StaticDispatch cell -jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell -sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -fin_CellularAutomaton_cell_left_neighbor_0 : #Crea el label fin_CellularAutomaton_cell_left_neighbor_0 #Fin de un If -lw $t0, 32($sp) #Lee de la pila result@if@0 en 32 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 56 #Limpia la pila -jr $ra #Final de la function cell_left_neighbor - -CellularAutomaton_cell_right_neighbor: -#Parametro self en stackpoiner + 56 -#Parametro position@0 en stackpoiner + 52 -addi $sp, $sp, -4 #Push local var cond@if_else@0 stackpointer 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 rest@_a@0 stackpointer 36 -addi $sp, $sp, -4 #Push local var rest@_b@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var result@if@0 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 param_0_to_cell@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var param_0_to_cell@1 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 CellularAutomaton_cell_right_neighbor -lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar -sw $t0, 40($sp) #Escribe en la pila el valor que se le asigno a int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 52($sp) #Saca de la pila self +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 $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch num_cells -jal CellularAutomaton_num_cells #Call a la function CellularAutomaton_num_cells -sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion rest -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 28($sp) #Escribe en la pila el numero que se le asigno a rest@_b@0 #Resolucion del operado derecha de una opercion rest -lw $t0, 32($sp) #poner en registro $t0 lo que hay en 32 -lw $t1, 28($sp) #poner en registro $t1 lo que hay en f'{stack_plus_opr_2} -sub $t0, $t0, $t1 #poner en registro $t0 la suma -sw $t0, 36($sp) #poner en 36 el resultado de la suma #Resolucion del operado derecha de una opercion int_eq -lw $t1, 40($sp) #carga en $t1 lo que hay en 40 -lw $t2, 36($sp) #carga en $t2 lo que hay en 36 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 44($sp) #Pon en la posicion 44 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 44($sp) #Cargar el valor de la pos 44 a $t1 pa comparar -beq $t0 $t1 then_CellularAutomaton_cell_right_neighbor_0 #if $t1==$t0 then jump then_CellularAutomaton_cell_right_neighbor_0 #Else case -lw $t0, 48($sp) #Lee de la pila position@0 en 48 para assignar -sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a sum@_a@0 #Resolucion del operado izquierdo de una opercion sum -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 16($sp) #Escribe en la pila el numero que se le asigno a sum@_b@0 #Resolucion del operado derecha de una opercion sum -lw $t0, 20($sp) #poner en registro $t0 lo que hay en 20 -lw $t1, 16($sp) #poner en registro $t1 lo que hay en 16 -add $t0, $t0, $t1 #en $t0 pon el resultado de la suma -sw $t0, 12($sp) #poner en la posicion 12 el resultado #Fin del paramentro 0 al StaticDispatch cell -lw $t0, 52($sp) #Saca de la pila self +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 $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch cell -lw $t0, 16($sp) #Saca de la pila param_0_to_cell@0 +sw $s6, ($sp) #Salva **self** addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell@0 #Agrega a la pila el paramentro 1 al StaticDispatch cell -jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -j fin_CellularAutomaton_cell_right_neighbor_0 #Salta para f{label} -then_CellularAutomaton_cell_right_neighbor_0 : #Crea el label then_CellularAutomaton_cell_right_neighbor_0 #Then case -li $t0, 0 #Guarda el numbero que se va a asignar -sw $t0, 8($sp) #Escribe en la pila el numero que se le asigno a param_0_to_cell@1 #Fin del paramentro 0 al StaticDispatch cell -lw $t0, 52($sp) #Saca de la pila self +sw $a0, ($sp) #Salva el string que se paso como parametro addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch cell -lw $t0, 12($sp) #Saca de la pila param_0_to_cell@1 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_cell@1 #Agrega a la pila el paramentro 1 al StaticDispatch cell -jal CellularAutomaton_cell #Call a la function CellularAutomaton_cell -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -fin_CellularAutomaton_cell_right_neighbor_0 : #Crea el label fin_CellularAutomaton_cell_right_neighbor_0 #Fin de un If -lw $t0, 24($sp) #Lee de la pila result@if@0 en 24 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 56 #Limpia la pila -jr $ra #Final de la function cell_right_neighbor +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.mips b/tests/codegen/complex.mips index 55200f39c..28e827df6 100644 --- a/tests/codegen/complex.mips +++ b/tests/codegen/complex.mips @@ -1,20 +1,32 @@ .data +_______error______: .asciiz "Abort called from class " +_______null_______: .asciiz "null" +_______endline_______: .asciiz "\n" +_______void_str_______: .asciiz "" Bool_parents: .word 1, 2, 0, -Bool: .word Bool_parents, Object_abort, Object_copy, Object_type_name, +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: .word Int_parents, Object_abort, Object_copy, Object_type_name, +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: .word String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +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: .word SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +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: .word Object_parents, Object_abort, Object_copy, Object_type_name, +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: .word IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +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: .word Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +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: .word 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_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 "+" @@ -22,298 +34,1082 @@ string_3: .asciiz "I" .text .globl main -main: -addi $sp, $sp, -4 #Push local var self stackpointer 20 -addi $sp, $sp, -4 #Push local var instance stackpointer 16 -addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 new_ctr_Main -#Allocate a una class Main puntero en sp + 12 +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 $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 -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, Main -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data -lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -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 + +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 -Main_main: -#Parametro self en stackpoiner + 64 -addi $sp, $sp, -4 #Push local var c stackpointer 60 -addi $sp, $sp, -4 #Push local var instance_to_call_init@0 stackpointer 56 -addi $sp, $sp, -4 #Push local var param_0_to_init@0 stackpointer 52 -addi $sp, $sp, -4 #Push local var param_1_to_init@0 stackpointer 48 -addi $sp, $sp, -4 #Push local var cond@if_else@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 instance_to_call_reflect_X@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var instance_to_call_reflect_Y@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var instance_to_call_reflect_0@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var result@if@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 param_0_to_out_string@1 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Main_main -jal new_ctr_Complex #Call a la function new_ctr_Complex -sw $s0, 52($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch init -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 48($sp) #Escribe en la pila el numero que se le asigno a param_0_to_init@0 #Fin del paramentro 0 al Dispatch init -li $t0, 1 #Guarda el numbero que se va a asignar -sw $t0, 44($sp) #Escribe en la pila el numero que se le asigno a param_1_to_init@0 #Fin del paramentro 1 al Dispatch init -lw $t0, 52($sp) #Saca de la pila instance_to_call_init@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_init@0 -lw $t0, 52($sp) #Saca de la pila param_0_to_init@0 -addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_init@0 -lw $t0, 52($sp) #Saca de la pila param_1_to_init@0 +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 $t0, 0($sp) #Mete para la pila param_1_to_init@0 -lw $t0, 64($sp) #Sacando la instancia de la pila (en 52) de una clase que hereda de Complex -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex -lw $t3, 32($t1) #Buscando el metodo dinamico para la funcion init -jal $t3 #Call a la function $t3 -sw $s0, 56($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la asignacion Let c -lw $t0, 56($sp) #Lee de la pila c en 56 para assignar -sw $t0, 28($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_reflect_X@0 #Fin de la exprecion previa al Dispatch reflect_X -lw $t0, 28($sp) #Saca de la pila instance_to_call_reflect_X@0 +sw $ra ($sp) #Salva $ra en 12($sp) addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila instance_to_call_reflect_X@0 -lw $t0, 32($sp) #Sacando la instancia de la pila (en 28) de una clase que hereda de Complex -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex -lw $t3, 44($t1) #Buscando el metodo dinamico para la funcion reflect_X -jal $t3 #Call a la function $t3 -sw $s0, 24($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Fin de la exprecion previa al Dispatch reflect_Y -lw $t0, 24($sp) #Saca de la pila instance_to_call_reflect_Y@0 +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 $t0, 0($sp) #Mete para la pila instance_to_call_reflect_Y@0 -lw $t0, 28($sp) #Sacando la instancia de la pila (en 24) de una clase que hereda de Complex -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex -lw $t3, 48($t1) #Buscando el metodo dinamico para la funcion reflect_Y -jal $t3 #Call a la function $t3 -sw $s0, 36($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 56($sp) #Lee de la pila c en 56 para assignar -sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a instance_to_call_reflect_0@0 #Fin de la exprecion previa al Dispatch reflect_0 -lw $t0, 20($sp) #Saca de la pila instance_to_call_reflect_0@0 +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 $t0, 0($sp) #Mete para la pila instance_to_call_reflect_0@0 -lw $t0, 24($sp) #Sacando la instancia de la pila (en 20) de una clase que hereda de Complex -lw $t1, 0($t0) #Leyendo el tipo de la instancia que hereda de Complex -lw $t3, 40($t1) #Buscando el metodo dinamico para la funcion reflect_0 -jal $t3 #Call a la function $t3 -sw $s0, 32($sp) #Save el resultado de la funcion que esta en $s0 pa la pila #Resolucion del operado derecha de una opercion int_eq -lw $t1, 36($sp) #carga en $t1 lo que hay en 36 -lw $t2, 32($sp) #carga en $t2 lo que hay en 32 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 40($sp) #Pon en la posicion 40 el valor de $t3 #Fin de la evaluacion de la condicion de un IF -li $t0, 1 #Cargar 1 a $t0 pa comparar -lw $t1, 40($sp) #Cargar el valor de la pos 40 a $t1 pa comparar -beq $t0 $t1 then_Main_main_0 #if $t1==$t0 then jump then_Main_main_0 #Else case -la $t0, string_0 -sw $t0, 12($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 60($sp) #Saca de la pila self +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 $t0, 0($sp) #Mete para la pila self #Agrega a la pila el paramentro 0 al StaticDispatch out_string -lw $t0, 16($sp) #Saca de la pila param_0_to_out_string@0 +sw $s6, ($sp) #Salva **self** 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, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -j fin_Main_main_0 #Salta para f{label} -then_Main_main_0 : #Crea el label then_Main_main_0 #Then case -la $t0, string_1 -sw $t0, 8($sp) #Fin del paramentro 0 al StaticDispatch out_string -lw $t0, 60($sp) #Saca de la pila self +sw $a0, ($sp) #Salva el string que se paso como parametro 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@1 +sw $ra, ($sp) #Salva $ra para saber a donde retornar + +jal __str__length__ addi $sp, $sp, -4 -sw $t0, 0($sp) #Mete para la pila param_0_to_out_string@1 #Agrega a la pila el paramentro 1 al StaticDispatch out_string -jal IO_out_string #Call a la function IO_out_string -sw $s0, 16($sp) #Save el resultado de la funcion que esta en $s0 pa la pila -fin_Main_main_0 : #Crea el label fin_Main_main_0 #Fin de un If -lw $t0, 16($sp) #Lee de la pila result@if@0 en 16 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 64 #Limpia la pila -jr $ra #Final de la function main - -new_ctr_Complex: -addi $sp, $sp, -4 #Push local var self stackpointer 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 $ra stackpointer 4 -sw $ra, 0($sp) #Agrega $ra a la pila para salvar el punto de retorno de la funcion new_ctr_Complex -#Allocate a una class Complex puntero en sp + 8 -#atributo type_name en puntero + 0 -#atributo x en puntero + 4 -#atributo y en puntero + 8 -li $a0, 12 +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 -sw $v0, 8($sp) #Reservando memoria para una instancia de tipo Complex -lw $t0, 8($sp) #Lee de la pila instance en 8 para assignar -sw $t0, 12($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, Complex -sw $t0, 4($sp) #Cargando el nombre del tipo desde el data -lw $t0, 8($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -lw $t1, 4($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 $s0, 8($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 16 #Limpia la pila -jr $ra +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 -Complex_init: -#Parametro self en stackpoiner + 44 -#Parametro a@0 en stackpoiner + 40 -#Parametro b@0 en stackpoiner + 36 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 32 -addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 20 -addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 16 -addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Complex_init #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad x -sw $t1, 24($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 36($sp) #Lee de la pila a@0 en 36 para assignar -sw $t0, 20($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 24($sp) #carga en $t1 lo que hay en 24 -lw $t2, 20($sp) #carga en $t2 lo que hay en 20 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 28($sp) #Pon en la posicion 28 el valor de $t3 #Inicio del paso 1 de una sequencia Block -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad y -sw $t1, 12($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@1 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 32($sp) #Lee de la pila b@0 en 32 para assignar -sw $t0, 8($sp) #Escribe en la pila el valor que se le asigno a int_eq@_b@1 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 12($sp) #carga en $t1 lo que hay en 12 -lw $t2, 8($sp) #carga en $t2 lo que hay en 8 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 16($sp) #Pon en la posicion 16 el valor de $t3 #Inicio del paso 2 de una sequencia Block -lw $t0, 40($sp) #Lee de la pila self en 40 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 44 #Limpia la pila -jr $ra #Final de la function init - -Complex_reflect_X: -#Parametro self en stackpoiner + 28 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Complex_reflect_X #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad y -sw $t1, 16($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad y -sw $t1, 8($sp) #Salvando el valor de la propiedad y en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 16($sp) #carga en $t1 lo que hay en 16 -lw $t2, 12($sp) #carga en $t2 lo que hay en 12 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 1 de una sequencia Block -lw $t0, 24($sp) #Lee de la pila self en 24 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 28 #Limpia la pila -jr $ra #Final de la function reflect_X - -Complex_reflect_Y: -#Parametro self en stackpoiner + 28 -addi $sp, $sp, -4 #Push local var step@block@0 stackpointer 24 -addi $sp, $sp, -4 #Push local var int_eq@_a@0 stackpointer 20 -addi $sp, $sp, -4 #Push local var int_eq@_b@0 stackpointer 16 -addi $sp, $sp, -4 #Push local var compl@_unary@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Complex_reflect_Y #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad x -sw $t1, 16($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 24($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad x -sw $t1, 8($sp) #Salvando el valor de la propiedad x en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 16($sp) #carga en $t1 lo que hay en 16 -lw $t2, 12($sp) #carga en $t2 lo que hay en 12 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 1 de una sequencia Block -lw $t0, 24($sp) #Lee de la pila self en 24 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 28 #Limpia la pila -jr $ra #Final de la function reflect_Y - -Complex_reflect_0: -#Parametro self en stackpoiner + 44 -addi $sp, $sp, -4 #Push local var step@block@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 compl@_unary@0 stackpointer 28 -addi $sp, $sp, -4 #Push local var step@block@1 stackpointer 24 -addi $sp, $sp, -4 #Push local var int_eq@_a@1 stackpointer 20 -addi $sp, $sp, -4 #Push local var int_eq@_b@1 stackpointer 16 -addi $sp, $sp, -4 #Push local var compl@_unary@1 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 Complex_reflect_0 #Inicio de una secuencia Block #Inicio del paso 0 de una sequencia Block -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad x -sw $t1, 32($sp) #Salvando el valor de la propiedad x en la pila en el valor local int_eq@_a@0 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 4($t0) #Buscando el valor de la propiedad x -sw $t1, 24($sp) #Salvando el valor de la propiedad x en la pila en el valor local compl@_unary@0 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 32($sp) #carga en $t1 lo que hay en 32 -lw $t2, 28($sp) #carga en $t2 lo que hay en 28 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 36($sp) #Pon en la posicion 36 el valor de $t3 #Inicio del paso 1 de una sequencia Block -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad y -sw $t1, 16($sp) #Salvando el valor de la propiedad y en la pila en el valor local int_eq@_a@1 #Resolucion del operado izquierdo de una opercion int_eq -lw $t0, 40($sp) #Buscando la instancia de la clase Complex en la pila -lw $t1, 8($t0) #Buscando el valor de la propiedad y -sw $t1, 8($sp) #Salvando el valor de la propiedad y en la pila en el valor local compl@_unary@1 #Resolucion del operado derecha de una opercion int_eq -lw $t1, 16($sp) #carga en $t1 lo que hay en 16 -lw $t2, 12($sp) #carga en $t2 lo que hay en 12 -seq $t3, $t2, $t1 #$t3 = $t2 == $ t1 -sw $t3, 20($sp) #Pon en la posicion 20 el valor de $t3 #Inicio del paso 2 de una sequencia Block -lw $t0, 40($sp) #Lee de la pila self en 40 para assignar -sw $t0, 4($sp) #Escribe en la pila el valor que se le asigno a @result -lw $s0, 4($sp) #Envia el resultado de la funcion en $s0 -lw $ra, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 44 #Limpia la pila -jr $ra #Final de la function reflect_0 - - -IO_out_string: -li $v0, 4 -lw $a0, 0($sp) -syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 -jr $ra 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/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/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/hello_world.mips b/tests/codegen/hello_world.mips index 47560dc29..d18336e49 100644 --- a/tests/codegen/hello_world.mips +++ b/tests/codegen/hello_world.mips @@ -1,76 +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: .word Bool_parents, Object_abort, Object_copy, Object_type_name, +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: .word Int_parents, Object_abort, Object_copy, Object_type_name, +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: .word String_parents, Object_abort, Object_copy, Object_type_name, String_concat, String_length, String_substr, +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: .word SELF_TYPE_parents, Object_abort, Object_copy, Object_type_name, +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: .word Object_parents, Object_abort, Object_copy, Object_type_name, +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: .word IO_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, +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: .word Main_parents, Object_abort, Object_copy, Object_type_name, IO_in_int, IO_in_string, IO_out_int, IO_out_string, Main_main, +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 20 -addi $sp, $sp, -4 #Push local var instance stackpointer 16 -addi $sp, $sp, -4 #Push local var type_name@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 new_ctr_Main -#Allocate a una class Main puntero en sp + 12 +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 $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 -sw $v0, 12($sp) #Reservando memoria para una instancia de tipo Main -lw $t0, 12($sp) #Lee de la pila instance en 12 para assignar -sw $t0, 16($sp) #Escribe en la pila el valor que se le asigno a self -la $t0, Main -sw $t0, 8($sp) #Cargando el nombre del tipo desde el data -lw $t0, 12($sp) #Buscando en la pila la variable instance y guarda la direccion a la que apunta -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 + +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 -Main_main: -#Parametro self en stackpoiner + 16 -addi $sp, $sp, -4 #Push local var param_0_to_out_string@0 stackpointer 12 -addi $sp, $sp, -4 #Push local var @result stackpointer 8 -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 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 +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 $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 +sw $ra ($sp) #Salva $ra en 12($sp) 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, 0($sp) #Lee el $ra mas profundo de la pila para retornar a la funcion anterior -addi $sp, $sp, 16 #Limpia la pila -jr $ra #Final de la function main +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 -IO_out_string: -li $v0, 4 -lw $a0, 0($sp) -syscall -lw $a0, 4($sp) -addi $sp, $sp, 8 +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.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/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/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/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/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/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/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/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 + From 83d1178378111ce80a83609ce6f7ceb71b24cfa8 Mon Sep 17 00:00:00 2001 From: danielorlando97 Date: Sat, 5 Mar 2022 22:08:21 -0500 Subject: [PATCH 89/91] finish info and add to pdf --- doc/report.md | 329 ++++++++-- doc/report.pdf | Bin 0 -> 108925 bytes src/cool_compiler/__main__.py | 4 - .../type_data_code_ast.py | 301 --------- .../type_data_code_visitor.py | 536 ---------------- .../v1_mips_generate_old/mipsgenerate.py | 533 ---------------- .../v1_mips_generate_old/mipsgenerate_ast.py | 580 ------------------ 7 files changed, 272 insertions(+), 2011 deletions(-) create mode 100644 doc/report.pdf delete mode 100644 src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py delete mode 100644 src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py delete mode 100644 src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py delete mode 100644 src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py diff --git a/doc/report.md b/doc/report.md index 154c7071a..e9b0392c2 100644 --- a/doc/report.md +++ b/doc/report.md @@ -5,8 +5,8 @@ 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 direccilón en esta ocación terminado en `".mips"`. El programa se puede ejecutar -con el commando: +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 @@ -17,32 +17,32 @@ debe ser instalada previo a la ejecución del programa. Para instalar dicha libr ## Arquitectura del compilador -El compilador es un único gran módulo `cool_compiler`, que contiene otros 7 módulos más: +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 asigantura, cuyas impelmentaciones ha servido de +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 decoredores necesarios para +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 -realizarón pequeñas modificaciones para ajustarlas, más aun, a las necesidades del desarrollo: +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 funcion a la cual decora, una vez - dicha funcion concluye sus valores de retorno son utilizados para instanciar la clase en - cuestion. Además pasa del nodo de entrada hacia el nuevo nodo resultante la informacion - sobre a que linea y columna pertenecen dichos nodos en el codigo original + 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 analisis de código de cool que se desea compilar, su función principal +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 lexicograficamente significativas y según -este significado se les asigan un tipo (literal, keyword, type, identificador, number, string, etc). -El desarrollo de este módulo se apoyo en la libreria **sly**; expecificamente la clase **Lexer**, la cual -brinda la facilidad de definir un automata que reconozca las subcadenas significativas para un +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 expersar la lista de expersiones regulares que el automata debe reconocer, en este caso en +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 @@ -68,12 +68,12 @@ particular se definieron de la siguiente manera: ... ``` -La propiedad _tokens_ de la clase que hereda de **Lexer**, por defecto interpreta que los typos de +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 mayuscula o no. En caso en que el comportamietot por defecto no se ajuste -a las necesidades del lenguaje, **sly** permite que se redefina la expresion regular asignada a los typos +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 expresion regular, es definiendole a la clase que hereda de **Lexer** una propiedad igual al tipo de +la expresión regular, es definiendo a la clase que hereda de **Lexer** una propiedad igual al tipo de token que quiere redefinir: ```python @@ -85,8 +85,8 @@ token que quiere redefinir: 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 analisis del automata. Para explotar esta caracteristica de la libreria -basta con definir un metodo dentro de la clase con nombre igual a al tipo de token al que desea reaccionar +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 ... @@ -96,35 +96,35 @@ basta con definir un metodo dentro de la clase con nombre igual a al tipo de tok ``` 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 analisis diferenciado. +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 automata finito determinista para reconocer todo el lenguaje. Para completar el reconocimiento -de estos fragmentos, apoyados en **sly**, se impelmentaro automatas con manipulación de memoria y asi poder contar +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 checkear la consistencia sintáxtica del código en cuestión. Dicho módulo tambien fue -implementado con la ayuda de **sly**, expecificamente con su clase **Parser**. Esta clase facilita la definición de -gramáticas atributadas de manera extremadamente comoda. Heredando de **Parser** se pueden definir métodos como -atributo de cada produccion de la gramatica y mediante el decorador **@\_** se expecifica la produccion a la que se le +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 teminal cclass - # en prod.epsilon se encuentra el teminal epsilon + # 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 cabezera el no terminal `expressionn`. Para que el parser sepa decidir +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 presedencias de los distintos operadores, la clase **Parser** tiene la propiedad **precedence**, tupla de +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 -redefinir, en el caso particular del compilador de cool se redefinio de la manera siguiente: +predefinir, en el caso particular del compilador de cool se predefinió de la manera siguiente: ```python ... @@ -143,43 +143,258 @@ redefinir, en el caso particular del compilador de cool se redefinio de la maner ... ``` -Aprovechando la caracteristica de que la gramatica se encuentra recogida en una clase, se desarrollaron algunas herramientas -para realizar la inversion de la dependencia entre la gramatica 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 fatoria de nodos, además de un +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()) + .... +``` -#generacion de codigo Mips -Para el inicio de la creación de código Mips partimos de la base de una librería escrita en este lenguaje la cual contendría gran parte de las herramientas con las que no apoyaríamos y así nos evitábamos la doble escritura del código . La librería es una herramienta simple , en ella se encuentra a modo de macro la implementación de todas las funcione de IO , como IO_out_string,IO_in_Int ,entre otras, las cuales tratábamos como funciones nativas o especiales, dado que en la conversión de CIL no teníamos contemplado el desglose de la implementación de estos métodos , solo detectamos que hay un llamado a estos e inmediatamente tenemos preconcebido el código asociado. Además de las de tipo , entrada y salida de información , tenemos otras macros, las correspondientes al tipo string ,como substring , concat, lenght , las cuales se muestran en la documentación como funciones integradas a este tipo. Otras macro en esta librería van asociadas al tipo object y a sus métodos como Copy , Abort y Type Name. -Se utilizó una creación de tipo Int , Bool , String , la cuales contienen en su primera palabra la caracterización del tipo y en la segunda la propiedad value del tipo , por lo que en cada utilización de alguna operación que involucre alguno de estos tipos, son tratados de esta manera y siempre que se tenga una salida de algún dato de este tipo , se reserva memoria y se crea una nueva instancia que sera el valor de retorno. -Las operaciones entre los tipos enteros , no las podiamos realizar de manera natural debido a la representación que describimos anteriormente , por lo que también tenemos predefinidas los métodos básicos de operaciones aritméticas tomando como entrada los registros de propósito general $a0 y $a1 , dentro de esta se enmascara un poco el paso intermedio que se realiza antes de llegar a la manera natural de resolver las operaciones y creando un tipo nuevo de entero como resultado. De manera similar ocurre con las comparaciones que devuelven un valor de verdad. La relevancia de esta manera de tener los datos nos ayudó bastante para tener un chuequeo del tipo utilizado y simplificar algunas especificidades del lenguaje COOL. +### 5 - Módulo Semantic -A la hora de recorrer el código intermedio centramos nuestra conversión en crear una definición de cada clase , con sus funciones y atributos, ademas del nombre y luego las instancias de estas, las cuales se salvaban y mantenían validas en el programa a través de la pila. Posteriormente se desarrolla el código especifico de cada función utilizada y se utilizan los saltos para entrelazar mas de una.A continuacion mostramos un ejemplo de la representacion en codigo Mips de la clase Main: +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 - 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, +@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)) + ... ``` -Otro punto importante en la generación de nuestro código Mips fue la utilización de la pila y el mapeo que utilizamos a alto nivel para mantener un orden en esta. La creación de la clase “Stack” es la estructura encargada de que los parámetros recibidos y los puntos de retornos de los saltos fueran los correctos entre llamado, la cueal cuenta con lo siguiente: +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 - ... - 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 - ..... - + @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 +``` - La estructura contiene unos métodos los cuales se encargan de su llenado y vaciado siempre teniendo en cuenta que cada dato era insertado de 4 en 4 con respecto al registro $sp. Cada argumento de las funciones son pasados a la pila antes de su llamado siendo luego los métodos los encargados de utilizarlos y dejar la pila , luego de su culminación , sin estos elementos. EL cambio del valor del $ra fue un tema importante con el que nos topamos por lo que también seguimos la linea de ponerlo dentro de la pila y luego asignándoselo al nuevo $ra para que la función pudiera retornar al punto especifico donde fue llamado y no creara conflictos. - +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 0000000000000000000000000000000000000000..32f2ac1db240c5531f20277a1b177cf9cc3d8d18 GIT binary patch literal 108925 zcma%?Q;=p$w`jX;cG>fvuqhG!GBGG{DBx$&7&cpBqJbQFALNfCIg#m4OpL z1Yl%q4B+E~c64$87+6EQWfg0US6p_WX6M$H+2>KE7_Twmz#dtEr}J{e369ag86%Em z9=;HpORY;~Uv=yWWm9Qg*{tX;;M(lp@6`TihfLaG7qv?ZZKh~w9|wPbf4|i7|Lon{ zuI!hD46pKg%#D0yixD1A-u!&7`}CNYkET!AVbk;bc7EQ`(iwJqejd>81Y#U|B<}=j z*6w>^K=4Xeen}vl{N-cbo8JF9S249cyV&x6>TR8S-}9NvlY9Bw>IQeiGTo&+YWu;B zPv?Sf9oqZ-d3N#i@U+oBZSKx&?pU~!g|VqR@V-*%;dVo|(i&`%icTolG$E0{_&2KMx04Dwp^(~w|4O7@niF*${-Q_r zX2w^KA$BPyF4|?TO;7UAG_l0_jz%QTNT$_|FsFI+^&sZxUutis$hLQ}$CauP`XLzA z57N~$yq@;^isuGjaHGa)U7z;7qbAuI3`Km!EzhToJojtCG%8u^QwXTFSevqq$R$&J z7^HO`^L)u5tOp^;kT1x1%=Z0R5dy?qPEmkhZ8`Ty_Lu)pF0nF+WP%k!VT#js13Z2!rRs2)Cle z(@ti}h=&BaemC(?%7PW=VwSSoSFJ|Dg9!!LjTV9a_6uC$|0ARwo2I#PWFQ}YM|e^^WiERHYmRbHd)}u(HiR4 zm<->W+wOPnG-nVipu^@8khEHYzy7m zmG(?gg5eOGlr3{K%t~d!pH9mzxw4A0_IS?_ibl*ljA1?!ENx<{%ZM)oKSZ?arYaa3 zVXJ_2unRi{Rne_9WWIq^GWS-ZkeNw|q~E_3>8@#H?o1*2rGIG8c#Ms!V@W4Js4zSYb^Sb2#;41hfGP9tK1h!8N4wgM1)v zqRf>GRsl4oLjWc~DI+*SkB06eM04-=nsT@;es-hU*qiU=`oWkd==u?J= z$qUltbBJc_-Xl&W5KE+50loy~uLg5d zhOOq=6a?Z%XR5|Kz_%9VBH!<9VJC0QNO+*Na!r~n;Y0$HtX83!J?J_H={Thm$4`fu zliP;l5THtVzpYXM^Rsu;y zl)V+l?S=%Fdy6LYG;8pxl-QE{#z*3Q+*4lc)~VL3S`2Yj5TKke$$FbiMR_(*Y_}Yx zTO}TX_DB^;Wf(a)F`hNX)`t}Dm`_7ZJ~JZk?>m&ro9(! z=|}g3aE9;))!CHad=XNPti-~=SBEV{*q(=kVrAxGb_oh49ulGg{N}rcOTBz4AysYF znf~*iremLDu=j7^BpiDP?*`^V2-j6#mSY#Q;T(C|L$k7Bd92G=TdmFA_N1z!s&-I@ z5|`wA!KfMkY&z&N76byMvThF#^hDZCgEQ^6oqmH<=WspL#+|JOK@0PK5h(&gsTKkm z%)mH&+Ck&Q$a#XQj8F;0nu%!uzVi1s??4~kpqUC6r9z8udw2KCvTo+GB~dJyNS0AP`O5{SoI%q`_cijwz~m!}gw z8Lq7igUZn1>r8gE(4QltX#&D9C<9pcwGl0Wd?IE-shF{4qBm<43l;W(w@^Pihjqz0N^N%(cA`siu(&i zuHy2C4t#D4YHFpRQ@ppp{H*b$56R?7YpP^TyF*IbVy?1%6spBX&9Vh!_a4kx1<@{i z;JsgeBae!q`iR~j7POqLK$e=(;o!7nhv8Ks;7<;b6i)In;MfG0wcW1d=X)vZYX9V0 z(q=TJ64fXJiAiEve$fAzw-ldW^(Q#KX;mWP;S8buGQbaaoxB@uE*v@w?R>p#}l zj|3S+m*_JjC^?vc!!rPo$8>A4LpU4AZxRqScT{rNHILYn=im~vPizua;O}FykJSLi zW?u~$XIt9nU-ypC-}VsCJ`E;CSKR*2GltJqh-RLo?Y9`*)k}_FoBF>_UBNh@{GNc- z&p{-(iW}4|{Db+o@T`GVW+#3A#!X>3H5tsZ3f=PVQ7(HMP!BeDB0{#K(yDnradMEE zGhD2uK_M)vnKvmmZnIv@hsXiD%L?ysR(PpO6cZFw8NZ9rc_?mR&Z~w z@FRV)*T{4bGBcl;pa+3>&pr{0KG|1+q(oqqtu6W9fg}z7g`@jN`FRGCkm=U>bbHI5 zI|Es^o$Ng%~aghlN0oka&j zmnppH->30%n9z2id*F)Dsv|QHgju)mp8V#NOp9vNpGep+H{h1>od*lB>QBUd5He^@ z*VreKmTjaM0p1e{c$57Vy2(m#SBk~;S4EO8VsHsSvvwI(3lnQ=It?AF<2~_{Tzchn zte~pVpP;dgp3K~#yNx4X_bnE3Xn>9J{|4uOPXDqt^uLJx?}3Sfjp^Ud|G8xSFC@

&3uEbsJZMo4|067!FcQ450!J>An03IVq*h#;)W+v9*^q zRJ`3fw#=OKgFo9o{Ba14-6 z@VWf>-*@^D6Y#mc-yhO7sl@z=u`t|;S46YQIx&yZMcwpUxG#vhd+0tTpAN=**4fty zp}iNj^7f3T_t*XyuSIGv7 zb>z@o|Cd_Ql`cW=)|a<>-0$u(edz}7@(0{!N;xDDSB z`JB%~*%8eHKZ3b@IK1%p9=st%Z;^8FI7@JREgBl_0-FkHfKP}T-9qU|PDlR?yY7Jl ztBliZMiYQ9)yd?*mWYyBnDq_W(pP0uj*?pJ!Ry=0N`f2B*o~%@d$sA4FN+0(?6B2g zOBJO)L&l&Pu_SB}<^IZo%_(5g&v~5;_f|l~10?{O#Me-6?g+u&->*VDtUn5##R?;& z)zJYZbzvEwJzK{#h{gB>CQXOTllgnj;#7B=48U#^rH9(4@wkfQBPVA+1fvx>$^j@> zCBm|hvfJ1KdPQ2Ljha{=M|ttFFh5QQZklD#eqrTCZZ`c=jEClFxS(ORr2-Vo7NjsO zOvZBye)m7JM5YE@<%s6^4g9fgMu~fb-Nuwn%)bC#2nrM9=9kZiap}$4n}q0)CUmgy zUIiAJ5MX=Ggz)Tq9n9ezh+VQI+#Z!A_>Qg7b76DLcz)ZtRv38r^HW@9(?Fr_L`~vPp4E!A7)*0ykbYgitH>@w^wGSo)*7&()*|BM% zZF}U{;McrhNya`uQzF==HUoyJ;wMxre%jIqqjQroMu(Et|t-uj3yT_y^0<~ zc@}#G@_MoQ7Vu$>BE}0RVNi$P;|NM%1e=*2{uBef`nGjO%dv-XQiHNSbT{b5HDUt%P|VW8knx_xQ-Px?pvQs8VJO!x; zBL&YbR3a=<2}_W3WLy=|A*jsD3^yn*3P&X0xvp(jALnrOzS_rF;Dm2c@6GA>pOEt;Ltq~-`FD)V%tyT)TY_5(9oe)Qq{!IO+6?_W>@3*KJ?d0^L_OJOmx)EG}i zq7xBZyJgh`nsj+&YQ4>=>5;fGP_Scti3O;dsT(*wwWv5}VDVi4aCD8bJk{6H#^*U8E%-)g&Yq#zz-j z?y@@#G-OvXB3*|fVu_qWCQf-P*iOXjQ$7;2Y#1*mI9N_xE^e`JLPSo{-tknSWtL!O33L2;g0eRJ{vI(ULTuVTCYo7E zGT%DuAxD3$H09IDH2XU8Oe>2X2FDEfU1Eh$i}-YLdpwmr`4VW*G;@ut;h(EFhB_eU z<3_4O{aQ=$Se2V5cAEL=S^V}SftPm3d?zr}lfu!)RDN*>5AqecNu1M~0g2@y59q?& zXamQt(Z<9Y#dNRnK}iQ$pLl;yhv?CgE3U$!u7RAZv)WT1Z)sxo8Yt4HMyDx#n~DXY z6A+m`c*@Y;Sapy|a+zI&ji^j>R$Z-5!RGJbTrOro`MxAA176}R=bg~uhR*n`!6(j2 zfbMuF>n@2XzXjo@qRm~w5~RqgYCbT@o?p7wL6K}csgYktorNhDGe?ftjeEUfjyfO4 zo2by4i)MF>_{{Kzp6EVyv;c&ddgB%!`CED%)XYB#>LZqPD|W>K#TXj=82;8z4h}J( zU4#O&*XQjs9pNm)dw7Q7GZWC%9oVU_^0R=-j@WPWt3zxpVsu2ey4Ru`?dw;B_@yVu zSGFz6yiegHz#M_6Wx0H+OrykwnP`ZU%Km2IX~D0tcvjzzvG7wehoyNG@sMu>0-%47*J`*_R5wqt4+eF@4zzVm9MREg#R2wO+*N`p+pIYdM0ljX{>s8D|j)jgGG%@kc95e!p8zvBnRQ`MWNh!c4GPA`=2}aPfKu1S&5g zirgfUL>*Py$oXVqu2pU%8ByfR0(xoWPq$ZoI`IjC{{~S1CC~o=DjO5${{>Wz{{pC- z{~v(btt}Nv-HEh4TYJmJAbaswaZvx(sB7$cKmd)fa}%@y^3dk~g}A&(QG#mRde#7P z<+-U^vAoA4RW_xND|Tn+`@M9~cNhKJ*Z1?{>i)^3 zSkDCARU1L?hvV~&4nYX7=liWS_76>K;+uNQV&}X1%$-X1QYb^|XX{)fyzkg6;M0w> zd-Aq=9RKf`jxWv2;(Pt-YonIer#rHgE`}@O#hFeYeB_2atvqE!%VdC_};ok&(tk}2016N?A z%-b3m&YP#pSk2=l(Ety7VXWoo)m{R2#Vip~u5(pzTt?CXT%2O$Vm)%FUk_PHNm{N_ zL;}*#Gy15%2vp)c*P&6MUL&z>X>T0A3+l%cYkYOok*LyDzLs*BOk5iX8e~XS&n}cJ zHy4CGVbr}wh_@F%oWrgQVj>bKzroctB1O3Lp?2=L8K45hczn>9(|VSM2b_W8y{4KT zj1YPoNr~jJTRQGwg~qa%Lso z_~z{_P-2>jhU$Jrc7&u_i~OOzP-s8~!SfGyYdLgMq~Ix~zh$Y3p!mCI z**zsj3)Gwzwi?#OmABre$dM53Gyl97k-dQl@{OKM)f4pVJDrzScEZK zO1VTRH~6T^7homb{Jc!{Y-FmUhzChy&1A5l9E9;*>~*-9#9J{FBt<4>0hcbnO$87N zE?0Jgu5{R5VXx!M)K{p#9Z$Aqz3s$9k0$GUXB}qwIcH{al0sirGOZ9^qi9|lpp19o z{$oG3r)V9Ml1zQ{rn*TgP805IZDf)No`H2~*g5o`fEs08E2-|1(Yw^0lO{rsNpOk& zLhny#E^Rmh_c-WBA$|1j#HpNVw&*yNTg+rcyBvN``mCkpo~jIDOHxLPl)W*>L0!0B z2P8ghSzrBimzo$ ziIqN<8EFYH_N9VooZx#yUFyWn*dWa=t&c4CHRH7_t;qx83Wk+Y{=KBES?r4zY9i8Yx6|Bq|Lm}w!LB#qiiQux z5U}}K9HCTweOmUI1DPcI5tZ5 zstA@PMU*%;ih{RF=ZN{uf7uF=cqgBRJ;`SbsHKY9niQKt_L?5}{sxGy}M12CC(6y{;!$8_L=K}PQbHrW@S>Cqs?DtSC zvpZ3pv!ynPIfoNao|InrAT4Ir1+#p@Vf>>-Z|-cc%+@+;LE9abX8@PgX^McK%b7={ ze{xwkvfjDJNX`2Di;AZ8z(-3MEz;J&SPWvbxUxtAGE?klf&G2MzLYqW%zJTQpm24( zdxzhlaa{XQiZ)r%_&s-(wB@f<)Rj|`zpUq)CN>R!US-yesFaKzHt*3Vnh*g14?#*1 zi6g}1p%Z5jaJ@b#{y6ak2#eQU#c+hO&}5-_Q@1KhqR@rjT{3}(2n02f0tEuHMofZn zmR&)jAX8_sHnBK+O-6-Y$|_CI(6>qhT9IA|%hFx{Akhc=!%vir7iZ`iFTblwMCmC7 z*^)ZHzy!I1yuzi_LLi2r4s|vEIR#|}?9g|D0n!i~4GM?eZ=IH8a4ddJYsEZdW9WQH z;~0lOz0P8H>TzhhdYyvN0W=n{83jO53K7(-jlOBb@xPrCUcxUE8^}k|7fv-_VA_*U zdqkLVCHW_8rliT+KNSO_D2d=Q-4Cgv@A_z|dIFElPWmS|JmuS`fxsVaWzg$Vd4+`% zDAcBayz!*pLY#mKi}BHzFvijSA962bpdGN>X)DTrf{@}W;Z24dFXi4j<3LZi$g{V`E?8entg$yBR;kX?BI)iU$Pv)u7 z*B#bcnqyM6pOkL?j zZE{OB&noAuvYSQ8Yb=QV(aMi2nbm|IFeu+(Qk#W*bI8GLF=ZSEs`f_)HUaOr&Z>iM zuB4dFO5qANBk}wb7UL8KYaN@J&y(;BRK9Rt&sGkSx-kJ zEr>-73SABZIAXb(eCUxf^gAmw+yFq7Wq`Tk?rm*huoxLzq*)^>u&Ogg{kj}h19Rfh z!r4*0uq}mkel4ZSW`>E_^1?o!tm~meG(hPcmQ$#+-FQ)ex)XIbkX)kWx{|w8^I&DjX9i-}t4xTCVDxZKWpn=E{Olt| z=JwDbKSaB3VTay8;HYHa#@&H4fvC~eB@j-yKF_tZRV?O@xLQP#J}G(i3WQTX9xoHC z@qALhuj7aI-d(iQR-8Y#J!<$t*#&Boec5%9&}6-^xNcPGFX#9Dl4Yow6Q?v>nTW^;R*zBhAtoL7GV8 zF26kO%15FMEd=!aso*_G&bXMP?5Fx_K=A$~<9n#mp5SWnR~r zePeSu?_>MIs$GM9Ne6<$G-GW0+E9>M=SZJVBIOnu;Gyp-+M`!ku<1kZ2^q8cz(tvr z!&tJZO^P(z}A{Px#zG6osLLu=$$; zcy?SWg2DLkvrle)p7HtA-}h@=IcDR=nO8roy9y$Upx~E^%iMhgJQq*m-N>-pCPJIt z$yQ+Gnh#6z!LuhWddTWz+rMuCbF7lLdc?jqe@X1Qc6QUf$1F_-oTNvrIN?Qf>vf8q zO8!_m3|zi+HzX9k8ftJF!+XX0$PW*N4aBbo2BPq1Vl#Yn+x&v9PnFRhTRp)e-c`Lp z@_qZ+O^?)@?$pj)!xUU4Td@uO0ZFe&Y58vy`DhOTM}Rq)}A`^$HG_^6#VI=^DrGid#9Wu}$LjUJMLQ#rFDqogF3qukkLZjDRax;L*T@pygC2MBotNUFlfu1Zb0cq&puTU zpDhn}V0ja*0_>AVA7eDXK8hLW)su0XYHKiHqrH8~h5%1P)cZEr9BHdFX|++pxTY3m z2@WFyBctKp;k0vMDnfjek92)fSgK(AA4^7Va~#NaXci$iw-_oz?y1zR?7#k{JiKF`MB4)TpY;tz^Ud~tO(8Fq9#7#f2FsMp&^L@ zW|e%Wh5qgCfZ3sHJB+; zM>@hdZfk-{;L$T}uZl>r<>~*mfYGeN0&xfqgY?27?fH$9U9MLP49{-2FqOyrd=LZ+ zsC3I`ibbHQiU<`~QG84&fD+|kmb_EBE^riJ648PUG;raYS;Q-Ca7lki#?=!XxGtE~ zRnJl^Qu9nJN@a%~7Bo<9pxRfm% zg*&40Vtns%WII=*B*u=0xn#tC_XMkoD#0402}L)mBH4>kR>&u9PzHiZ#EeE`?q|gm z*02b#CHxpioH0oo{kR+<5*X9$09`)jdS55lwzgU$ZP$Hs0FAqppX>cyc{(2?YBZ?PcqxcI}XF*GU;5rAs9}eKOKeQ87y{#4q z=VpGS(g+CK7K$OrV1V>T>C(gU3dU;FNsI0;Q<_{&jmGIMKd-?khbOHLtwWD zD5=qkr_FLVkWV|YK{v-AC;U|P{aU(rVmlC$Y)B|h>R*g~8L@Z#Sj5KXZsL^^$Jj~L zUa)Wp;Em}psXCH9$fglYb>~T=ES8jl#s^~bdbZ^Cgr(F_DE=c-x}6hhadU7ldSM9> z{EIU3VDPmNE6ymg*t<$S1zmXW_h?ozYSTbXz;JO;^O;gM`2=ots^ElTcvbmOcVYM; zYQsRB$$02f8HX*XM`|1Fy##nA5x4ue0aJ=+OXR)>CyY?j9uGAkWF#Xf3=I*0@h~m= zWOxm>xR0hdE(!ZQsf^_hIG%Q6Sk2^&oAd_QV4$L0HZYH3NwXv@qO&&9xg=S%&2w@z zR>Uy+FXC6{3N!Ss=0BP-r&NV4&IK&xjhc$xo|2~IH9z(rs_i)J6yQ&IrL!>VY0&Wg zDHG8BYWIZF_g3*b!(s6*dcuNjjk?O0u~Y_}7!+LFMa6PQ1 zGC4`0D-lm^oGRonrj0P|!mMNIv|i%mYbV7MOW4N=T zHzh+Up#sx@l`!aX9FygST94RlJ)=FQ_#OvCN{Y@=w@s$4~fdV`Yd_e-!q6 z#iY|>19N)DoY6c{!{f;KoKKqvA*O!;26K?UGcr zD)Z15ecYNHQj#ScU|D+b&4w!6>oFQA8N!HNm71K!aGR+o4T2|gU)3ZHWXC9IQRVML zA9Az`K3BkuKY>t{Efh+mvaaCYsu_XuD z;<2#cCKUBQMa6I%T(84%lSLoD5$Oi6WPU-4E%|Gg2;_#YbGga$;wY4px7V_=oPC9T ztlI`2)bv4q|_CcExBaTo!v z%s{uhg?j*2Or_#hchCY(KUhbZYZetwE_00wCPNdog$Q?!ke$ol71zit9;y( z>H2C!zPr9DsqT`E-fXlyZiKzb9>!?1D!XUIJ6gi_irAXZK}iGy7bxscgVuU$&O0gY zl2cuUeXQwvGHYn3qL}A{5^GupJ>=2HAE9JFhqg9SDg>?JrjYe(tNE&lGu!7nNFU0ZEYtN!a8Be@CR=Yo)z0UOyu!aq~|58 zhVs={-0JeXicXPLEca7n%=&r9^xN9E@AeD;VlD0LRFk7KF=(sC{l%p@Kp_#8U2;k? zeybXbDd!ZZiOr0|hygRqa~X?Nagpru2>b?<-CJt1M3b9$HP#|jlvPCZSmwb?{Whm& zka)LTDX|p!H9@wcvhzS{@5Y?f5@FdNY2nf5{yE0e(zG^wVu63pT}i35Qs)Px{XBUT z8y(Ww$Ec=I~4NVh_6KELVSN_irgLE27k$ zb#MfwjD7V^@vRwmr|WXg%|@$#dUPw6=8#2V&^H005cr#x11V!(&pT@TIJ5;enalhlW zqp`*5s$^UF4Sb`_+`J;oV``{rxwiFk)yEn< zxRMZL#|Yhu&tfGM5EXn72vakPigJ@F`p=4R-R(KN7hJT~-RiZTK4`n{R_#$oU-4AP zh4;vkOjg5JC46@9@3ZvV95N2V!oea3cS_tSw5*a24Z$FW@l9dOI>;iC%T)4t-ZF~zT><6G-kiChe>llF5_-gjN9#Y}BZdFW2 z8d;A4>NVlkRg=DKrV5?-ZMDrNqr(oD_lT{UuX9UG_CL?>{K5Hb+5e5a{zppxW3O!N z|8Ky?$nsz9_1`M&f3nx%f9#dG8>#!B5gVsp^6@eZ1EPL(wXh97g8;msjfM@-z0Up1 zU^kw|p9)qNL|B4Yt#gz56g8DtQhM~K`&`=}9}V4<$%2N1`!k-`#_$O+8{ZEBtqeH>-v&)4KgrzpYHNh2~dDkiBCMG}n z)Aa&^d>`%-KK*GsUDdYMWGB@zEhI)uuCdc(EWruZGW%NI+1`e8p>sj~rd_+y6HIuF zD$XbhZkO|S$?|2`;Is(6E`q0h_k`^leZ;{b%yWhE0n58Utg$QZUhf%5>#d%h#&Mn< z>ju?0ejt&18TGb|i;q-@TL;Yyz5Pv?2pq2YACinFF zYpDS)DDL?_}E7j$^>Xq=q*>Ayu&{nfHwff-52` zjf<3RY|_D=%k8FJVat=bGuX|-UVDG(Q#BS5)=J0wM+(r|#o4H~+=$16SA9;9DH(6P zi*&>|kq7ir{%=x+W~x(X)g^yRa>_IN!*ys-oHgmI@1Af5w5kHI!c+ZC(frB1c=B)Q zh~|%q)`ra%y{0zpd5xG100yE*Jsx?Hn3)c$Ywhe>LTYj2^#AYC_W=swU7Vjibz`%LfJ z$!|IH!w(^1lNzDh?;R@)-xJ9XoP7NUmcznS=bHM5}?KOL(6fB5t&VM&$^wOA#@^fizSF*;D# z>6)cjG^R@-X^PKy^e}0tjRdB!JdZV`W;vMKBYh`}B))E{iD9&R_+;5bg)ylG(a!3M zZL9Mk`G=|rwbV!|9wmfBr&rMne#b*fbO~)<#OC!p(Vn z`-vgy#$G_o@+R9BO$NvrO=q>f+RhiCDy+dXC}~&5w>q5rKsOS}V~D_{n(c#AO=^;h zdh!*2DKW4&&BOuZ?CUPFl?kaUUz_9T4zEovSzz&^%mY1Iw~`s-{XUPImYg>7PqJKg zcC@kZEY;l^WZzhLO(%MVav&7Okdhzmk#&K4Ke9YuAtH>C=g5)cP~c*~QOMh4Fp7Qh zL1@b50vky=ipamt+48pPF8tbIzSD9IB%Z!CV1-tfRE zXtSyNg_=UPDf!w-Q7Vn&4;5+a1Y!PS3ok`Od6NLRUYA#2DHRzzrX*n&+{4_5>Z*+4 zH*K8Uhi*^*^OKOzuF6N;g9>9&7htop+io3aBd0)&!dVhs>}8Qi6W^%Tt^mB*Tz)gb zR%iD|4y?>qK8WmviF#3;$x$K*Q5UW$`il!>`d7~G!Dg=d-#{q9Acz`;Ol1lXN(6oE zCP3-xIQNlFuk^Cunn4AWmLzJZK>8oGUaKbC8JEdtp>bbHE+to@1g=-4mZhzg<}`Ry zjwQ(*PhmbjKR}ecWrP?#_l{mE&MOPf{$S^=##Jk`8=G;-oH6Cln>!Q7GQ7pwjyPKo zc1;6>sWnN!J(#8Iu!#hg$zNYTIc<#coPlp%RD%%)fv3dF76x&`(-p{PFYI+TbcLiq zLz(q1KpbHeBY-ylt-yyF%kn%AZqW#ait+gFef$z?L+{hW7%qoG_|;)=F5m?bKj3*_ zgHehK49zP(wi5ChcpDa*fh*a!GkgvWJE$Iy^Ib2u5)klExs3 zK%L?*vxw{(VXjo-ny{~VD;u0Se77#%dQQnJ=gK_T0D5H^^xD zqba=htPs)=qfE{kEk+r)0Xq%uoOcLXm8fJmXuxO&5gE{RpQuil3)6@KdImxAJN~ym zNyZR$mj#M+3^CQ_2DmDGRr#JyHt5+P4@jb=zN=V~AYBZO&kb2g+P0S2#W4nLJFE(D z<87!hpSZRWn~p@~q_nUhziRlUj7L;D-9-_WEfbv23xu zci3Z`MnXm2^JD_SK>?!)cGoZ#4B%$50#OJt826EV+1k$q7O7vK7HnmjH@Awj!#Jnh zF_kT-QjS4?VLxj~tjds3%gm|V19c#ngL`7I6oE9#5M^KO3Mi5KDO@CPT4}f}_gPUj z{S3vS+SEt*UK`t)Gw7>eY&S3PT+RmmX=ykl`rurP)PVWLqkOyhw!Cle*o{>J4-aQ*j#?dZ7(+ISQ;l*0l2EJS#yXN4Ylg zCFY0(uqi0!BPk2X0i4j138#In`_M*lZtKG|WU-GAaSK)m3r}3vqOZefM+sZ2(XU7=TSl7;~ zI^hE@h#C(Let=taKXzoX_Dt(p=_%!o+4o*w@@&fRkn8VV*)QarYtI$Fl==;enyOw+ z8W)YA6P;aBtxnXz#{8^@WfhrxjBY;z1FxVpk)LZunSXq{hAT4g3Phcf$Fp@ewGV+p za$;|=_WEnND))7%TmVWb1NageNA(Q>f>;fu8yl)*&71qGtBI3NQ&mvTAqOYNOFi-l zKFN)f5Gp2yer>aKDhYb@srr;=g#|#HNqMRHiOk(Bmi?B-1*=xa<4edaPh+@oW0%=a z=${!dGcFv^f^9r#bwiAU2P$fc$9SpaMd0-)=gwvC8nn)W`n0}d8RHzN=xp(MrGH>e zS|~HQ-UQizimPblmG@4Iw442MGR&KC@ z>1Ymtg|a%RRXmSA->Z=`=s{KM#|AFZ@4Mob6yo`bDAzrP!Zp^LiK+_}#Cry8+B`j+ z*(0&_D71`|v$L2vN*s$5$FBTW3<%#N*sb@5bq$pw+l-JQunPZ98vyntmAN=;7 zG8@REtK+C!)9KPFQz0XUI4IXA*;2eVZw&xQD36S)l)>V$%4y^)$;}N^?WR-tCI7@d zTp2-_QU9=Qv6mTYz|Bf=ez%4lcIcIPbufR=&qoOebgz5)D#Tl!=Q8{LhKwZJf7api z8XPMOfwjRGJy_a>$?XaZj{=ntb=NntURY_{kMlfJ|;Jm$XTFZ_yoN8{5kZ~l zAd*s1S^0!(KL4nq;%2|)Ef_ygJi=a)r2xxR=5^fA!C=CD{W}QHy;#+?Yglv~1dA<= z^MxPQRm1*S-L6nn z8NcRCwac50+DMUn`aIuDr#pY#iT%kcS#(M_an(%fu&U&$)_VVW+2Q*q3SI17#Ql%2 zw)uKjHTqg*Zvr^IzrG$%R=gA+&MxqKePmlNG<;=c(ptOfn8)V=oj_WM{4J8rrFPH<8h0q*6UU zQ(wB0re{g0eviM{J*BupU33qCp9OT+yoov2R-UP8Z~qPbY`wN%DnD1XRer{TTD&^u zT*SI*j1IaL@A5-1nbi0dzpHM}`ly{>yaQjg>yBT`bI-W!v*TvD_p#ISeSddwaeyw1 zlrpVtRSOxAv|sSQ2z$pS&7yAGHf`H{(zb1*(zb2ewr$(0v~AlqDl0Qj?Gy3deIo9T z*#BUz4|7GdIa=?-ajyvDY!uHy*`Wt8O&N!NKLPlP9P0z^B~cK^(F+LUawyxj!8Ns1 zEd|?Lf9fa@661`FxQ(MQDW>r3QgfY^^*8NQhyOvgJ@9h-a8IuTj5x)5Dbb48rlU`e zpmkQ1>q~vzZ&j)KXxU@V$e?GOZO56Q_;Pq~;q&3q`mM>1=b!E#=h*d-F~Oxy%Oxf4 zWFaLtB#rPj?dB}JYTm3Qtq>q3pfgUKs;1V^xA;`aDHm5c(_01{gHx{RZ^>uNaV#MHfsE?+=#nUFU_Y}zWEt^3@<^^>1l1N&1i zUWtBVH)y`C3v3yds>aaPWAWGV3DCAr@*;o4z_({)J zzfOieT^s-*XNgc=L$wO5QtpW1V|Ntb<71O*Ecz< zVGw2S^i5lFIue1GmW{a7WgIie0;Z*z3qRJiJnwfHHIR4GOe&Cyt)cbhMVEcJa2^~o z^Zfobcygv!QiAQj2c|sqO}q&AgKnFJI)PLeYR zZICW3YbLZv^`%=zzhKVxdUI)X;Bq+*Ney@=@VlEZ$!bW-3qX0-1v#RH1bJ)Ch-aV%GaiuG!9g8j9eN_bki!>I&@92Fs{)B=M8 zk=y}*8o2e1XZ?CHVH<-&85ReW&=Nw&9@v# zuU5rCsQ50iep`ALh5<==<@Vqdfduh$ABonq%z^<&9FecOG7I2!x#%oLHAa|( zKtreLvO<{qVzf-d)y90%q725hmb_oz1doFz7^f&io4`fch1R9{ex$af$BTZA@CzPS z8F0^7WY0ufds*3jt)!$nJZL?Rtnfrlo$7p5YH{H4Nd$%hrnI{an@R?mlTy)gk&P{* zD35As=cJZpQBsH!K~V|Z1f*k6H+%ti%>?%Qj!Np5QSt+@pyV@34i7Cd!}l_swwqEM?Qw@|q!_K1 zgiifSxk7AJ#G5fF3@g#iqXy7!8hNo-cUl-x!Ub;eEC{)9U8_urbi$NYL|fN~mNZ`p zMwkZRc9S7Crx1$x35OAO1)?R=Q3-x)XHASyiDn}=4Wn2hrhePTUtmSG^0_#2{yD`aPs{CU|6P1qJ#s^D5vPsgH@0q4l^`C_b7G|&;?o8QuQgcf@og= zlFT4dfa1;T1vIJn-F-%XibJpRI$NT)Vsvo5NwRsGmQR5u`6FXjDh-ZBI}ip4FZ9-T zF@%==2a;5aQ?E4wBmNykWbfdC{vOo8k0N3e)lDOoallK&M? zELKQ4XU4sfyoHqp++JqoPFfxP3?MQdUow8VF^6b4r=#>U(9DywXd$+T8?9h;#uEtL zTRF3ss7t?9@-f$JlLyQ*n-Mzjl&)chyyyu?0=>@CF;RiTu)4`U`M%(J0~oyL7}=Vn z85STTaM=evxWV=kNdMX^3`Cs{@srKxZqQSF?0xG}!m`O##d6#)f8SrbNi#ixHdp12 zPqW4X%;?29^G|0$%~IU=DWmZi83+l8UM7WRf*t%MM7FXeAaA7gZdNW@aao{slsGkN zQ6qT7FBTymupzi@_`4A+A~g$^RC6i$C&zxR-oH`xXySlklXn)SJxe*5Y=xq9u^GXW zb?0?W&@wj9IuUA3&UzLL{h~@MjpuVa;T*1ix{Y&5tupi|j?7~BeFcUM-r@cpCx#D3 z#BCfnO<7UkrTKYQlOpxJ!7`muqe{WaiCT)GGC)rz*55p&!us>>MRs2_SLM;JxC(7H z$o$bGC(so%;Zb|mtSSc#5A>0wMQY&_r9GM%Uf+>eJ zb@y9222r1H%jLFRM;O^_`|OsEexrNi zv$Jl651$zGnG=TWXT(}Fa|TGA7fZJ_KEd3}Ju8QlPt6fN{qsjHIWbw5zm4F>tmvJh z&XXB*vsQ}*(BTT)JNtbUyyjWW_4p?YrPly5nBn)g;1a4>K-Oz(qIAFpH@!N_r)7mw zp6=fK`CqOFMY4zMv%P>L<5Nr9Ux+0E#uMBm>L~sj?c7AxGKm$zO!E6->lFWFo7P9n zBu#AO&tVlNEeL1l;odS*rhA9lNDz~4<5K8fcmT8ykZ zHQM?&JvI>H*%;UvoA9jFJ0@>s+Cx8|g6^=FFWH8)Yh`@nxd6}Z1~4EyidVV?y>KwC z$1_Rv;XqGbbqcXSJ?ci70GilbK0JeJX5~%OpC3)k2lP%!O0q#E=}IR%L{4oVQnPxcsTDWHXc2#VS1l6ZTT@dkzdD z258#eGU>{uS-filc>7-(rrgx#%^jgA37@i9nrzJwZKJ zf?UQ+wxgj)q9Y08x~{PmT7}lN-uHT(YBghYDn9%~<74udtO0<0iG$AlD)&D< zH*%|@XK}VdMvv0v4CG%Qcsib@&Mus}6Do)Gi#Odi*(!@ZC}|e*2Im6K*y0=Ycu%AJ zb%bOV6;G;fDusUxzb%uHo?wvp<}g=wvW}E>P@H(b;;zjc1F;`dUnJt`uywmW<>gAK`OgP7R^*>Iz|$3+aFb8TMTuG2=Dqw9v=&fp&YiOi0x&nL5s+_f zy`ePxM8pA|ijvy53s3=i1Dp?p1j1WMIk)X8t;2J?js=>L2 z_Pg1?Gx|F+AJY1p^u%n@D%J^*qVn`~==+3uWI|rNiO3OF_N~IJONn1FsFQ#EM^Ato z8((s;MEMN|MqW_S7G>Dv7lN1j9F(-ih&fG61E?-($t5b!2IL}oe&)5||&EW*3(u}eh zLK%mt>$E>WTBYn>oYwiYDsg|Foand^)d|)2Zq`g&0Z2Q2Z5Lek=j2(SvwQpVf5OWD zWC~f>IQ|OSYJMdT_02%({wtzr9j80Qj zqHv(@^smo@W(``5%3JI?A|8zmJJ;k9FP|5K#u3fDZ=a7ZfczotvX_%`Ub|Rc8r|35 zqxSUQ|IWYX68`fx_FLaBpCS4&p3aD`d+AI-!T(EulD;uSe=3GWEJ_hbg-6tiGjm^(XSy-@3f?4+G3eXfJncKQW}bPjo-;f48QN zo=z}@%eSvRheB|OT%dnVR(HhbsVaY#uZxY2pj*vL*9Sg(zq29dq@goBPj%GTH=uZM zGTB!i+1xu2Kr)ryyQG#Ov_;YJ>W+eG8aQ1g`ziWAg^fq#aJb4TQRdPAN;jTbS-9NY_`&(oQ?LA@gHHX|WmwS2Fx2GaF7_f0mePrwouM zTmp?qloBPE0?P=u>j+#mkBw_CA$}T``r}bo1sJz_T%k;ogvg^oXf*Y`Am6hLhSgnb zmFD0r4n5=IO}_05evwXZjmXc6qqOb7Q9n{`!#1pAtUd>mdBFyTNP@`&sRo%!ai}Cp zPRXGb&8&HkhjAll7gURYbT5MQQ^~fMypD)!A&E|oud1=G4_^6utW{4U3ja6Fa`PPv z0|!NhQT?}v3EEC9wq;}L@J1%pl>4Kakccl}Ua$d4s90-AY2V@22Fjsgd^mpk>#fAV z@cKrX-|Zm$--l2T8SJe;Tfoskit@X&FV>#9GW(Z{OH~qLQbk!be6V3)#}ZveSu(Ig zA$IXOg->ldjf0Fz+v`Y!fxTrR#f(pRK$9YbEm}3L7jO=M#!xMY=b+0(mj7Vvq>pW! zE1Jx+fxi>{#z`^_!8#Avrar<|;9SuxR_UIm8Y6e1+l*&ijYVgaHr~EEilJCFRTUVJ z*GChgQw~&GWp{aYgocTM@lbO$3$UNOL8_zbiC|cSX%#iu&j_Yvp>O$>V2%RZvOLu9 zNwLLq78KNXNYSr5GQb!?__AtDrBN6>t8RCZoRX+*)@y<$ujKGo4t{K57V?&F4b(RO z2m7i4fru>t=87KGVk<{<#h}} zOe-i!z62t~EJW$kxndgAUuFU^zzKqZ&ec zlV~$sB{xduv0KUu`xCjy5uIe+vhBw_RG78x9L{R$2nv_FKei_CDA^&GWo?hr{{~D+RdWvfNhAki+lpN)CG~AqM{yZqVTuWo>A(^EzSUI4 zwc{ecMrXZby6~UGv%C?R`x3ad;#2v9q?_Rjc^7gGq>E(F-k5!t7*ec|1&R7Bni7s^KNZ z*KktpI@y_Go087g?xjTaZ&1Zhfr@>0V>}i|9-D*a9xmOcUV=L$b5vVtN_MTwha3IQ zGD3p-@t{|AR^Eu$X^MIvt4oT}&Qv*=4CHa$0|T|oaT3j1mg_lA?v+xy_Ruzvy9bX` z(fN-ypr7)^5GP;m=fV#uJCft~b8uJ+8*)8Y9h=7>Vp7?uP_!@*X!t3y#Mp5#4DqvQVJc{*RMFL18b`kEnV|U$P6BM3{Qq3kqYZ= zi_G_rFWn`w8iejrqUt6MjQ|eE)hR_{bsT=nS?XcOU<|r&(BUa+G{)9}jasK>%5y+D)TvOv$Sa!br$mx6 zt@+=ht-5lah03{mfwMm#Ur{=>-LR458KMBW!`A#danIRyg5Ardd~!pR@jlBLPX)L! z;dY#}Tcag<)dQ81AQ~)w{fX%L1bP5Jv>yfFB-?(@ohH%!O}@*O*VQO z113NeQi3U2&cDEy6E7NB+jU)Ktd0s=O3jYFaIODt_jfpc&1{y|J=A@%JrqB@lgIgk z{lyy<(MZ}+*{r3)Oi^5WIhd*1PIO-Q1ID+M$C_k;w*3y(7;svj9_v7|2a32A7ww>TMoWfvXCMB3?%u)zGZ4?1el11UP$(-K+_e{dLf2Y~t%4^xeCTqf z!rEQS>@#rDw1`{bLmppFiMQR;ZSu~oaOdf*8Bw1J)1FdZN_L|YV{0*9=cYJLTRlGq zu*WZx00(>9sG9Ybc?fIu`>L&?r}dO!LBKX1M3DaBRQ(cPaS7O}oAf=PIyQ3CU2P=p zM$LUiX?E}rj#^iCy||-mdf#hzQWu)sl|(mTn$qu@3bHvnJkHAN^<|)6DNDD^8Ex!L zshx?w>eLKj)U*u}8{%S|6ZucO@S6HvLQ2wx56+$6yofa2qK&X>`KA79c}sZ&&gg2!A) zAyNG`*#j|0W7~JZ-*v&a!}SZXH?xU@^A{3Z2UZyqgc-aV$y3(g4$+E%bmZ=;&VfH| zXkJ+Wt^SbA2M$o9;%5Kt9pXx%C<=l7$-J$At*t@#V zphtpKz|vd@Xc$b5?|hH>rc$d7%HJ|x3dswQS!YarDT{0Yga(e!EuPJ|?x%vH(N6z? z|Ho)&9YB$M#t(rLEW7l+lp2(DfmTJFbG;DpD|7gK4msx6Pc7x$>Dr7-Qar7zhZLcT zKw_}lc7mkVE{coM4vnzhgGZdV!1-ZEd3i_04H7grp!R9tY}b_u*3^)zRx)eRK^2hS zeY%o0B}6LJ23p8q5D594uZ5s@S}G{jI)9)}B}R-A#f*DnR>$U(N&a@CD&gk9{#}p< zlWS##E~=XCW-fjL0gI6Vs5bOMPiisXGpLO{#~E^)sG!{Xw19T9%MODs3DQFdtX$|U zVHE^`kjG*4^yga!y4Tc`;j2(j_*3_pa@~#ZOPqsrhE(#pMk)outk6$h#~`VP)i}nb z^#DH&AM_^}j}G)FoScEuG8Z8jIE1Bwr-V6+i&(_WhU6j^G-3+oc(yk$v1{N_#KiB^ zthiy%bD7`dG_dtx1|)wNw zQVL={w_OxEdtN`b0`dk)#0GZGC-*dn>HLE%Dc3N4e*jc6X~2y~Ly@3GS2CPC7G-no z15^orhgekkhP3U3P*@4g^Dx%QO<@zcJ|5v6Q3lJfNf=vd_JrXRqG+spZ-Do^4^&1y zO`9iixdzu7%b0d%eTMc>yHUm7Jgc8zSlKLuFsyX)s|BrCeq^N*twi+%o$rGqRpDyY z<`80!0=c)HQ;$YK(OnvRx3>O04o1$AQ?=cFlj@z?iAza`yzVe_-m`dEzLf0c%>+&0 zw_czd4ca}sDxgz&1WnQxrB)N+ni`Spr=J&}rPF@8W4n)4FM^+alc5#zPlg;R=Gq&y zOx-~zySK*rMz}mVr>PKvLc-Ns}ebdtZ|-Kr?ST!|Ag^@X&zd3wDp&O?Vj&5BY#T@`)6 z>4zYFpOb@Q$4HLuK)@f8r=~7{=OyN5Z@fJX#Lx-*5{E#SD@jLeci+YdE9|`0%9+)R z?BDVZ1i1Irf-ok7a7J9rXSTow75V?(%#TqvZ1DoboWo-17s%>QnmXZ|k-`hNrc6&;y)Ks$WjU44dgKxT@bDz(9U|Fg>* zF$XB@al<$r;y=`XAoCX}qEt!|t*rKLeBBH?Q=*Hseibl`@B8ayj^n9ld1}qy&s(2g zzMjTs<@v;3|L5`K&&w2p!*KQvW^4GJU90wc*{bQ&#q`ea+QZDz(BPWzrG1Llc?E8i zrTb3={kjH+@bJn0J97;a8iWj_$t^*d5-8l(pdHNj$4taAb67v%O#~{iru*a%yoD$j z?YA2y*TBK)I&=$Zo^EHk1w$Hqi0MN1X+^V>z3qg=z$7-x66T|(&ynFf3;8ScUQ?86 z-z{(y4}gW6=E0QdxUmBt4PF5o6-^bM*vp5Cb78!B8R!}1AlXuA_}}OEk61|!dEw5M zb7rmQNSg9IBprplH*h`=D3h8Ql@)1jS3ut6;qrmR&jZqVr>FYo#no?$QS3+is5+@1 zuPN~g9kll&!>mlZTw9id{Navh0a6+-ebLk3f%f32>(mCty$j3de7GNp3YGxt&9ZoE z`)EX^CxX!acq$wACShqwla5*}C)3}AC@4Foprvcf%thW94Bu93!WXn$fo{Y;npV(- z*1GKVN(D=CyWL%}c!M4eP=Q1IlJU)fTqWkD9t#1n4Q}Wgf-~=s5ypzo!?6d$;pD+c zj)#6caMS_~PO{``Gs%&`UiUi8l_^H-HIo%F_k3n=!$odvm9eS#Rf9}P0^|6`vLX@H zEU-*6`AY=7${Bu5)WFsC#|M6O;8$@4iF?$gFxyxWK?xe+rV5)7&mBuM)b)DTTjWXn zI^M1k{&ZK5UN}XJu@O|I(_OUTzV{8Q3}#~@WN!#1FiLM*9)9G2556L}@T{3#XRUo8EO`=7=#_FW49e3|v z54aNG1iZ+#xJ>txs{Sc-(rzfVI2g1S^YwVoQA`yBRku8p7NrDAqq;wxgP1CdMP-_y zOIr{l$^~|knP%%87rw!NR%LLFRMRkSdTo4dzl8?0B&7~;9w^1fr5{EPZRsqdA)!88 zq1i6!HB#2ec|DnE#%^L9d`7u9s&dRErQ~YM0T+@Y!xAP!nMM7*A=Sz*X2?&n$j4<1 zmu{b|%a|>@rFN&qaVwh!pS>MIgBw{x*E%3i11+v}DwFN>Q$83aadgjWZ=vbEBIn0re@c;M6wlf@HksktnMH`&P{2@>(rS6Dd!>V<&^H zE43p(2FK1EU5jgXvZ4hpc+%6AHged!vi|UD+~7j|s)9^Z8M4^aOPFb;vXpYAQIS^Go}1`6s(~($P=X7U8QH|et)~a-wXPG- zB~<9{qg~XHN-kT0UMO$khc~$MlA`UM5zi0~vm8>SA#%nzp0IP~$m{S6F?*BgqphQ+s!YNke;wa5m_<`s~uwM}P87S(kl3rLPh0kflD1 z)#|Fq06GS~Cav6eR9C|qPV|hhrW4%U>!LhL#d_drnhkc|cO8jUZRKm4DT;>^ZkS zc0-mfj0G|OCJfLUTR^EfK2pzx@bdgCEqGzrt<@|n34`ND(ud3~6&~rcgJ@sf$I#LJ zC7^HdMoR#5ZKn-)C9+ULgyGL9Y$^&POt(oDK++4tlp6=nnJ2;2YeTA*hK&%!GcFDC zP}K>Pg!ovf(8LQW4u{C>VLXwm#vL5{j_Xo#@XmyDX!Ye8f{CC%_w?kGBat)3D00Wf-}X_*Of zpx&@i7=9xr%Qm&~6}Q+5vKm#3JCn{9_4)&lqZm!5u-j|ReWr-nQ-^5INOkhCaS(v{ z-qO6x*{OxyxsiyFJk+TGN$pp#b-!fMfY51zozrT#F`v~kre22i**%qfH_xuWm`zCo5 z!9f(=J}W&-AnJN0%52|~!nOSBW{21PX27&wR#3XgrW>?ddDLK(I$b?=+ZjEnNum6w zHmbCCqn$NsRCXrMMeZ$jv{6ECY7Cbk@W!ahf^Ru(+M`|3^clIj!!|k}1U8b&5ULKW z#5i|Dj|m*JY&wT@t!UiQT@~Znz;pNjrHq^sA3ns)fw<$O^2z8GRv>nXu_{j4F#om0^q0P&6tD1McM_FzP;E z_`Ak|?ISSZFS07m+hi;y_RcE^2=#E+A`t~UF})aQb5#pwZn037rjuq^XgaYoDO;mz zA`}r@(ukC*ks4WkO>oWW2HE)+`Si;Ag8X`Z1#ao2p`%rDoA@LCJdtau${O@=tu1JD zs30cEr4c>_Ejz`H_MUM?}T+nvq>hU56@8}@SGoNb4l4Sk_XUM7e?c2H~FWFFUGq^*5ULYXV0i-$uAV|FixWqBjuT;5R*@< zsRofs67JR{D(H6L+%6gwh-|`ZzDOk?T5XHaadOkm&&Fxre#;@y{eg}JYni$HxEFix zV~)G}t#)rd`3Sj)+`MZ)`)vLjwkwhhAqxOO@qAKYN8IDV01OHPooV1TrqZ1{2g7P+JG+)qkztXY<3o z%6sfJyw`?)=WF@&4mI}24$6MdD-V^LDbQuhj_`&eH!twU87?bUo1s!E!$0YSPsFdp z+O4KMd7_&tAi8%M0yP^>?(c*wv?o6lJ2O`MLIIa8Fhg!BJjfGAm4&Bb-TclRtI1z` zYa`rsA>XneY^iPQp*lM6_M0(}IZSEBuPq0+nIA4__t8up2s>IMq|p^>DJXC)TEOe= z{-8v~2RUmWb-p4nJw%xnZ5}wU4(D)6O4~0z9mj}u3{PFNbEpMuE*2O~qFw6Q$r7Aw z#wc>5*;%aybon81Wtwl>l3NQ<*9jW;j5gA4&DtxDg4-`30o5U>c*uw#u*Jw)XZao5 z*`(puwMFaO0ci=*VC?Fz?`_mG84K&t;7qTUhzU)5sB-5h4d{bDBk;wK>Ep}Wi!`}LI0ds{ow}`MBI*LVK86EgH?8inC6abO2gVu}97K9J zEm$Br)6jL)V4iNVX<=p@KQE)XE3Lo=)~gnfW#Dvg>=;Bf&eJ{>U)lSw|6QWH@Nmi# zy-fz}aKto(I7{W91l88oXpIqTeap<=IYt^T+!iB~33EL(r|7`zb*>>3Ew-ns-tO+n zI}HoVI`X~}V&c17IdHdTOV4}xE)KPgM_du<)Fc*%{H`agas)z|I+|Vp9rxZrHDu$N z)2AsH28X8$P2&M-tY-v5xhJE-s!;A5NNIV=d3O~E|Hm5a?m3r5t+5|seFo^2KdQ)T;=4c-;a;}=&4ml{}Z47Cwj}m&idbhT;~7u z;Ql{+`d`ZP|Hh{y+EaC;o$xz*|2l62@cF7$`a=UBUA+@`fZ$D#P148c`=`zP1d=Et z|Iz8>4k{RENBxwS;_<-A=zrQaY39$}- zK5zC2?|%Mlm22Fpe^BYYo&2hKtNu>8wc`)%yi#Zk zzZ)EMJ{Wduw@jFSt0sJ*L@a?vJ*0*F;k{K)P51cY=oF23DB2prX8^y=g@CHBL=ak3 zb8rDm@rmp=iecV=^u8}8PJ00SO@6=uUOkZc+CZI)8rmj>uiqia`>e-`^sSrSsT>Zu zcMH>sDlw#F@IkSXJ8Kp1tQhTwfIKP%>J?!4pt%}c#`69B#Xz{%=l^$b!)If9rj0%R zs?&vfUCFeX!W6l=KMxG~80hEMHrn{RfZSqPZ+(8MQ85$Rq-k^GE&UzwR7jIwj+lJk z5;%&u1BD(a5JVF$FOhd)u(8iWU;7sVy0f-o<(K%pvcb#JLa%4|w7HXBRa3qZI2(`boTVI#SBbFcN zGOk8gQGxPsBPvA{Dr|QlWn3p^KOpe+m><>^+PhyjK8vznsNZl2Ir%_`l=5H&WGa@= zREI9uwa?dW#{6&)=RvaoA3RaS2E^yui-nHW^q_Y%voujD5s^2rgGMnRgGlxAq;0WR zR%nxy{u@e3sGKDhL(?UIhJtZFLU~Od{Op}ybILkK6me-$azv4qF9~R#2^$93%E}^- zY^;R{yV%PBjS8Mw0Ab%^Q^~y$cVq+#F8lmffSEw`y~=3W<*qh{O!H|M?i+KsEio570jO^F?f8M{8rC$+wD}7bgn>=u)@JuVRy{r`EEY3l|b`BY5I~q(ZNCK zNzVuf1(XRglXvHam?ZXLkJ|#?7*6G0={(gXq*x1*f5tJ*P)nF;p*_4H2{9zA0Apwy<`6ctyyBxya^I-e4+Db_OVLldTza^Vmo%Ntsq z4UOwaE1WLcl{q9rTxw=_8HBXw1irMm;Le7HH>m5uI z!*m8W7k3o-=n3!+*=lHfugjmvgd>?KXndSPQ2Zh{c(Ut`B5A^ZlAjhRrW3~GIYZ<9 zK$sZ69ii6@9OG(jF6Sr$fD2Ts&=aH0t;0^Kq~C2WZSOXNw@F1wnE z)o2$Da)JyFs_u2paa1HR9B-59D&=Y|@#iT5wR@wijAg5(fTa&3TYg>W!?}sO+ne+L zGQVg&DztP8yp7ZrX(CPqjS{OF3{i>U3+R^@#H*r+j(?eO&Y<7QxAV3xnB_k38o3eZ zcMHa(%On~Jpq3cA$13%&o1B_YVSVj5j%cM}&YppY`-MffHm-M?@?sqD-r02*oCe(J zvCBxnF1pcElf9K~_sc3j{4n<|yyh&}*;uS!*om-yOmb!lru42UK2SA#{s_#uN;Jcx z&N$!c#_Prw~z0h&3{0WHbI!tc08LIJzy3PmZsPgXz^qP7&se5@<`V8#N&n zjssRHP!ddis(^x{ZP)Atk(k5&EYn?K+z4Uz{G@a;hf`P`zM$1{l?SfN@FfC38@^{L zo|6(JT6Ea2j$W3w_oSjfxMsfHuiGS02X?ra=iA>nhlFLR>rX0(#=Jv0`LAn zY`hD(D7*Z38WVBgrBy;%$Qh`cJ016AP!)*}_Tk-_5Jv$Smf(9BmX&>YVjgKHbzL?B zK#8x*4hRZ*C42wA=|M+7G$@PlcVLy%E=Z$IbW(SbAZG#scyIL}KaS-&5Y@tTb5uv{ z)9(Wuug1avk=8!ny$TL&6vaP&Tr!(MjTHJUsxzWL8?Vey%L6FvNh-PCxh=5i6`F9ah;yM0ZHFOh>5T4+yV-;Q^ujMC?QnP31BZ0jJiZ&Nk)fF*I^RdL+u>eQajiQ=66i; z>agC`&@27u+%hKZ!AP(W8Th+Uo!jwcyuBrqOWQNh0}51s^2nCZ z%(EpWgG+KXn&PR0N$Wou?VnW{gxG7<7f}KI65|#N&Uf>LVelTfMPQd8xkeIqvGvHd z(7i+AUd_t5_GZ3{-(*pfI5Gl2?=yrgm$2!}@B8PYQ2AX>5&}JKjBeOOl6GUZIj9E` z%y&RMpljHv=Bc0zSjZC3B^db@$)$V0X%pE`(PCU)uEcZ+!L?6a<-Eji@2N)yr@rW@ zc(|h=hfZRiQbz}{5grH2#6K@g5?qWk81u9!R(RMSW(%(ykKa?LvJWmud!E&V zQ~D&O^f@4ue-Xb{7W25@xYTV-GGC^uM<_<&|L7Fzq(4tVFsO{>e+_l0^A^3*(-@a! zWI>W6sG254M~CFgy(_}}7Rb8esi^U{=(`MOt_4G;;u}VMvRQ>Yi%Q2K&zbU>3P)y` z&nDcNL|1nEQ8~-3$+4U-rgWIHLSA7iBiA(TW2Gb?5GlvULQNeB=9;7$Nrua^v)1(k zJ;Q>IA`&`Va!rFoi>gsKq4**pEvCwh9S#J=%GS5foBV_z*yFLAch~CxznBh1!dWZr zNT4QA5xD~@X*kUqgUaYQIjM*+NPKieh~npN0|XNQWiLI2qT9L_u%J{l4wbOMZuDb? zOGvbcqGrC##D=>q-ix@B2sl>J8S>DFT3e=`a7ZyVn+|@W<^Di2s67&p8h?gh+CW8wi<%7xJxw52gM#k|MEsM6%)tjbmY6NvDKZ9!eoFvMTEV#Nj zT8fMK}FGv5rL8hTmZXUt3-A>H@T;vb8m5 z2Tk$AI0y9D?HBVWL=;tZJZozrAX)3~AylO!gYPj_Ss9hFFAPkCEFuky7A&cCq$^y9 z33WE=6mc0tg&879p`8xx^gABX{J9?CI$d-|H_58Xnx}w!VRs&&-eYOIBu+!$+hx^L zvd{6j>Wte^4@Z~DHiwIV$SvzS-jT$S1+`2OiAR8OP&}qvTNb)Bp~axH>h$JL>mfvl zV%=EDS1-4$6~_VPpL_#_$+$%UOYk;FV&e90hSIQ?l@TNOnxic`Kv#Rby4a zLN%>pz+!9!Z>M@*SMMNHYbxO{`RBv7a>~#y%#sO%p8H3~({Pkbd;*42JWVDy}U8@eVFr8sy!w#FTK{%FN~ zICM=~BjhmD*t=K;PwmdCy7*1~e^kLPE&@2&$bq(yNFeRnU-?RZy4PAM=9cz&Ka{+{ z%`TftifZ-gf5262PrUvo^!ZPSlZBc2{~68wr(gHK(TC-~wA}v6??)9hBOTKsqq|t*y>t_P<7l7h7)RBN)`fuN_ld-e4_pphTkkaSf8iud2R?R*C3T=hpKOH^LsE{Y|ypjCRy}T)Y$i1gxAw>r?a_#qgH!bg^ zr-U%gY2p4zlB=d(fIGF(y)&PUXHE8;h5S$;8QFPH%`uiYwwkX9+9%^lkq;tjxg1Hb zc&_H-_>RWG;#GeV@4rLd2bHs|Vr~;=?!}Me<9XJ^ygu;(1^Hk6UeWqe)5GhGd6}-WgyYXd zv`A-JQ(2I9kpxAe0Kka8`ft(gD{24HlQl2TLNVT9x|ju1I*lz4=0U?YQMU|+*Or<| zp1rTlYj#V|AC>JX`3ow>Wzm0Y4y>IeH2^mx4BUv4-U=ht%bIM5a@x9y#(wJiZfU)x zwU3>pWa4(1x#qm*A%<*@6n0>jcSK0s!AsdUy$%|v>Q8RM6fkY995tVwRMw`%Q9-Q@ zA*fApMXjb?BpvBx#!v+li-t z5*$gYx&>yXv1YI3Mto3_ zcU^+#EQu7#9fihF%vzF~dOo>T=-a+JHnlz9E%eG!W11)ZwNT7D;e>GFi>s2?86+6o&)L-$!$KbU2BUU^RITrv+9{7hYGg<1dun`6P2m}6Jk+9Cv@-f;3Vr+HA}(q;N_ z5Mj2Cfa{?oQ@lUOmJsHl4KeOSNKIlpIy3?K+iM@BkSPE0?Xs?OH9+RhcHtV03L z3j;IU!W7)IwwNy46cy2AaPa~rU%u}#>D!|RsIX25Z zw#7_QPDyn8rvH99FuEZ&dExr`-9^l?^I?drVW^3^@;j<$^OThbA%vcv*2h)AIluBLhXJFSlV*Xevel}TF>*0}mS(brD5_m>v` z?9e)_P{I*9sa*myO|8eKqiU5|+61cGAQMKqM2yIZ5$jMLTUmuAqW20ij;apB?Z!gu z3L8OVdRXc+hnt`r5gCkL#sS`qlPZ>ZPiG*~c`nFeTb6uf@MWVBD=4HLhzL12Batu| zS)?_kib1l~UyaraXTruyDTCXIQs|S0P-!J;$<$v}%QHA(C!e0?m6yUNT|u}WjKRNl zB(1Q*Ca!8T@MVOeka@F&e9c_R{O3G6ywpnByReT{{Qb|4DOm@aH z_?k1#p&z|%#ne)fgKmq2gk137s<2?QpO?KPDeiYp%&qZCw?3LLIN4yDG=XmH#lFw$ z463;r@45Mj>F&m}zH?rQ0&+O5zXIY#K222v%zfn&ExVQr79`xL|9VbFISkUOu_fDF;}LcP_b`8xk(jM#kdslqmr_^-5aZQ;Ck3x$(w znPy%<`}_U*6x8#^6T#C1chLHDt12n{?k?vQTq)aAm2Nnq&NnQ%cZ~i`tdt-G%RObf zdz7cQ;b7Z%Iz1f!2+EFge}6MbWN^0Vx)|GX)nJ5?X(*T8aZJuojca?k2JTF_>=rYD zw;t#41X`{0w-xxD69r>AX&amR=6;dD1B!nuX`+ zI#zRK_p3*8bhRZnud>$g4%y|R2;ts1dva=AHoO1=KQ|YW0a-)*xyCX&Cm~Bai8>>p zmgNcYjwIL zEe8>7XW;95NIHG9{b_XS@M5zfczUA=Ajr%U)6fEI*6}sMzo+uC?bcw)Sg%ypXncH! z;sJ`CGM+RH8J%s4O@t=Bq=Wm;h^SokyKK~T93i+GhVsZsJ6*B;Wj>J1lRM{rcz0n% z8ArMj;a7f^qqLMgTcGNmB?}G9A%~8-Q=U`x(_<{P(*GgtEr8-|_H|zzf(L>Gm*6gg z26xxs?(Po33GVLh?(XjH?(R;IGx^q8Yp-?px9>T(E>&IgO3OP_-81y>dHUaz@juhR z%BjmGoQ90Nds%H^1T7y@P{ZBuQg)*2Q}h%|JUNfZ8TuD?-CZ>6o5wD&e(Gvb!rTMo zt8z4_pQJl#M(0$?R5txywM4=uw@BZr8hcq9!{4e3*dQkKO3@ldISY0)U)&XtCyBd} z1)Oa+>blb+eL!2i%RcGx`cqKg!y3)4A7gS_FeBdHrQO2tX?ZTpgfNKIMW`4S?8P=N zSc-!;qZdeiJ5Uv13SiGrMmO>9a+28oeY>u*}*;HJ#Ng^fe0g;^kd^n$M%10)$9Ay`l79uW`=V%3X`B^ASoemB6d< zgYG`0PyTc@VbP>#wWGwL9e>+$ckHPLgSZ&SUZFya zL2f%@6a4H8;y0Zshlnn2q1+=$G*qw-C;bdPWAX1R-x0MteUU$piK?%jaFY82!X!+* zQ8MIoKa!$)+)HnSzZhL2uO*3hIyAzy5{FwUC{-Gbx#%YI51l^JR}(Xob;{DZ#FarP z2CV}l`1Q+we1uEwrJNYnC0qUm^c3|3%q2paEemr(RRgeL z6tFg1Ac|DuP%Pca>e@$fsu@~#Y`(<)P@YG+{D#w|8;gtMc?bq#aor9EB0-FV9VE-} zh_4+W>N~nUt9}Zf0)?-e>tiIgoz!xvUaI6sz0$uR<)(@<0e-&_N{3OkhF;DSKb-C< zD1+7DUW>|Z(mI!u76-W;Qiv=B6YSV7k_I+!_55+c7*sI;>Oi5%%nxd5m^Y_VT^Irq zu6jys;$V7b)knOs5;mKSBZ_PM+ByE}@Ipu9D{=BSbEvShtS`lI64~2 z$j;^hwNy59(OXp69^Rkw1Y0Q#6n2lnV3jTXJk!YE>dw||UIw`ip7&1CbWJ?G&E5a) zc5><+l0W2eKzNXBWxAi5zkieLa=Yh>tdpNWb*8{XxZ7@|?bWx3C|)gh{un_xc3ECS zuYOr#)Fn{CCcafDvau)d-RqtFTaV>eN1WqmG?49ZC?%T^5U@khK2){FBw4|AX=&_F zyXa*u2A#z{n1_t`OwzR-zTMj8n`&!Ku^gT($vIx;)X42=$&@q2efIUC$zxy2B5M^? zF%0`IiOBd#7mgzadW{xLg8X;yRkCzlp$F}h-~}OIUc?2g0h#pZD)ml3i*H4BlX}W> z)~1;BDs(0oJ@>I?2DzkYB{HhVaLon>aa?`99g|0wvJN187^O5x+;iH_w69o7(7qxw za;`I!BZra^4Ft(e^$dJs`Yqn(YFbiby9rL1I6BocN8R`C-DIV%e^9PcEgP5z2=kU; zaztlEJRT`9 zVya@*ns_jC;l${qAo&JY$uBOs%>XdHUaf&J%GZKj;ilYSo|K!w|!K44dl z6>LcoYT-G0bMy4pkoLT}#{CiP)#EYXBD~VkSgWJM`SSi}7n4bp8lpWUGKhAnw1~1E8KVIRJ;BtV9*NQP(H)2Y}=`j&theFxJRcZWUCp>u{x_|}Xl)n^29|uVPSJY_=NvX2vc7!u1(2&Jbs{3{OPW54nMrK63JaJ^~e^ zjz_I?U9)6oU7f%R(=c{vzX0kU=XaJbkHZ%XQ-z%oP5=>*TIf>WT|PW{geh0}iM%TL zK7KBM!{mh|N#kC z^icp+cKmw&W)?6gQ7qk75a2nSc)m4S=iizXDmd+iL+pahOEd#PvezbOur9AC+1GU0 zNbT<0o}0gxXG3@MX!(@BF!()l6B(8U7NS=};M@~Uz4n_Gl3Az()remGCSeCTwMmoW zwv`M#Q!^%!fx?}U8Bd9DA9eV*U*EbG*1wlVZ++v=3ciiW4ap;9A|2a>KYWtYJ>hQm zJ7nG*TXT8o+n_;sP06mc{uy-X>i&whniC;}FximUGHxgwfc)rC`Q&Uj(Q6M;c(d;<(ev(nJ(9+lH+ylbn;B%-dU)fyw3w|>~5EIxD%9j)e%Pay_|^+V_@VWoPHi_CN%GxgBuiYr{`=@aJ9&kq+% z78a3wl1wNvX1~FsJZuJDUtW)Tw1pvXKJng`-`y%pH*`mzS1WPJw%K zvj#gu{dk|#mHh~$JMsF7_2k$~YIenk!oyo@B}Y$sLZ8P?=v=@h`*_ave8U86=~TYnkjw zkRcO;I+V04t7;CR?q$K1a)Yf(kyir<^{4KIr*UJCHFr4!Z<9i(V_x2p98;6>Rdk7a z<@GKsH!;2>pHne{yNx%kFTUwE=}}b%NR~A0o1{~Sez0}^I<;u0$BxqW*LW#hJ`kQ# z>y`J_XIM+&l^%L~=G3*1@jdKI_!W7zaH!@VR$*__WM~F*MJqmuHOr=`q<;Y&ijk z-|@*as8UWk`PM#^&_S-wv}m>RlNEpvwCxMBP}D#({@d&%0MD$jA#Xj__r@su`%mO zqIDR1Hknf*ckDW*w7!!N+HlM0cIMOCmHDY%5;=k?38+4^gTYdW_N3_Cg9fqxk~eB;2_lo6d{Pd;oql;K+8tE~ z;}nWtHlqx&gi&U3W>)5A!}93b3$8*)5mg`C|3a1c#3Apr+ly1%#xRBXIk&pv>cung z;uBgs-e>Ko8<_i=IFXVL7t(3eOga6ks1N*CbFWt4@vWAd+uI8antx;=y4Pd>BrIj~|EM-ytPgzJ(bzYl9Gk4r zyr<#{Zj1Y(egTcUBKCuC;v3Ev6G673;xyzrE3S0pMeBhhzKyEyJU#7E)Hh}{koJ=l z?iiM|R+0*XGMBf>uahZo?MeHpC!GgrDjDS!hVOz^2`AQFDRZ0sjmlfKNfV|0UX*?= z5>nFXnE}+wfzzu59ewuq&$y%Zx0WLCHs#APZyhTTJe_)#9i@wCmzEcCB~Gc;3u^f} zl2!*yS=qiaYsKD|Y0eqvLfYBIY~c|(jT(l^LoTvstLPGFy5EtTbDT2TSXwzCC*B{eF*cIoc8+HiEW`g0DfwjO(dR zy=IafP|X?CtUf{=1Bq(up)KgDsyc4XZggvVSk=Ij!5Pi&I7?P1M&da`8&YR}J4oWX zA-~Gg=e`$nx|>X_ZuHje@$F}7w~4LX=^@WXj+O&B+7v!AphN93#r?$|GHW}h(MOm; z9;~Aoe=Jvfh~v;>zN^t=|0=hUx5o3E{L9%FJYiQw3`TjlsLU1rGDRBL9dgDUZLv$H zCaCyrq69zEZTyDAO>-Cz9lXD3rVOT+_Xt%28%N>ZeJ@ za$b@+wE|Ux>^8>nY)8dhNh&!`N6CU)Z%>f|xG5A4^4WkPA(>lQe-h(hxDqBrKygTl}=!|&Y&3U=hntBD%l zIp(Nhzh|50ZQHvq+~*HMi-fUz?4;-u%8J?{uIPcH1s_I-S^(Ds2?_ma#SlmFFIoo;{4_` zVYq&-;8U>>y?Flas2Tz`_dQMDnpVi`+^moHjbF?U%H9_T%3_^x0_R1hVeXW(LB?R# zS#obGFIZq|U4v7i*ht=buOxHNr&wXryyS*wW)S_lpug5D?i_1nL1&RY{yJj<bi&qF4uXdE`gW!^4%T*mol5Ik8qx{z{rRI3(6!JtFw~{tx3(~Vr4zQ$HMS>U z1|9%Q@$*}|sM9bo0SIUqf#H}KnCJln?92d7Ixz=b3sZeQD`N{o0(w|FK6`ybD+dC0 z0Py%vOMgy)B^Y7p1axgg4NZ+rfH#=|uyhIzhL%bMY`|=Psuwo3Fk~e7i;u{|0%?b# zmBAlQ0t;;K|4B@k85rq+*&Pgl&u^jYU?^y)Z*5@s?}S7%cGRke9$Dz|8J6xCjD$s+ z93`ZW3MG_VaRmuxn3ouhj8V6HbJ2OgGM|=raQEx)ZyGb>o~_R7NgXd8>{CV3>E>LT zzkz{+T`%l{5oZ`5tYzMQ4MS-kSZ7yYVbE@%3Z zP$94$Rk@xVW0(+cruxH>zv8XY*qG7oJ0PCk3& zI`ecIACco_x4G^~{mJBdvYGZBotxvOmoKz4pcdV$6*AO|0b0b%3H2lG672)`g!E3|KPh2+5fE9WtXosI&W0uWxfF9rKz_Y3u2I5ho@Ist?lj zJviIUY9kQF?ugx8RP*rY(Tm{@yx{2;A>nxP>hF5)zgepP)ko21toR=_c3rEU^-<}0|yg(^*?=<1-P9OfQf;Ci3LCa zU}q%&u&@&V*%|?Wm5G3fo{fMR!2XZ>zW@EWiz8#_I) zT{Z$%;4oqWy2=@WU7v*=cuWtx&(27o`Hx}oUt^Vk>92Lruyl&nKdemu^mt%ff6(E7 zjFx{oH~x(;{!ihz|HT&pjI50RK6=)b&26yf(K?)!XGRjr4o?i#7tHQ!UZV`e7Dk+K z25ooP`oz)_u~)?``eQ61)twCX5yVWuNj~`-kdN2x&x46k#EB$RNCkp{<1$i6aSDv; zn}~m+fj{qxluwd|73FfSce03;_qtUxHG?uX+tpP>Tx@7n!Ce2=lTENek_z zo|eD!pJ_27BK@L!F5**+Vi6kMgB4blFOg3)t>b9#9!eQQFD-A&nbF$k{rJESdkvsE zV!S6}BsR!Wu~(@g*Jx{GF#DnxE~ky%K<=rL>tK_AuDh|8Wvo0ZvuwbY+^I(iu)DU4 z#ek0a{R1FgIHH93LcRz2^HQEH8uSN&L71B+cemXS>p5gUWqoFJmdmQ!8`K6P;Tc@+ ztvVJq0Tz$0JSPr|XXs`Wy)1Or_Oo(lxAH#a4jahAV)7b-Z&g`x0zSgI5-MQJnOIPtPs$Hb*DVNs#786w7M*X6O@G`L@G2~yu z%T;QVtYYtf)UOAl7hSbHNR>n{*b_RL!H#(|xVVffrrUdxi#nQ+`9&%I-tdggU2~)+ zuY7*D2w%zB?CuUrEaIYR+I~ zB{3BDi)}WPy24f~Qq2(666J_s8CVi3r))NkvP_+Hwqb1 z%@tt`L-2U+&ke+(>GMlr_=hRxYP+wFr)Cd6n_3h3tZ^rXzbHlY_iy4~Cu(?U&SXGR z>HMUiz7hhrToEiYBt_fmN|gdnAAd{d!bZIGAN2aj?EH`}vVP09|9Oh^0q^n9^|DxO zKO_+)QYAq*Fin6?UG___q)LcCdlI`3*)5U5$-k@lr+uYRLTxe*?!ACrS($Ir^BGoi z&E_z>yK?oMchH5$NG@ za$^*rn1sbhb-X9m_3;hX;q^ynOpeGk>Z$II`zR0%XCWd>@6Z-`=#(W4*iP$QH{L;z z&e@3CQ0hv1{6jtb=pF-KWA(~(GU2JB6ny}{0Go4^JX$Nzq>)SF95RDQ-_)@rIaeC% zpcULc$`SJiMQKo|tQCw_3)YwlV(*BN9`RrL-`o;(B54nPanKwT?5r#^`06T!{=BW- zo4O$#^}KyGkRx*tj`Ylx>T}$d@AlJ%)>swmrx#3zsAcg$Tdq@yPf|`&vF$s3P<9!; zdr!Hr`e}NYem%70Qy}^y^?vB$^q0-#%sa_@p4$1!@l_Ku=%HYZqs8gZL8wm?)@(od zvshk>KDLMj{1%p5Ua+?cd!#jDA+#scS5y_&#kN-BQl#$G1_>~Jv zm$7wUe(2HwTAGw);q1yAXsDh*mBw+q(*0@(Wy}l}KC3&PX&Z!j=QDBXE3Lx}hg?n% z_lpQwQeMMnSIgCa&1qD)v01vH)N&mMKA{mi9IfHY?Ug<_LO4RaqZKyxOShA*P=N4m z^}NJWfwzyW1z|@h$kYxyp`R^Y31ZL?8mgYQw?~_)sdkyrLG*7U9Xi4F_wRSfm&!`X+pB@GZDDrf9pJ<*w!2(ewMN9)^ z5J5{s`Y7+A54>W8SCSaAM^bo`6;_jM9$u9)^aJ;=wI*X3O-Pb`4*p4@8kf3H)fCrH zG@nAME0*e1I4BiySM_KV%N<}vZtx-3AH!bhJGCpwFrBEmkR!_g)3$0_22m7dS@rz@-niI1_jk+C>VFPX4Jql4P~N|{zKxHus4pPy0hWG;rn zLg)F|2DM!9wDV}QK|-?F?nI#r7YCDQAm-IzrN2dc3-(mO$g)kDB-^y zMV2}I3VSKBqcxO2U&@j@f={V$zi>%zS=e2%s3~->4;v}N4Wg+P!LU`VsP3(-onP6< z03!_5U-x$l<>y9@RQ!QWiKX#msU1MI1fa#19clou+;dLuBhajBVuT#t=JX795kC?l z__jt>tGMR4`wAItCllFsYwmPAIwRn^(>h)!=0Cq4MBup%?$m=_n69;$?O`uh7xI); zSiTWlIApGOXqlkggGuek6kihJvSV;b;~T`SIgOzYQ1n4)_XVlnSSz@=n=R`MXH^qb zjChq?cCkNAOaLx)$XVhu#U+Su`-lc&6Tzc?6k3Twq?9X&nu_KSbB-F2+E9=pU&JYXy%fy&_QvOL z1O^v@0*N{)u+P=#uD19)*N}?gGP!2r;Fo@);XFcM@0>TX=z9fqLsBaS2tU-Cfa`H4 zDx<&h1Ovlux$J+JmnSJoWhCGks|0UG?2J5%L!|K?{8b2-DMzU&y^wVq@L0qe<>Khg z)Q*8G7@56Th2^~S*#k;DN5zc7qf?qoqFpBS__G_`8~GcCYQ9DIS=brca_647t71kp zer%`g8rfN1aMq8qU&$Z42^#BU9YQaYh@anM4d4&G)nh2~cYsWkYwtlC-B=>Vgzow;V*k9Kg0?M=@Lm)e^C~rh$ZCOjSvsR9$Cj4K;6rO z$CUZMa#0L_OU#t0fpwgrB2f)ryTgsq_|-5aBUS@t8D~nO8pvFuE4DyfZ(%&RH`ig| z=0H981L=3OO%dUkpeIH-bd&T&(PNG`Y*e*AArJ<)Shd(qTqf-6V`+6&M%QMjY{bPKGhX z)QQ*ANdKhSw5)wX-DkGncmLm znn*umt70o#W~uK!V}G?>fSs;fCy3;ivGrdX_J%~P551%|Nk<1r`)XL^e-yTeUf69} zGQsvZM?N9&Ue3SmbyTJ5xvUP-*Jkh};jL@!172zsRZ zHuuV#zo&2&5;2G<^RC^Kheb@zvLkSv~+54qJ`AX1Wn%wVv0U8{5r%cSQZFFQ-aiEO%Z=~S!Z z+ojkJ2(>1h<~WkQ>!!%cO^z&4;z`nzr$O&6)&m50_4kb9Q_2mvHPkShuWQV$LKYE5 zO+5n09cL@y<=ThEUo%tj_)Aul24tLXYwk(BK3$H& z@K3AMgy6wT>gRR?9-#Qpg_?&(7?HYCyzH;l>@4q%cRfn(isj2B+D57xvt93HH$8Cd5ys8zP&CjDp*VF`MiQ*}<5QiIyX>X4%!o%;JZ34sZ6dTzF zUP87HG74rRZoilCJa~94FbpE7^)vI5tO{0+JIGvMU^om~9YcmIQ2F#mUF6!ZVl8O6@P!uIdvVxHaA1$#dI zay-n)0JkAx+EfD1)M2THdX(emh{zcmBKvtC=8ivkgg$35k_9w$3`&GQlsr}gNfe80 zR-P$boIz)PYEAaKyqek)&3OTWp@d16rg)aAT0PP})5GtF%y{nc*NxOi z&&PXV1=Lk2SUEbL0qxl#p0zYAydBK0PEIDpg`NKS`^?9V}Bl}l@@ z7|^GTwe_3Ta;Ei@&^i}yU59Xc5vVBPmB1(qm*mV>yAUOdFU~E@voaf{q^PT5)Ya1o zenj$M#uEwZo*>_RPIvM1$ubcuoUskX%r2>7$Ph2oW0?R~7~rLkf7oigYZJb7J6Xw+ zLsrBJw0(_Jublk~n@7;v_1Q#+{vA=Mv`A_5H|5$(+4@CS+1;Zov=G;caw;&^QSGTg z3rkan1XpkfG9wunAAt^&nq?YHmzwj}^U)OC_%SNUA?f_L{9I4`QXw95QV)e8 zI8l=m+9m4_9KYa4(qH0!4m!AW`V`I@Tw#k~co@n#@xP=XweXE|S_%tpIADkcp|4Hj zl6nxT~QYytccTIvX2p#GsVq(^%8DqP}~#nH7|CbUol=`?U0KP z?M=2-r?KnEEt1-4EyD9rd~}_o79x{iM=H6w0cvPA{>REm!2iU~JBlMPFNp6b_-31~ z&Jb9!I}DWEe^O?sJFxSz z(Wb-TP&)!#QxJp@CzjDthOAtzAT6Iq$lvhyz2w)Cua+IvSdH&5UF;X93U&%FcN6F! zG+TYVQEgDYS_Sh%G``|w7CN_;4yH0J1>aCw9E6o(!}uAwJqr(SE=F?9RU!)E=30eg7;R^e z$?|m3A)usXy(9QLIAhW{oIw{u?Cl%wP(K!fP0!83t&Op$dt0n0~sO51oW!6p>}z6jAw->Bzaevs_<({*ik ziJ$A`nVWWYqY1H1zYBl<RPR_hbj1P7H%c;lu;dCsE=%9_9= zxp>sOA)AVmlM_9BbAIp>*&MNlYy(qI%~{k#%qKdyY{%ft0-IR6V@hYHl$4bnh+Fj` zM%RzIZ`a4N_FXDP49&{I69>I6695caXjK!% zFA1wG{=L{ev!zs<19YqPwm+kr`&JC-I)9G{Mk6}2UYf6}89Mu)z$&wN{BSG3NO*Zs ze?JMaTmpfYZ)R#{yo29c)KgvkK6s$H1|^LS-Ga;;(xVV%-kILu3_urg6l$xMgcc8S zPF~iXwA>)_N|xGkKQi?ILnA`nOZF!ENiTo`j<(xQ zRku;crgM1yJ$JcHwKTG6a<5u2=$?RWLZei_7w3 zN4u?rKu=U06@N05gJ8ee7^|}K<3JNn*kuLm*jj8Q9GUv{h=a9&>F(3Yn{D)yCXC)L z^3?SZx9%_}Bm+3vZe}7*EJfI=a$-Va(cMNu(?-t1a-w@mXh>RGEvLgd6jo+MWzDmT zUw)gS4cUW{Mt!Z=&9B>MH6ZJ@F7V`KtXvkZnJrrl=G)oR0Sy(^dy`wAiYkxrL=_*= z`;pUht3zL2N^!3++CY~7J6vsf|3xUCd%k_R+Ve-inY~?@!s7^oRqOYW@jWGfKcJQi z=N387V9?HXRLmKkAaCBN86igh4e5E9vl7t zgnHSD%jcO$`>Dxo=j+L!!9LS0j6;@3R;96FR}8?j@bM4uE&tsA1scdwj*V|7j$WK&ci4|Xvy@xl zs5Y3Alu)UOHdtuQ@pf#M`t0koVG}PAX^_x2GoaJ8*yQ9cnYI|ap88lJ;a;P9+0sOJ zD*t*~b5Lf#&<|q$<%YWeZ)maLi;V@yfz*aKs4N!u>}xAwyZKi|D0OU`&d?*d0p|C7%II;QKq&;+1NZP)yy9_ul^Bd|AGEBtn z{R?h>_fualpUbw;BIE)yaMa%1@T@xsxjo6K+M^qB^P%73`F}hu!HQ75yjB4v3-gCu zxQzf&(wchy$UBh}!k|w{QRk2o`u;omRDDW2Yv?^gz2is`8jaV7A{`but?%^($3`9k zKdCOL@Ll!3n0I>4Xm7W?1yGg1g>`BW9^y1x#~4xyOn(R+GN01oFY~SE4?Wq2fAN&~ zj4A*@$noicxPx-$DqTYHTi};nHo<_jitotFre&RXbrN6T6kh8J_p~UWPU+ zbgS{*^+bkg&*1xUU>Ik|sjl%TXB-QRx7zfoW!o--M+abb8@}R(hWoS}+Ty8K`>JQ< z1yrace7O?_H?1^*_l|RP$KHk|n-X^HuZA* zPUbGdF^wb+#fs>Aa{`B=H{PJHiqSJrjDupxx(7$QBAIOYW)7iW=TGJIhaXN0iUg3v zk-Ua0S>$MIS1?kaoezxCIw&F)kP`1}F2N_*f{&Y2r?q7FKp1Cj+e>C#bG9Kx*l#;Z zCa}G@!BRrXUt2Pn6n-)xrLyJZyI(@~%R(Jndn<4w$*vMspk!VN^7cTqQ*6~UhGNzB*a1IHbr>tI6;9?LgTz&RU(D?)&w(rhM`pMs^pNx@U=A-%@aquYCw2%?d{zul zT1j6xBgh4i1F=<6XiL#g3$KJop2y2eT?xH#{Sn@!1KV2lovrL&xCqi+@2K1tSydC^ zKV~Pj26}l^z2<}38%#xT=qby5HssfqkecM}{_EjU~_!WFyn#D+no7 zIM(WWz(__`xM{R^7Hz=0|?K#$dx^K90q1qh+#~BNe(AFyEw7H!K2y^cPG=BD6bM{YW z$5c&54Us)Lcd%O*5FKD$82%wNhA;)|@RKMs4qyUi#_B|h2PKg=vya=G>z6v^R0}vR zSGUs$puK6CxFD^({k?cqEbi5+)ERm36NZL2;#+{@#}0VE{96ltY6*T_K(#3k%P3%B zXzRqgF~TR%QEQD2Jfbl1+*tRVqiVC+z7Os8I61LaPK&3n>PJ@~L*{ZAhTJ~dHVjfrpy$p$q%u;biyaHbzk|xy>>=8(Jn8%pnrR6baOIy<_iq`RPLa1rG2hsR8}; zEc*B%p`#oM z{5u2KZPA>+(6K8KQzNN|lbBZ57@td-Q@Oo~AW(Yw+_^cvL;>m;lb~tMl-(r`{$`f^8t_5TSB^J>4^spS-H(F#51CM^7Jru zl*-O%@z3c6ywbQs#~HK70Rl8%bmTqvG9vYD$1kv*&o7!6B<@sERhunLm2)-;(G^!u znu%S`7b}YH1F*wb}7nD}NVqljN9O ztIk4&PHM!qDhphDr5$R(KjQ!XcKqB*DXu!+io6|-t~DGITc6q7TOpJ=HQFHoKj9Q zfp@O;-t_SZ`P_IU;ff~9VjS?#L#vUp+N5uZV#0{ypvRD9kzHbr0quPy2X#-D&Y~K4 z&R-f!?+j#c9&mmOI1H z*Fn#@Z6<6I@NTt7d=$blyn2-r-9|#@e(f$3KC}-%n2^$(5(&!OT8q0=;XWI?(|ol( z%pb8~%S>Fk#``XKE`Tg+G&5;zlfs;5ha)nCjmFyGlRG#}7&1E6A?~1HbFb1$Hyk>&rDLiD&4Q7#t?-4&_TtOlxqGpB2-bU8-JNRBOC%E= zgz?AwaQg6bHq}pbUciy<0}r9#hy8^6bf+MO7sr&TtUD@Y|6U#veFG8QdRUJl=JS>6 z9IsFmwlg7imu?AIJ_VEb&Y+wxrGV2b$yM!b5sJB;aTQj*9FbXA(JXur7LTq z0FN-=tH76E?tn6NsM9llL^OW6r(i{do9KFwMidSQG(pnfcX!#ZfM0ivNMuu5-#^`0 z2-u#S4)Go9w1W#>TiY=`3C~H?ih@5%pOD*avGncofJIX2e!#%Wz7Y(jcd-unC3bnh z=j&9Yt)#kRn9vGVX2HDfxM1xi3lk<^ipaH=WkbzDZ>mp;m30GLU^m0P#2MlePqH86 zWu`ee1S)fRL_UJv;fU$m$D|MN4qOj}4$3IAPUNME5KA%)Rar)?j5Bp6ZIvpLTT?lE zxUv_DnNBF~G3Mz?HYu*qnK902+2pTE2J%$1o2733584iXTB>m7aTReDa~0}4ep-iG z|JeeBxE!*m#b9=IWA8{S-;HHJH(8AJH`Ce~(i}ZtB|$Z^yO?XTlE9egH?zAagU$_M z$N1@*gnfo5#$n5TY3+D}VSsq>`_v;hSB}4Nn)if(o$@s*LDE9tn=0sl?_3puVS{c! zY3LS!2!~!tLk<)ndujVnc*{`IBe-b&(1Aje$AVNMBr{ajL2vHfa7_~6nuCQ@$|afm z3`q;})QP4Niazrda)A)PUESxtDDpi83?t_Ud~O$%;?Nys)#oiKxPgJnOiVnS6qJ#d z(Eyb?4pQnB7J7zwG$n+{NCasERs>@VgGM7(M1xi+s7A|iX>ww|uM5Meal;ut!Nc3t za@iax;S&=-v}&wfaWH=1%?!Vb3>U0HO`N%$r2TqVOwq)<((5!k|(Q=(MXb6Fc;MFkC;6ue#Bb%7HY2 z56?ZFhQI=YD5ayKRpdjk(ZVHDnkvp%s-{%`L#j6g=}CV zevmX4IYiaiwT3BrB}S6w-CRzO6|d|#l%@%NMKHFPiOiA9%g0M|^AoH}dIWP2WFqp{ zhm7s#R4LF#$0FE{*&9}{T8zEq7GMc- z{Vc~F9GBv4H<_h&2b%c-I{!E&@OPa4pH5l;3mfylL?h<^TPLl+e~L!(hQ^K-x_19m zjsDY23nb@%tg%4Rh@I`fi$?!{C8NKP`hP<9|8AxQlKuaanKo`TB9#|truBdv9oB=; zT<;1qAau2eY8w)`-UFwv;}X^9#iV#I)3JBK0Xn#?PBAoTmI&GeR9sXGA?eb&`!Kxw@u4}!;?0b4P%i{rmNv( zA0*-(lj)hiw^4ZBR&aaoueqf%-%kQbq;qS+IK2?&xs&OKef2a&V5n|u; zDX+=X8GNB)Bfjizw#(*%JmokH(D2b--tAIfKzIr-yT@&Yx?HyIMpHFjF!*F4|A3+M za;Q%Kc8;9{bio=bd5tlbdLb5gmEX^QKuUh_yC2aF^-Xn78Bc3hi3oU=I=&p9h<(7S zetl6lAh~N?YMtVl<#;n6`~0HL2J=RBCUkU3udwiX-3s%TK9Scs>-n-ca+RpKMS3?G z)jYLX4E~1uKyo)3T{yK#2rcmermFf9%J>HNO6&CY(KSA^X*zjQ>G)ziv^m4$*O~7H zB_rWg$dugaSDWvZZ~y06D&9F_-=z1- ziSs5<#%6LF+!Ni)xjiWtvHJUapne%0B3CC{^V`-(hkAi+59Qk{6c!&+_umbf|Bn{l z|8b1`t+vGq90>pB;stIm^q02vN3&uCI%wH|&RGC}X0y=S-8GzarJ2L?z3(#!~6lnp>KphMy$}!RZap(dyu0L*Fpc|MG=*VRTmi_bk z&wPK{0RWg`feGl|{d4@MO`uB{*bW;5upMAI7NE121vsJsz-M3vYFB@>F*cwq%)$n& z8@P!PfQc2BnGJXysKK$aGXM3;!Ul8<1Me}j10BQcOu+I$H!%Y+0f3qsux_S5@9j^$ zf37jJ{nb7rFwdXF1pFNSq`%%9P{;f4y4zphS^ufK{Wr%j@I&~QD*2Cq1Hgv=$aR17 zt?)0$FatB|e+qB=?$8eEi}73Tomo)?yvXq&qaRNYqG0&pAntx3=yG}FEW;2a5)fil zq86mZM#I(nOVv`5qmnzeVtc#Ewky&jh14W?lY&lZ>1?)ZEUD@Bhi4NJGo;DiTB*pA zH93ju9)E&RQ_|WyJ*IIz~sx2hhO=VoN|$X@w#$zs%XfBv3c-SZOh6zOTE57IB~ z8}MBfzLhWIRj~Qu>9M85vly6Rq_zEOCbbxec5Si;l$AE_f|>YlAGhEduE`!tApB>l zSV`$EMILT%m&*&Km;AqP=0}U^q8j`KgR#@^#8vi4*^cwMgKfh_C4ax`YHgjD_NL7( zvW`haH>Jm(z$juw+RIzH|1ZkkF*>ua-P4V2+qP|^V%xTD+qP{xsfuk^P%$b-#pkL2 z?%liJv)?}5=fge5Tyr5KBXcF=$?uxiZ7fnvG_&n44}(M`#H4?YdrZ-_vI0hV^Z=hA zf+#ua45cbsn630?$w$y3JC2$Fi*k-DKYE}ag~F{F;Y1M##<9vt*Ce8<45h?7H%88P zo@S{83k0~+Noxbo~{GiIJ@$>zaZdaOe8=zY(&Sx1qbRb;%83V zFdUi8a?Bk;g@zmFO^%T*qPj;$CWeZ_&OyEJw618ptuIaN97(gQ;VBF4#Zma+lT=AOTk;U=LxnnH6Hn&-MCKN^+jT2V@b%pIaVivB73!$xKs zgE8eU`8#w&DRR$SL=WUro;$%SymLT)XE<9^-wzucIXJ3F8SebfP-B#%*!rpoQb+<6 z4p0+Ii`^R>2>T$<;+jF5b@kuJ;F;-Rzt5al!kj1how%ea=Xas|wzxe|{p*QMkpdZ+ zq1$qQU`>5r07F><(L2Q#yJ!K~6pcGS zESl2=uEIBAwDHSBUtP*32ScN^bL)zEXbB!ZbIN@1_eeyO6yztwNFnr7uJ;rrGVvbD zu5(nbdMor*7<<5<{|6it(OlJ@h!lya35nN;f)cLm7D34_OC3I$-e{QK6e1H?d_$oo zn>wRZu7uWsQsWZTV6ib2RHknuDDHuhQ9nA}V_1DYQ%R__Qfl$N=Yw#`I}6Lst4Z3v{N zO;JHxuH`e*j^QZn`G%U|?`h`z>SxE~2wqvScYU_|UB4CYCz|W61mkJnX&FKV&R^5W zynt5ttK8(0%VIhN4yLs1PPQ0l=q99?)ef-=<1AwYX<0&gbVDH0#L+U zVC!;@=fJ1rfPttZ)Vw616dZAYv52_9u*d)fxN=?AQ5$F-aK;gKh0exyo{|>y(7f`4Tt3%8JncC1#r!YSVF0cjH}izG>TyF@FQy_ z2=Ob84;*wQ279r(>le7x0dl;%Y7yr(QTX?1vTsF}V!tDzYNL&wN!zp+ z63}4m;Hp$7{YzDkskbhZs%o0g}JM|Mrb`ub_jdvD`R;tGew4ax0KOe3m>JbcHrSaOu}#?Nn5r4LeP!w*4V<7Ba*?${Dcuk@9CcBE%cZh9ELhZs=~L`H z;FsiepJ#J@t)H=Ek>z08fR$TsjSJ7Og6Qo{Ro`C^AAhW2T7q6DBA&0fvQOJBr(%@F zSN>Sl+&19Lg$xbD6}3E`o4vk0m>r7vyPgN9jYAyPf^uh&;;3YnmkTRrs_%W!OgCF9 zLWAiTM;2!a4>M6fh`l8-)xnJ~X)DDijpHf4ue{iR6t(wIBHH~ZfHrvGAk*X85GxXp2NW`~kU*Pv1r z6C3`CFEtqV$yTgl2$6=SLT569CTqc^TssUG0>PXsiwTOX9OB5O0%t07amL}Z$!8yF z`co+SCK3*bObe85?O^x-Ipk+}Vn|EZZ~MZ^#^PKJbWgZf#k4N8j`1TVpa_7M&kiNJ!Bw2*oR#qp?Xc@6&S4DT-d$_r7yZPIH ze$R@JXT?0uI628kV4$1N;JyA>T{ytJ{@HcE6El|Jf3Y)5%lNgi(GnmbaQI|I5a|zm zXes`Yw5mUgQLp{Pnji-%#FI5uvYLXk(lo{S$QIZhveuJyt~*}&u}f(;DR zLN7y~S$gS{`uZ|9DZ9aU9mUVP4FQwdJxjCfji>#poRqlDtM1(-RKbzHmR2VS{D57r zU*11#jg+7te^|*}F3W6ORT~_HV`&VRs^u!!s0@h%9L^>NHxU{cd?tuBK|_iTtc)G3 zUu#&=ATFWf1RPgf^+Rhrr*K4=SlC;fBc@8Ipkc`x4el3n!=jgFM2$A0t>tK2c(z0> zVis86LN14aVJgM}W1bd1GX}qY-P7*<+ink-DDe%6M$IOEzsB?WPt~ZO>2#yflgqd# zYXP(nD>!cT$7reagB3_OR`?I~*fV0z+05p$Oe3Z*st{Og5)W)34Kkv1LASz0*s)PY zi|W!76>m&zv?~~2<%GIC3p|JvERRaf5b0FS)mr*F@jTeDCe^G#qaq)2@!|%GR}M4| z(cRk5aKEkG)W`|AvA8-LwstagjM+2ZNP?Obs~C8i_>doe4>*u{77Ch|z&?6G#1yS+ zXlq&1R@rW@wcbDNSA*!c#+}El8ruk4g-OGucNMqXriT$@-E0gYD1_i!ueUS@ylQtG z0x_IgP8)7WXPHu(?XHT7D)7~)Ls>PraKmKF+*9{$LK10J#qMr$$oH!4ls^~OKkKZ* z2qXH#PD>0RcP`P9uZDE+)-P3sM;!QE6T)-O2zt%0t)Mg?Hs@X)9Mw7xY0p7uTw6F+p?taVJO+$>+}Y4SmD*A_9O_RW!4u7!s&P3yZu~lc@CqF^L_(T&GKs#fps%{;M` z-RFc7;W2-beot5Tet~gr_9Lfc##%N@FOAlKrML%48EepAj16UCg@y{kYY;3F*onxt zMFc@PF%fyLLb;i3JXwq~=Mo0JITd=1E+^zR5&=S-42B|NLT$EY1{WcTB4TQo+|XK6 zfCxB}Q{x=KP)j>BB)Iz^=Fv2{U-6=0y_#-kc$e3XI4C?mhKB1skhheTP!VCJgbX1p zpvk-|`F{AH54&JEd?On?Eu8DS>hngA8{E$aapF$I5Q1DxqBT!#(3Y%^1QIEN915^9 zOQ@KV!aFn>R|_#?0kY zT>x~UN$5Df7G8Tw00=K7&XVUen&;~wCdy!#lonuz|UVV5O?-O$Q`gO z&5%UFYQ@$MlF0Os>6argz(qfTy>VX2vL~=J*QdNbiZ~N2ObLFEj;9y+nODz5q8_9DkF(X; zo7VL3$hjP8UCuN0@mGEOcx8T0MdS6r!?DTw&FAdGJelzmwEUlu+Yf74al$!^G z^&CEmoP{cfsZTHpQu>yzG}6ps>X%BMJ~4x)b#=2AOKX~L%f+2Vek?)@QDE+d**#Mp z?3)I{0uw_s6>s+hA3rN?tBsiDJvw?u13QG{|){42p`(p=O5VaVj12~iNI15QJ*7MxDxS5kll=$XsOLM%)prM zWP_lR9KUwj@`gDjTd}a=wd0h7V4R3+?vX@liYCWtsDWjv&TYqZJ;2p3{U733Ep~ie zIn~u&=RU?cU5zpA`tD*-8~nWu_m&#+iEipqMFlpNmV@y&2bVgfOWi}pTFp`FZAjRw zklMrd>d=QHN|NsOa}=Sv+a;~Po8CV@f*?aY>ep{r?$Ox%-2bT-7U2NTp?Z`4>s=3> zGy>(bXv{u_WBY03<*Y)-Dox#?J!d4yM6ck(7}-E98Z4v!BOlYDz-K>br{2BT22Rz* z0d)615j#!XGZLPy>Ui$~jsO^cv-04xi-uh)z0jR@&6xcDsV11$ zg31hA)$3*LR-uXF(XQ9EU^Km=>F6#jQ%;YWcVjS3l8Brf_WTxyk0Ig~O<-y;s)?#G10 zCrgA}YfMg3!Jnx*3=nBl>GGR4jyv`0{ROdh-COq#b)9>(UiQb3=I}&I2->Q1Qa4#% zzq608*stm?S{teta(kV$5#J+xdgio~zN4ISkYsL=chF8N+Vhx0A(|LBB&y0-6Q)MR z({g@3b}5!GK4Y$QTgKLjM7(dc59Y*shwvb1AeytzHr7KsVf6Y!2^QWy7nFU}DAzDJ zgxD8?{D(!1b%Kr8hEk>aJ<8Tim$ut#oJ~AZ_zIF|kcJ5kEoy_J0)Myj3@)9HwgK@6 z9uC&5ZQWysRHUy(*bs-@7zvIddC9#u5bJ$a?qzny88)$(SSPq%DMHSCU?7%wCW}Zy)?pp z_!%}yY8D2rNJc~iM-cgaX}H1CczEn^pJPY2#3SUpi4>3{eJMzs*y(<@cI}O!Bsaql z8FHd{!Wn{OQM*(^f$CWt$A`yPRJlq=ItO=-tjZ6#`xuRfFp55yfcR=VJ5=McWn7-V zWbZHf?vW~c-SKH;>FY`1347L9wFeg%S`9_&EO$Y^< z+=*^Do$A?4RO=S?`GSUKU7-&5F2Jk>)L_tRp+SfO*4K*iMJWoV$Z#04KXTP@{IwW2 zjEAfVOXWkV9S8=tcLIvyqT<~)ebij@LR@o7QXS|^{=|O}hD;d;{>5uN!tc^Ns(}m| z#K4SU)R%oB4udC!Z;+eFtFS5MqFOZnx@N_p|uLX0HVi>-3?fm*=C%T+Kt<(Jp?*##+D29Xn+nI%!{&LkKz)=_hM#KN_Fz z8{Jv8nh4aVgV1LPjl`+uLmCaiHIx$(3Cgv)#8;1JCc8#$r43G!U=%86BlVKfx^D+7 zC~bc4=MO4$%YTfF7YXKXskpBHETgT266as>`Oe{Yu(&?>Eye3gXf2a?fXB0<{dxVs z)@G*8!?ivBs&;bsIH%9o#=JRmAY1V8@+5+b|(6eKL2 zIQ}HawT;Y%>^Yr|DU~8)?%S~dN6wwjH*fsHqg(GV|1CSZuHZW9-NBuFZ^W;oEKGX` zOM%Dl_;Y}N=sBIOxBPijjf5Aof7`Az3FvP=XyZMpkPn6{;wb#W#U*1|M#knT@(%PK z5xa|^f{j9?z`TSEgp;GQlcFF+^j8`3GVLZ_GHzuOB)mh+w0KYSdLa{s$%=*H2APVY zL0A~R@q9f^;h1_rTnjLFY7SHVbs|{0v5f7DH_%~C7pz;_w(gv4uMmgX!MpZFTt^Bn z^rjGGAu}uBs1rtF-s zHEQ3jj}v;bMXkbNl!$L!XWDC$HnV4@C^pn5;raZ?Hd9`sJ1cDNF88zRdkT2Bo0&Mq zuW4Mh{o;JiaUHCv1lmve_k3*AwaxsIHj`dO{V(1vo(Mi)&)jp?2j%WY%tp}hBhC>T zP65Wx5TRVy*+v-m-N)_(~{95bgF{?U7HTE8O5Mx70@)w)u=g&a(5NEH}$$8yfao8RRiwK&MdJ}wim7zZA zd~S^rf2bdSVos(4urHowiQue6a;ug9#}qz>RxL9!VZQtqr_{P0O7W{a%t%)(u0m zPSY;R-pTyjXC-APbV8x7m1gElr9PIL33Re+TMN-!KXT>)7dA+o@>vvs{G&2uorv0p zF+m-s_Mp?LL{dQ0*Lhyf=V*U0q<)E;yB&olGqQgfn?oW=;}Gu=a-W1tOzB)cSFVw> zwBz{(@73+N?i?|@T&`RqUu1Yt{+>TO?wP}6OZTbb93%hrfsXlm(_2Ts-^Dt@H$^`* zEv<_4&=Wai^902QZX<~>uRo9}qD`_39%Qd*54zc};Wkptv$IqjE^SO@~<7D(OeXC=1e{mhQX zGZH%7JxmrFm);JR^LAU+p2I)<;`lUn2_Jsf)0cT%JnWxUSd8{NYdp{P3@{7c9)tK7 z%_k{WoL?YZQn`pfYjEO4a^>l()v1z8A>!(a*V_fEW!xXFmW z(vuy>^83pefsM?w2gOnkCcH{)e_k1+i zCN75WYSaS1}(D z{|UY;PhA?Z}tqBrSLMWcJ9P`}qy0Y_tS>jjy;X*MrJIu1C~Inlp`X+L1nRd{?*idxVJJ zsruav^{dvbQf11xC3ODo-fvM{-_gVi{?wp}x^)W{rZ~RSD7a}N_*Z!d^9Ae&a|m@J z_^YWw8MNS9cKDh^biw4H6{(1U%pey<_D>0jS@2u~yLU4$ba9J4zK0G~H;7dd+(!Y$ zU~G0JhRw_%=0%o%xNpSh<9zT-mW1Qv@T}vLd}%>NWQMb5hTzT3C#;Pqa?K59hUhR< z)hvxTX;h;ujtD%powT4QAhUuNhVa>nn=Fn5`fC0pprSI>>LVB!3Jf#f+71Y^;l^@02xDUJQi> z%8&#DGw)O!d3w-8)ZyLqG9PDKBNMUn6s*w0pYPj%D0EuJIV(pt_i!|M`}?7(328?& zOBPpmGZR1PusR;>pK}`;?rS=YF|UlybD)#oVCF*?V2}w1xg|?OUJm=cDLPRzC>$-* zv;?oc%;J^LYNUNiF|nzNPv}xKt6xpD~tU zj-iq6H^ti0A67>Fl^>rkvpX}U2uEKi?utTRgv}OKz5w$}5gbP{?WP`N7dx@>`x2y>6x(P0tpjh4um zDI9{^pv?WV;lLH*fjewu3q^@GF5iEZI!@Jzf- zP)gEH9gp??U?~2#!;Pu=0ipwl33xo;_G`j41>PiVcpyd`R^3xzOWt}9&>m#R3nk4_ zg5Z=0BRV)*FqQ(QSoI$+Z@%^>pK(^Q*Yb_YfdzpCi!y_;T3RB|UJ(1Qq0=@bS}Z;= z>RN#U&gW)u$CzPxJQ2Kdmbnf36rhzKXPAUSMgHj zR1>UCf8S0nFHayP$+O3zbh4IcovlK9mKPl~FZ1q;YIls!P2@N~X~)lut5TZ2rtitg z3s4^5P0WAYwyi!lS@_a81{_$0c9f+-Y zOO>ft?BMn~v_GDo5oMF!BG%Acx3Xhe^DU69l9f3K0tgKHG>i$fO^yV?Uko@HxZVF9 zN%Nn^0xkej@?Y@T|E;k=*hyT6Ck)4SdK%Q~_qbpz~VrF9I{#ReYf1zib z|LSr4d-Pu($GzF9$kZ@r9g?5y5pkuv3_h z17DTc7UvX4u?OpN%1O_rbsi>`%u<}y`HO?So&F__dxd-N_mGo;bqrevd*kOM4SU_6 z6=$#zOfgWsbg1;M_5~H*-t~|-Rn`XW_FV?6eY7vIy$z^P;wBR`Gwa{^R^Zn+w+CfI zh)}JRObIfdcC!T>C)#WTY%Yoy#Y2dcvrNPRKy)@2bfRcJV4xBN@AiAthF}rjn@zSw zK-g~DB_T>nfUr;VfJDH=C-E!5V}LMz*+4z_iTnvU@tK{wAt<7LS+IwV{$}Hg%B?eKs8H2-g82LFCx{#)FO6(H95AGjAg699|)D@^o**_U~}3|E4+kXU+fX zTkzjC2LROT|AbpHaWZrKubzV=9%x6MF}I#CAR&-p_+T=qbI<}J;XTma!5k9ezzC|v zU*t+aZpdImq9};S%fi$GXd6*8qsfRX*jr5~Cyp)~pQ$EmRxI^6TUO=LIAi&2O-o$T z6m<6ep($aZWyi3$X?|waR?z?`z(y}p<%2E+mB6Kj67O1c>w_#SH z^Bzdwj}I5f_v>oDjzRudG_G=WF|p&q>(L2C1{qu>Rf$feB-r}=8iP6`5E}n8?@Ggb zdwv|?3qfo_y|P{#gBo zC7_Dp$8b}(G;I`=8Z}c(xUm#9^t<|snuk>G#a{)4*gqxxdvS?BOD-><%=8rt2JSEn z{2o!J1Kb~#-5E%wF-9psS<*wHh5NaPT+B*X*1C9)QS{=|GKmo3hIO5}u8Woj1F84H98WM$wXaSO9sa6LBs(;3$igquE-yBK89y<>$y!#8oq6bX%5k{g5 zxiE(^0=OX+G@$pM>o-koP@h0JU@h9mtH`=)C&^ybS=p#D&}R8_{MbhX3ru_l&5rp; zJ}dOIVqTLP9z8U!$nmbv&e&p>gQ(i$L`eod(_F-8BYw~(HMmWXdogvPH6f0%6O{dR zoXhd66w=s;`eET@`@I2Nbx!Lmj8|Rpagt#DVixP3K<4t%1<(xNlX$FTH)Am@(CE37 zBcoFBr18mhYl7%`!E3Y}nEjJQfU@=Fu;MQa!L%*!@^g%akT8%ajG^)(K6J)`?DN%M>M`O;cB3 zJC^Ps4s7v4xlv_l%d*e?q(Ix9OeAo%1o0~KA!b>>`aoTZ34(!3U_yFG#7hkOB30%E zDi~T`lL1W7UJ@doHTJmsBjJm9y-A5x_DUzV=!PA)+u-$KL5Ql+itsM}DdxRq3f-)f9;2Mu&52w{XEnz*{#s|u~K5|XyYUj4bvmI#wi#B>tb${FS% zGfMOR(7H?PAWZy8CQCaN0kM`i=!SIZx-ll0;={)RlSHy4hXKn%6SR_fNfh+Dc`-EP zpb42#@7FgF&0sQm_n_Zmh4bLfLqb)9ew@T4i)i4yCSuQgTqprQ>KsXv#znINDNUIo zPNNMFRT!l-WMH(oV*IAUc^I=W$67j= z&kNmP_{U@_u&BvyqNeuIkQzY0 zcBQq(em=(!=L3n$oL_9x&S_ue862|CZ2{m=s0zUL4#U7XU`H%Mc3K_{>?c#+T_Y+Bmtp>?q42V1V#m9Y3j&#qi&<_Bj^O2sAjbjyAp>UQPCi1+^gdDkV$qM zqO6QGbf@z#CP%0~Kk3 z^neUOTxBtt^fq9C^v;O6a)8$*0O*wLe;`zjxIbn%1F`;tsRCt^0WeiLfGZFIC-kN3wKVPpSduP)Hx-H?0!J$a zhf0wtprz~e#t0};qw`9UhVl!Mgyp22E%Duwzfql|g+ZOO0VW}b(Y`l9|kqF6NG-C+KdJFV=s@-O^CdD( zm^h&&u`rl>_K6zy|NNw)lw^-orSU_vVmlWuRX?fX#oNz*CR8cHE1itmb$s6}^5k-m zT{ms^o)R-~va%1_T^wCqO=aS!$!9fe>aC5dflZ6D=O^u+qA%i**a)>s9AZeR0rnrD zw~T#|&Y^5i=lv*>!L;B>A47k+0LkIGn7WvXX$|ZCkg(|DALv~-rD2%s$l#63s@Sk# zKwN3e%NQ8_X@1WYch&Ccr)Q8dr;;t`w63P7gkee5V9m1et(`XPMZaR=@Zr0#H*kjU z^8(Km42gpXsRpA{&xZ%Eeq2Bm*c+{{vyWUCbRP{S=t5B+x%qpIIV^mkMtFX8hHUf3x$>XgJ-p6)x)RXIXM1@ZHRu@ z4zE|n!iF&&l#&)S&KOzl{&$1|9JdoM7=|$H`hCOw6Q6k4iIJs_;KPDP8w5vGbA09B za$>Q#Vd9FVr7OLKe|rw~RIu z{v397Tn(KRhq1yq2w5bHl_7*nWLPYhjrw6*7tiX7UgwkBi2hDWXN`+Ahj5Bt9o&6S zG;g1Cy9=Zk{TTT>$MB;H*LW|NA(X}|>BUnG9eAFGV9z&~dwvGepQtP1I0OyfeaK^` zjX;^oO1_aa!kB>A)3vR;>`$oO{etd?KBopstnfC$ijIjuTFIL*HJ$NKko_IZ8uq99 zWpc3M$mL{Q+WCn{q`HO4sie8l(gHgfSEvq)*)zK{gkjR$Zf~-I)61)dFvHNt57hn# zeI`1+T_YW7dQVk;&*W)3jy@j)y#%Hk*4ICD0#ZX5&VZdE| zurGf<>Q`OYvbO%@>SpV8|4hGe4Q=>j8SCYpCUB-Z%oi7kd77*Y0&}5ns zbkkl@Vvu_c)0k3B9rc)@(72){6%#Hn=bV{x&U>iznl{aXNURw@*0rtQlXR|tr+;<% z{guPEz}l_zR}}GAUd64TMQv}7`CQd!RmJtGaen_@N;SSD4`Oa<_hN7Z|Byzp`!a?- z^$=bR>F>f^`o=NiVR_Q@A9SXou`fnaV5_Iu5yEVC_P1W*8cs>4>cA=+l^VgiX>u-R zNAPTrj#>mE)wZ@rTN_!rF*}-@OzYiVyBHphTbj6)sSpqxseJ zto%noJ0BB%eL<@~3bJxPTOjN!1Qc$d%Itoqsp&l?576|MSY4|So^Nak)~;yf6)$P; z#A#lcI?z=E&+Rf0rhgfbiMW)X|DPvi8$m|^Gej4b1ta_KOB2Hg{c^KV4(ZJ{Fe!a`dNvj>?Y z1{W&494W}*i*2&DG?W$&ZSI5@l(pX1tH*M+&BC@ddeZwjrH+8TmhJek5{w9K{MqiW z9rjcz-Vh(cVdx>M{LcrIPIp{X;IGC%QBT|v@cZi6?v+oJdw+J`bUmmy?C9>y_O1!E zwEQe)wz|@~Rri*2YulpvEeHAO>Tvyokh`~Jkq~=Zx#hxA^~5#J+t0m4vQc?p8%Diz z{1XnnXy-(<J{0He}mE*amtI>4-br=niY#$6f4LO4|MDG0#&Il2^P^s?|%E$c`S` z9CUV-9A)c~?Y3s4PSTy5li3S&mmiH_*LLlRZ_C6IyE1#7chAyr*D+m}&rjj8KW#k? zGVA5Rc4h|=(VR|;AZsm9k`(2;e4aWuFlbb`qci;&Zqh>9%xx-@jYdXQ;I@*;?A}jS z?zPUd2hObvsHB2Rt_`!+fTE`?1M_x8e6|q3h`moBYnZhhX+DuS3W2FRx*rOp`6gaa zGj3Hw0SipItwjh6wBEgCG&#F1_HsBL=kQ9CwOP6JH9uQ8H~5^NEzPba2ig;RE82z4 zW>fW0k$0r|eK;rj;jf{A*t*Gvg$c7j%&*k6B6{Wsf^_X}NA67|iiOi< zI-)~&h}wYim{hQ5o)iJ=UZXVU#qn&Bd-9p1hVTn344%+4u%u-J8sV;wW4T1XFEgwO zoWssjyT!Yyrl3rbXE6dD<=U1-u!!{vDfAIRT8Z6&z@0yvB%@?8zN;J9%JElu*!@a) zpDp}|n~`b72&M}w)S(hX$wsufXP$$?6OGNUdzY^kky4jQ(l9Z0t~E}5z4qP}K&DMF z*1G_?!xzU&>y9CdP&KT0WgHH}3E6F1g-@+x2c6GIbX|+L5*!qcHry%t7__`oJgAB& zyvXfqsd*OtJk2PWVN)l6e&CgzL||Y3eP&ZNzFYPH#yI(LLdeC9V-3R`?}2%3nJ>_C z;6Xglz{~8@O6?b13C$Pwfmj);eF*O(#bM4Y+HLQTbU2?>cnmSra?eHecEcR3B6=RS zso;-+`BpCekWAATXN=-BEO^9^cjy?cN3MpI-gKMQf;r!_pOkbj z)fQ}C87{EX2`t|4(HxBTy7lCkF|WPfF4ANZHLu&VSqc_)km8^;j=`VSkY>WhBQU;0 zjL%3ZGV^HwjYO(7=cq7K9of&saxjs?=8?29ZfJH?d`RSauK%JE8SWQ|K(s{np3=i< z*$qm22L<)wFDf<~2Z1>CONIFUIDth*Zt`-qth*#h;M|cgn|FTIqXM&^VWa#8kw?DM zRX(IrvT{2O+qk6gzFP?{N3NrWkJ*6$_X~0u&a`iTjY$svkh;ow~qPvOm8KRJ*|V? z_O8{AaC7I_Dwn5&_vMzRV8Y6E<$+@jfjuo0H3D^C@t1QdpbqBp@a_M|L` z$pOaarSx^+c&^9+Gr4D`>I8+aSU?8vw2=1liS$>Dl(^!%^N2 zvd}}8OzGy0_mOp)p78aGeylt^u)b$a8LZ(rH7w+IO=)J<{4|~Af;WFJWM@PL%7+So zokthVh+Qr%W+_F*1w%A)Q)*RLSdoI44&)SNa7*Io46rktAugKt|K%G2i>357Lg~ z>Yz7!BB&C|M}$aAI8dZI;L)iay}!k z57GIhfAZ*?d3|K@Vo-Hi{j-{|vgEw)oO1cAxXIEREibhY>X#zUYs4`kt<< z&?7GRYB9}YBgn;k=xZy;$v*mH1DYlx31R#!BOT-HH#tV=9n&yH6*WEdK*>6$emXjO z#A!mAX*noANd$^T%FuXJ)~YB}R_Xoq>BUy2RGA8lgmQ||`j;+pBOhZ9^3IZ|5m8pz z`>Vov&XjL6Wk%2A+hW#An%VNuKluGbzC^4Ue1wD(Lz9+`z0LjQD-qNo)9(3YqeNMy zH7l#_fGJ+JQy+!gOUk;bRkxZ=sL-ImYxZ!ht6{0JL@*AzdG}$6leJ}3JD~ic%CfkP z_>v%yDU{E$s<@4;{ryEyj)VHdiSu-GwKQd5Wve#AUPgw0HItQ|2v;BSO)s&^R<$za zXkv`2e1AVQm5pg^Wy|7fW)tKGUGz*)2hTaD4ILydQi7s`aZ?j1#BGKC;RH-D2IkSB z19gc4l7efdb>KrmPZnA>GAw4z(d3ClwXOU%q+{3X(7k``3gX(wC2FrHB}b7=ZN$RN z>tdN@2^tGl4RSOM8Fp4y7Ir*2X)+cMoCPjJ0d=RbW6fV9G4F1c{`$#&o)!>m;N>7* z{wrYmXw`~l6|vj`0sI8Bg66H~l_t1jM^uRoQQQifzWARo5(Q$MuvS>D62~7H zygIDSX%HRA27B=*A5SPs;vI!y86v(gq*1yArQs?tAdC#gXQ41U!itr390&|IwkKXFG&}QyPpT?$OF1x4eU_l;VZsiiuOJs+fp4~QQ47_Ut;IG;p4v#^^o zoq|`zafz=MnSPpflhpegD8p?8xTdU1U-=*nY+#Gji%vP^BGcR^jWls{L3wV)X_eNX zUipK{!>9D0cEzjoJznS@$;#BF)VbPS{IX3;k;mmP5TdR?9BQ#Y)ggKy9<=>gdH4|) z7(5am<+%Q)?J)wB0S$UP4cFL{Ucq-#rg??QsJS80aD>~>A%uU1uXp>{=d8Q~INHru zy~vq`TJuWXGfR;$i#CK5Df_cCl!@2R*$vcunGRZ2SNW%rY`-j(d7S^Or4G8uS^}# zjEk9>8Q_&>VrKi-bn<_-ssEqyNq}(U-|5r=!O&kNH6T>^&qi~ASm}R$BmZL~JS!X9 zzu5)FKk~^3+c{4E zW_*m5E|w3x{_dtaBMd!<))1@S9*kjh`#xw>I@jGtQAtLk*Cp+kaHM{kz5Y|I;w>zgunpHgRO({MW=0 zkOuy3+r|P&6#u4-?0|M~EP%k14IrH00<3p-W>0@AVCD2X9dVs*qAwB z{@(LX%QwK>UxCA4k@`R9xw!vH9siEm0MB3ph#%MhA^CroHvIEK{fo5WpOyKqYxTcN z8vxRY|5J*{!p-$Bw)7)ySXb1wto{<-g9x&zWO~?~2>$k_5aD$RLp)v~a$6%b+YKp} z1`$KLIQk&{q*1I06e4K&P^6aMt9BcqJgG<`IwCDrGP0aOS!h=<#yS>y>r?v zdKf5w{%}{Z4*$5$TljIDl#^)Ml|A|;+Y0Gp+PX**{~ndr*rTUrFt!0Gjt-}1g}T?nFgH-1@pqY@~_B78t*F8 zyjZVWg>#Z&k)36Ojj*q8NY%BmW66sY4})%@82M!Px1m^H!?$hPry=}Lepn`Za{Atu z$BF$AExPjd`u*w^j6z?C2Ghpn+1yij!i+?5ul>`V3+Ao31MsXKgB5TBUY4vi7S#(i zOeIow5~8-)pBU5h5)q1o(-SwuEq>H;wFH|bwFC)2?tyrs3`P(av!2;Vvo+XBr9g+c zfIlD?v>xPKVf+yMVDm&ZGI6l{!m5lgiVnVkTKXZ9;bwAT(=P?T-qehP?&J$mE_e{< zQWD2YV>me!Ys_y&+$W8 zJIph&sUCA+=kA~HF1G*;xFWacsb1--!yoO%EtK|Vf;*UX=aG!fKd{~_u-W3?Av`2x z7Eu2A8mVNf7YSseNMIJSEnNxKWm&E_*B|MuZ+h1$03UL;OhpOy-NsZXz$_)Gs(vvuRy@WIW7Jm5R%f%d zw7r`Ka?bF0QqbW~?4QN5j{XiSF#&>|Zg!lX-R!XjtDaw6PBNz^=}cwQw&hMSx}Lw@ zUr=v|*EvEAe274&EiukpH7;afrX!Rlq=Kj;!<~jq%7)%WxtM!~gC8Ctrs!nlf7;&I z8{d%#!_UfL1^8_M+D@%ouJr+oM0@N%Y{(mCezh+LmhiD)FBs#pq^YK}?pd?eLteW$ zYk7Q?<=r_Pc4Xdty^^Z<(id<)dENese`cTP?37*O3lL~Y%o;&sradf})Cec=E_^ik zCWW)<$GF_wqPPZ?Fk%_yN3n?QatmdG$1L?Stu$*&6`H7d*UD{vP-ccnnW5L()(RAJ zy-5)yuA>C&sHv=_EbUcmtKIy-P!6`e@SeOuRFJ-#zH1U&vHS7Spw7{_dxl%Eo$wsr z6Y%GcCn+^fBPDWA#+|AKC+;+tLCiFlB~PhfHT`%8kzUm8;s`Vf3(?V{cnS&=cwG=R zF@~%<5O_NF<<97bo({s=|HIii2Ims>**>;y+qP}nHco8Ywr$(C?d0Udc21m|nYozv z&RcipPE|iu{bld|^50K&*ZQrsQqiXDnOUK8v9(fl0?{>UVo_W6Pg^8iw>E4GIGZA5 z*S*4ZhjGEHqb^Ib3F{Ez2#}pv>_xK5rpP5?L_;ei$ZKhU>1AkHGy%#tga}vJ5c|ny zoTl|W`l{SM;FIPiz9*BN#*S{H^}D)98NUwaSS~r5fNWv~`IhUq`pt@ZXz-cAc(btu zm4&8oR)7_Bn??gOr=>!btm0gpM5 zlytmWGzcbMGYLKAR!*)wKWlkiO>KnS6p*(vmlyazNyyCyv^D+0 z3h*sXf|6-Qfh|!g;Lb5hDe1ITzrDD-p)f&TiL+cXnS=&>LGU==)o;Rg3Ioe{^nR?l zY`RQpRBDvQn0Zu+Ry!R-ze2e~nI0V|m}os)wuYIS;Z-A8Z>M z;4khe<@-HQ&uD%X#oW}|q16=ir1gDEwVJx#02680%utCSGH`==5NrQn_r167NVQJ0 zQR>Kiwl$+V>kP9{LsqssdVVVc5|brBF~Y~M(nBm*et$i>&s~kD?QSVB+XnjIh;!2` z%SS6mYnB(zE^nQITtO}E1KSElEz2{tS<32q>WX7?RoPzR6KG^9VyKyprNi04#oLC3 zqR1AO{!&0Ff_4Y`)jqDm`oHs>dmH9H?se~!L|z7Xfw$IhG`-%|?dfelxm{mfnu{xr zX7RAu*7%$rsr4&r%@mw28dJH`R8d!QIo$ueLXAftj<*qWzAN&XY5o)JKbwksc*aq2GA*W%Wpm*X7*7g#~P4dyr_VqE*7Z+S_ z$Xd|kKsK^~sa&%>-2`31nEeE+)mC6cv7HpXr$oYnB$pLP8 z!feS2llgU_vdP5)Zr3i=Mex1!leD|#pK9^f-z;<{Y&UANuF@9lt}}geHJ@iEd~?*I z_qxgIXO}6fEa8$)KlLrna<#Y>SG>x_wF+BYtCc#%EzpscH{hR50#Ws?qDI1y3j*?o z=N{JXT1Q7my!ROTm`F%Vf+<9*yQ$CXPH^`bZU~hmcZtbHhUFL)>TJ>5pfAAo*~mq} zhe_y3MEFpS4uX94pM%6|K1I~;;Xu;PaB1|aIj%=TzvQPn; z zVa7tw&tKsKD)g#mXu#k>^%k1&>goMz>laDdP~C<#G^!{gTn#@@=T7p%O7 zMM#p1SpuCEWWo)s2?#|<84Zr!kpb{h0S)peCZ!qm!r>kq2=LH`-$(#(BH{c|`8i}s zO7hE@=w3b>Byff!{82!z1QIc1fd*8Q6DzqC(0+%QFdf4~8o*;b!ix=;lSmBbeJNmY zOG9VlzF;eH@TyD|5kunwj!U;_#@&9PBAQ1UQqTQl} zF9Ye*kV7PzZ-VGTkOQ)i4q_-lRYXE{Cj&;|TV^#HsXPUi>TU{JDWZclz z*0@{UAKdGh53IDVok?!?NB3+!`n{`tU0vQBI`Zg_ZQGolD>^suKBU!-E+6l*s;ML3 zl3u$`71bk0&xl64vNBs%XIyIC9J)O*>b}V%C*+(efr_9T2Y2t<)?K-kYF-tS0r&%dwJ6R}c(eDDdV25R>2Iby(bX+Ya`Vv9I~b;vVQ-V(1*3u( z)89%4o~V72G7=fHn}JIttWfp4mK7nRct&8ej|;hSy1kCHi#TfUY)g3*m#9?asb#iE zA^M|ShYyabj#?n!W4fa8dL%=oZRi|Iv{oLaCBu)~al|CwW3N*Rp~@sG0lgE8MNTMC zNV;+11SO<8@*x-~ zN+BQ~IMM~OM1-UWtY$b5%!Bt;fu{wB8p;ySZLTG`inv8FoRNEh^Djng5w`wuVTFMS z4#GDASzzWT@-#>I;x&uxbHg$DItK=myNnt{s$Ug@@9`M-G~kdJong2OYk| z5p={FNd=NKo|nPK(~8X~vlOqEsnK_b_uYz##K0S`@u-YM}B7j zh>3Kv33gP0;}TVCrj*c*m{OIpkH$|Yyo9sN61k%b3lm5az40THBRO2j(o*9<%}+kR zj%F_dIpKfGR)3S;e;nJGGlZ$2d2rFsV~A5!aU0NpC43U-Lp0)5(hIeiHYzUQ7CRM2 zTKj87EW$u5@P0b0$!IGRRhuNGyrCB1iJiT*XWm7IU|6IqLxfqVQD}TnEm7tmJsDZW zLK7U7VIrxwl(8UKj<}H~iFEoU!_-brCQ@N>HnIuiNuH7qk%E85ryy2}7BW-% zz7?RVJ-F*_jzxnu{*CxXx&$Siix`0+Hz9%BW2|SA_?&h}&W9k$wDw`3Uf4*E(blf7 z^qPRrg;k=3A{S->4|JZBrea3qN{yi?;b$bJMzsg03|p-}jdu+mWk$W2{*oQEx}g1~ zvBZIGv9n)cX39^|DNI$RT;%7qOnHoAe{dF^T575bwt#R%d|yCQ>?+J(lc9)OkZ#H- z&=&zq?Sn+t8Wfy&u58lyz)`I>p%VPD?CS4{qr_`l(zR4pizHwitrjW+(`c<28h}j= z$jM3K!cI~)UivH*+Hi>#-xFJw4$7+JbJm$N$r=J%k_g=vVIG~!*p2lL;bV3_78Vf# zGJf#5jie&-q@3Qlqcu43Yx5go$A_>pO&K-jg|0$X9#fHrG#jkZC^yHY;vq^y@dXQn z7DzWu2qix^(OtA@9Rq+fkgPnGw9%?uph3`MPUcNLgF%bV_p^md4X=yNo8lj!JWD+U4XhO zT`vLGZ{%d_CY_+>k;jKj6<;({v27L|bZ5qjBLlZsNg1;jv&tLIX@l{j+>5PZ*Utl0 z(rT^56{SNkc*!k3xYMX|lw;-;_m($bOokIZ<^A>Xee7Foq?5Ih&m~UcykkAj%!<`f ziF;=pme;5Z+mo*u?>Y&O>m-m7@7f73T@$>=6~ng7!C@YgNnh0Mz|#UbW~V&uT*=w} zch>3dPbVF_{Cn{arMr_KRqav;yBvz#>`_r1c77eWAm`4d%Gp>5E9O}szlj^ZEr#l4 zr*Tx|6;@5$OOg9#z+>!EsZM9bc%+H`$dm8a!gT?#LsuF1VqYSY(8_&vLbaj{eiUv& z#+B*;j;+esO!%1~$Epah>RL4nsY&;)LS907MbCEi1j>Rnl! zLPX-edFE;40*kB4bD>rwvx!OjM3okaAN=iNIi(lbhrG)(aubAz9}@%oSoT=zSQcb; zDs`erKXQ`K@n@ zlTs;HMKij)b6__$Z{cB4l##7+hpID`N8O=_Ia-%33US1xR{gn()1+WWR;17d;qW&M z6e$qgQx|Pilg#6emGjnO!*!{qD>3!OnVz!}C3s8=`^+F!r(c)KoL3VQ4eFR4D}UEg zuIv$eOPrD;eyJ-(r&4Q~Sbfg1a@lzS`^+f#g{oB=@+>R=XAg17#q)9!_xp2tM~c}V ze~o4f+dEml%03(wb_Q7*rs{cK?%e#VA+x-^B`!ja_ zU*{vbbeTP=Zq53Fc~h|4`MNh@_hw({EaTImjbsK-`;YEt{b<14xH zvp$4_$8Pm%n1$BjT^Wd8LDkggJ@zYg2cw_Yclby_s44Kfy!^Y^s=f-LWJAZiYV{{F zh4a6fp~!>&_iHud&E@8eaTeC1OE(3;*#z*fU4eaVPfoBRhi*09MpxVM)1d|;54L!e)* zabG;JzqS-VvSIyL{pVu-n9rd(&0Y7KN8P3UTqfSf89>+5svk0de4md++m@Jlz7ale z%VO7O;&)5$>&o&gj%93rlwF@Iw7iu@^_%yRNna)!;I1Vx`8~egE}kzg*U@pdHNd|D zf${wYM{)N8^6K};Oh4Gw?;5IJ9+iM9$>5No88<=}Bo@@tgMLB3wx?*5 z((9Z3PMvb!(B-nr0Ng7Xs-b0WUsc?8EQ__y2+)3Ra67-vac%Xmq+HvMP78FBmUdW5 zRI0Uv)oWazrllN-nptlxPi_LeB}&&*iNwa1x{dO{;w0U% z+0hP$$7+46lW%56S<7}%xnWj28A|<1s&fQ2J;c!mqCU;!gv#u|$unun11@sBerv;= z%i5Hl1q$EDe!r1nN@i!qm|O9plBzzQlJN`k&XQN#YLt1^0J^*>`cI;njos*o45zv` zD*8tKgvEi3dIO?a44aO{dOzy*0N5!e+ixHRWrf(MP9Zt{SeFnD=mU=qPr5pU6G{jt zK*L(R6Qtl*8@RN&BMXOFkI^rlsUzcSo}f!p8t%x3Qvac&+ZfFGfn;Nq;EV^E-~EVY z1K(%pZ_t~$4|^EN+W7xW!TMj$PPQL++W%1<|EtbU@qd#~MNF*>)m)Sf?VM!o?f%i= z$qMza&DBCe_U_uWEI$r8TIQd$bM_xWijjeZ@gEh`|KsoE{Aui^{};X1)Xw=wbY=e8 z<=^`|S$=wj|EYfZAL^)o8i4z{Gz!`C0952R1Qz}R7z7T%p z3fusrOM;ak8vW}XD5+HmJ)e2H$D+Nyw5M6i_)AVQ+jC#*N|Q=P}#FME3OpUrA^}<6xl+aS!qpW z5aHV6&vS-+f1>r)AvkgOaaJu-v3DSqchq`}^5k2CvAHffc`3t`o?|B_DUxT+r_=ryu@aMBw zU~}_`^y3{~wvz8K8Bg-u%Qdp07mDX3GKN`_L-)QLN5#~&_I|fT^!}6CVf+7dTmC1bX3Vf&!#O1Ta8i$YB|PVgUmgf-Ixuk|`R-7MZJ9 z*2q~{*0xz%S7#m!B(gTmHDkw&ma_6*v13b1dxyo4cC&4(yTHJiQ%g=?5Bzg; z?dEkY&suv&pL7@6UeTfNz!Gt-gn`?=c=maZ*Y^6t5Cb8!y|9XmH*+U$g73KPdZ(us zmmZ&=J$>TgIR2bn++FN0AHQ}>R3Yw^5hsOo0qgc&UfRqENQCfbE&~JJi?6Is>jHf3 z)a9KI>c3pz-t_%_t=+~?R(!V_(ck*YKJjiwd*L}z1;@cy;@2;(AUPV*_F#SBbyj=| zB%DdVT7u_=CiO3&!QXt@-9O{z{Qyncp^P#39_8U>QLmhW(N)etV${mySukYHq!U>= zNm*%mnW?>`VlA4u9dkThm7(nfzw^Ef!Cm`pF?yiZ6x%}=2-;9{2D@${F}S0}3=U}@ zonGvYY%L&g{qd#)T}DoUxCU44#I!qREYht-!W6(gbNHc)>WTzkcz}oro%ubnd1G9Q zd@M+}<@57^NFgy1#@gYEthZ?%0p~d;XN0pl;C?saUyc1OdY~92-sf2zymafZ6u7Vy zq1~d(Mt@f1-1pUcp|%PmhcJacQB`XJ?i*?5jMncj(ZL-*9^f9QYRq-J1wN#=2yaSY zwV?GB=7L=3Jz)lBI}h9ge1;2Pz${utYy z(jL)o-hk3g>MWF`#S?}dLt>8@Dk_4l@h+Wrl^N#}%Z40tFFV+g_k6J{u(lMga=*Mf zrwXxp%A~@uwhAG;8eoW4S4SnPH%)6!yFr2zELA9iY0K>kS3!3ORG7Off0^!}ZX;Ui zpgyUUk!RYPmdn~$9VtqHn85Ln->hQuerc<(1aK(A7tGE@l>>~yS^iBowOp`j6BD0l zVk0Ymxa{4?X)fieW+vuoCDq6}VZ??B8{wHlCRjtjD7su4QR-Bep?tC(8F`XR$;s|^ zoq}}a#pN2Wgi9w&MatF^qZ>;CuG6Z?=8AX)E_ zu|`ISmXo>(OmZ>bmmD&jlgvbB4O5liGK2b<(@8*Q>Bw4LX0fH}2ep)Q!>S+3Rc9Mw zvgV_sm6TLP7t}9d`)y(^WjQgedFaKur}sLWx4P5twiw$w^fVg+&-NEDhudqQ7JT)i zzJjIi_s*Ul>PhqaW|^#4tGAi9_JOvpzNh;aQ1Bhi_>8$KCk14UEBaJ^#j*rLX0&AB zgb9tfSc+wusYDC)fK3BY5g(?2jorpcnVpvuzOQW>oijngSVGiv9{Bm}A-S9|a# z$p>~1z&jhaS>bNzicCyK6Gg91mDY~ym^P=q_cyoJjP_!NjW_I#({%GP4QKt+S9K`S zy^N~HPK$Jj9Icrhq*56b zRZfSuEr^W6it`E#aVn?TRJ*SXuc-7B?4IrO0r&%>-c_zFmF@giRWFVRNT5nf(|9JQ78jklD&W6}@rsrvRqnVX`yeWvW&fZT)YEB(8N_@Z}m zTk_p`rxG#g z>ZIx=%>``Rqb;Z)iU{Bx1_NZxkoJEHCl-=rL7nH;=dS1xnyNV`I4LtKUL}I_Q5_r{ z9i%X+hN2dXx(Qd>vFb)01xU4(l^t(U{IkI0AIxO|HOy0I#^lAHrn0W3wA9sN3uZA#a-b2If3E>)VZ0-)(Z64sGY{&=`>u0_4Q>ZM5i zh9JXfywBzuaK658nJUv1>vFu3@-82t3vW{bnuy_O|48V-Z;RPx8{{r&TEsb{Sx2@a z_Jv$$2KL$5DNji%(Gmx7ABMyr28Q)3_X{UeWWXe>OGJTYnWiBm(JD{g95~D=vgEwM2)31-Fh+&8gSL;pZ_GLA(b3$|~M{1;0nW3)xYG z@9jo-R(V@q&!BdXZJEc z(#zL=&Gq1UaP{Qpet1Zaowlk^lvZ4{7`D}RfXZR`{tVprx`JNfce7Ey|EDTwy`HaA zF}5HL(5dehLrUDojvZ}raVb7NH@DRIw(2nufNmCgVq(>?DqotcOMz;)Xe%W>Gch4I z)utp%3y8$L9@d=AJe}aCbTN5~$KX1Hnv}hCn?v1zdrS7-9!c=wmc6N%8(gKbGnT!P z-sc?~G86F38!eYj-(BWyV*V*eSxOl#l^1Cqx> zSXd`Kn5E!RL5zYq8Fg}Xu^dPGm;0YD@Y(#<7<*rF)eoPAnYzyQuix}s^q(FFo2BZW zaypCW;&kOI@A#Iy*vEJi&gpE|-ky6;LrbN)Z!>_G=b8=oJ?K{fTn?cwf74E;&Dc5t z*gP@4N1{8oo0f$F$pB}8f|VgNK^OoS&+`jVSu%qiQG=nGkn;@7%;L1lM5%VGSJPQn zL7+LltDIjX z`+O7hog5B&Q6yq)QXUswPb65 zH*@0#?p)Kfm5^R|&`wURSd?jiL66UF^FE{4*7DM>WE3i%31;zR@h)X#8!Z!sQHftP zZz{&Jjfg@gIi<;}M@>5qu{Yu7UA^72$2@fSy%}7uAXPGo{x*xCoMk++(D#(NvHWCo zjL8K9ZvTCdYn#j31sj)vnUDDpC}|7IbS?FjYD&#TJE0wC(?EinLiZ%I9{YENPVc+8L3lKd8Wzw5a6-~-hNf}wuCml>wEU5X4mEBbKZR)(5JIES*OYD zHlTES;}IWNC!kvs5DCm9NPYU)DIzE@jNqg}`wNF|%}+9`9{Nhrp{rS#M?Q%h+C;bz zZINX)iVIja=wx<&kwSGMNWC_>p2q1Rcm_&A%l(fMN0amKz1%_G4dR}S_LHnd{M-3o z`wV?%#qJj2G>25*gWkUbn*;qq^nqKpdagymu*EqzEw>={XR%5>eYySPpBQj=92D;0D0W?GkN~1&CpIIbx8J1AF3u>m$Vc33K_V(G^-< z=CgUz>z8o);S+d0IOYV6*@er9H$2GJ<0CB;Z4D!J%_ereheBD@Mr6xRHZSG=^c#1@ zHxf?=b~7JG(I6X|TVSBWna{lEen%WUMWyz-w)xHFrQOhUySSQ*Kh&PJ&0cRgeWIqg zmNz`jBndBa_h4T?(^y*TJ@PIrYm{c|5 zl4~z5wMVP8m(9-*L1J~t%^DVLiF;Iv27%#b4n+GKn=f7;l2}J7nl_YHCN|Yj;pPKq zzA&|vYeuY5CploOeVLWmc#~3HR(pS={_L*y@fJd8bFo|B0P2n128{9U zz_=_na(#F=S&s80^f>d_Nz(ajw%0{Pjg;oo}^ zPoa4W7ZO2uaS#sX#KVTBKpm)x=7SQ2j$Ikep$@|M@V^+y`}GM{i&gpCjK)PP{!U8F zC>qK~L4dOFq)C%G?cHueVDXTDVgsPS7Z^Fr;jY|$6>{o3JuVoxj!(WV*VUYO+`su? z`J}3F%~iF09v=4g*?hcjCA$75cs-~uVZ0$c2e%A*l)EVHSM#7MEJIROP-4M!saaV` zb&Qtj$9hk6vebYjnD|su?W9L4FD84&STZyecH~;d@ekfNw_tqR#!HJ3~F=FKJqLaG%PB(5pXK?~MZw{sS+b8y|b=ey2@9Adw2t z*bD2M8@$?iQVx{@Y4uxYDswSa|G<5@#DF)TA|2+O3E z5SuGNpS8g#OBYI)7VR&drg6O8{>rfCe=cr1d@qRaNc*Jmb(PJ2qh%~Ry2V^vLl2ji zIBR|Yq`WIluDU9o1=L%RVC3jpeqBON$Yvk3{y02F78Wg38`MjA$O>k$u|J8}LCH3d za8Xa@FoA~g3#y|d)-emz(&CDfG`^eJt!?M}S7kI?*w4F=^wf;&AtjpuxaE|r@k1yM zE2HR6eC+tJcM80h6lL0(NB-$5XMn&`?c&+dMeu7F7aZ?ad-3xh-Yf1)%(;U*A5Kgh;cz&PUYUH1x#{}34? z9zzIr8_-N<3`T7Hnj1e{+|Rb7p$e88pj{eQLC;aoHAQLC#R4fCab}?y3{V6ncU-tv z*w6hVq^j0BHI9DfA{uM-%tWHfNvp?4j6W!QQkQwe4#$36Gg0C0CVWJ!QC`~AnI2cQF$M%rqqV4&>@%_W#`v*)5MUmtd*d2I0bC6id`Z|SCOVTtQ z$@<6^U!N%Eu*AHC8(!LtFYIJtkGt6Bt9luj&%hhZc8KRsq`on|aoK^1Hm2Y6fl)TFCIvPP;7mGZF0BEev>@^55N;3CDe9qx(>820K8Q#<}N*?0xUQ;XI+$3>M zNzl}6XH>5fCo{MmyfKBe*@YL@xs2v1fq1IY`~t28EHEBD4-!tZjd5z)zVq*gJ=?;A z*^LVZ&h6Wm#=yveqpQ6t#}(NIZalB{$}LSVL#W+8voE0Rm%k}>p>KXV6&mH1uhGD} zxAduge}k6-+;GAAjGh1=sz^5K#7uTh{QYi>-_L;Ba>~pph31rww6N+RyX8gYZ!U8v z7mZr*wxxZ^m47;}jE+8;sBhF0U)j#g(|&c>9+I>1oZz0BBedh&^Li%l)f&KgxAdzE zH0@v_$V>G5w<*jnf{@>0(1d}aUSc{%=I=WTBZ_GLdFo3hxvsV)A;|td{ZN$Z0=$&; zJ4**L4=phpNHmG~TuuR?PD-S?1ns<6lCY1g3Qo+2IA~Z+!(%u&;-r|eDI|miSw4TP z#;I>Qd$g3UR5F?(otLG`hYW!a-q7HbjKViF>v)U6@p}@_wvv*!-{K9S49OVN=k=Y^ zb&1N;^?HM4W{^xLXbbvi!rwne|v^Y$6I+{)#<>{cI$TlKX4K^$uH$5Kyh|V+ zp0Hu{1aco3fbl-m`-`*-HoDKyAQ)5G6hNYtB^GriTLwzW(i#lXVgOu2*y_=urCO`{ zkS_24F|Ig#HuV>TSLtlbufAOeNtluFx|`z;Lu|{|750Q+yT1agraUX1(|-PG3ohC zlD=#mdzB{)jvBU1mhWY$tsVkuI@bjsuJ5CN{&>|||J~OjYB^TE_wD#LfR?*Bt+=hE zW1D(y&-Z-36RuV`^ZRy{n>P%9ukRby`rP>MM-SQzP6c7gH)IK}g5(A8w#0YSxK zGh_>>E6L8Uc%n)Vc~=}PJDtYIOP?=6@#A`D-*kJk7A^4ubm@Gxpoax)a{R&PURdm` ztgx@Ifch%c+U08t%dfTGnZHZxbiiJ{v-hf1UY>#Z!dxx>&OAB@qY~=1_jfc-uPFQ{o~hqVfX)(OMbkLCDlSd_gGa&JQB=^yBLXS^f*#nO~;O{Dgw{!Xr!;wY6; zyi%7}RIdm_hJn16E$?$kd&IUjmsM@A=u z!#1HQCG^as4T%yaI}D{lNHE+6(9BI`q+HMckOv9AR+=x`BRie2g;NVoW)rlu2wFTY z_>5mfi^s!N+oVbkjHR~4+V4}?e3X3wEy*eO0P)FhhP4QFMc>hMFUMG*yoyU<6Dzc9 zT0D*y{OeL8JMX;Xmdpl!1udm5VCfmNs79E!TiT2quiGbMdGXr-S7|ds(&G&S7x;YA zqljs_jS}bbGBQ%x2h?cd@vOw?oy@_I0V^UDco#2CW9fn#iMq3EM2w4?hz*P=;5O91 zPeL12<3e|V{;jjSCnq5M6c&8gpl*F_Zx{D5;!7cpeH}Y%>F_Ehd`hUNz|+0Gm!H8y z<0JYGHQ*Ns#yP5Vq}0?Qr!!QJB8P*icsaUBbl{=xf`z_^Lj(RO`y;xj(5In(J~7HQ z49XK&VbnSc72}GhjJAUn2?D|v@J>NMAkm%Ese18BEIk-uPoazljH>N^*_UO@H^ zl376n#puwUFM&ArZaEkinbN`)HjqKy0SI9vGdIvdz~3vF&(C7OzG>@-U`K|S6fg`O z!xj>c&vr=f0A3mhR&jxY1G{p+{{R=9Ob>^mPcb3DxPp2T7fjF19}J&`pHcwY_=1=&J8vJ(1z5`5 zU|&3nJlHSfi4rzsL;~RMza$8+Ea#74MTHxGR?IJga*kdQP%l3j1zm>0{oL0xz%YRR zBxFQ#j7a!;ZUNL!jvdEv3zAj}@h;Hwi$6!CT(jc69pA#+L@>Y_*Bb`Ga0=X2K$%8J z5U)^u8|4-7B@^rH&R6;Ip~DUXkpGpNXI_T(MMU!w+V7WLK`Y971H#oaP$7Y4y|avS zLoV4vz6a+HTwdtjQT)Yg0iam7H^-7zP;_?$8>I8Ov&&$72rm+t(<2i-doAmui`W_N zS-u7?LgXwelRIuA*EsfS+TXq7078bSxH@8jSq4G$>}rn`gsg+B0tJ5h?Q860Nh~x_ z+!_%g0q{XbK+S*v^-f&qLxXme>~RB5)(3XOUW;G3YKxJE`- zQ&Hs@u~GvYvmz^N4R9(Cm#eRzvJW$r){Jg}w-bbxl>(-Rk^eIAkSXYGiQJN|Q~Yq_MTo zEJM1wQbVnwz0)!qGN-hh84g^xzP+=yv!QU6l#NwIeRUq}x5ko&?wKJopqD^lYJ|3? z{+dcpHzt^YUNk6%i6pBrAe2gfpA;FUav$7si8IerOfI9MmQ`k@u92v*EHbL0qA_o{ z^c5s^dF+foIjdd{5q%3HZr1|00h(?Ng~m@X9W+Q*IR^VQ=uPGBDfFXgg+28EZJBtg z)X~S8ksdWU;II9W9)$LL4C_FCVUva&@!4Mo1EOsvX^Fm;ZvZ!;I}&nzU$B7Vfryz> z1bjj)889HkG>eAVmyne2dc#|=(*`T+G~;Qzb{c4y$WBHABW%OHzYtPkf`b$#$O_x= z#fApDQffG=ZB&z3^L5Ck@Zm(>49cMFAe`-~0y_*l^B5%qdlc-RC@Ps>ycg~@;9??k zqTBIN!V0S;mVK>y)OZkd&}ra=VmCFG*H+Z4Nu*RDMLqF1g9j3@ex^L7b5HR0ImTwngDx0 z8I+?c^IOm;s{M`QA*#Cacc86-Y(ml&&;z9Cz5fnmyXIpDdk|H_1M1Uzv1Q017YR|) z1ZnpCTA`+18+zzBpGEu5dQfMeC7y?8oRAh+Q{pHcS&C4MSfKb&$;GuvjW$*p$o_)` zsxrCnuLk2j{=nYmuxx}eX5&+2d&X?l2GHaOU;?V}3)@_B$i`S~64y@zw`k*)BiX+_m21U#L!gusFptJ$LF{Ulzb<*BD}I@5tC8Br~Yj+ADwO zl_3mKE`|yXo}oV8`GQhx%u*y18NqiQqRDqm=mYhH0m`MFs{33F5Jj{RbmgFDWS&}N z{dtLJ==f?7qrM>jEQs%J3SWd|DsS}SEKsF=cTi!>6zi1l;XjEVq7na@?T9lL9Q!!n z2GRb=%sEza#|&FIy|%e;namq=_hJG^N1EzQpvhlEWX#m>ogX#gts+<&7BgavQiPxT zJEgJt6Gm7)+r^?QY=hbC;_fA;-)fEgbRTP}Dg6jHK{53}uoPECA;;oVevKiwn`xMwLdT z4~_kpx2%}(?BT9_gL(KBW1-PIo-6(we%=_G;(T}9mA0N}Q6Z#+&!$%7L@DE|m&PNg zCe0WVRtj&W39pApYO>LJT$4xl+Q>8gr08fBe!2TbXS$d#8D)#QJq}h5L!8x8Np#48 zV|kiK++`OdUeaBJcd6VR=PdugQ1`SLd(!VE(u{F?COY<{g_8B2tQu%vDK&U%Op5-) ziwpsFHYCi4X^m}}T~Q#ZUg)3yeSoFOxz#QEM*7XM$K39~*|@9DXAb)$<1*JpzNOhe zd?@7BeMs<((l-8O16c%U0@#?dJyIfn2gG+rx@nrgM%9M5^iyA#h)bhPJrj0_BclP2 z74t6X8(rC__8%?zvse-LvkIt23DNC`{8-G0X}m_CFYn5uL{Vx8I>)Ty>l=-TM)-~w zE`E0@H>7vdPqw@rz8!pvjlP-GY^GpDP`w+CVJJx}upTJKo#%_cE(^~EY31kIn9Nxj z$OL=VBIZ{6>!C)gF?OlclRtLkh#EsTQ;v8pPg_i|VC`ou+6faC(Khm3(T2Rb2t?J^ zh}A@kvnp5{F=Jz1nKEcW|Fts3(^Z5do|!MZ8VOe`V(R14I5KPyUQ^UGk>q9In{_Ev zVU0GHX*8X;26>ZCE<+XQ3SB6=@4`@O)@3IDW-@Vw zTCMcTfl3rAwGjv98`U^FEB&kG7BS-s595wuO9kK)V<-KF#tbDj=2ek-sV;C|VUB~w zWR4;dWp1+}BgR3k!o*#%OL3wKqYNrkVo8=YLNUuCC(A=TddR3$pH;Xrb;b?|r^?WG zW46k!Mg0SP%Hw~cRN}mC{^;!B**k< zjeeO%o8$EA)AW>`NJ+?u5o?y}fXxm|=pYeV-xSJ3)&UQV*_hb~|HT+dR=7P)tkDCX z{B^wLh`W5V0qR4Umgrz9BMVei9avy-qO*M0elvs-)1gWaLEi;oIU=CFmrrBQguWZCIwa(53Nv&$Ow3 zOOceR(9?zb@#0+cUjQN^cyw?4I*dtFdf`oyVuiaui1;Jbm1k?6#i zJ_wc%e(hdCit%?A(Y1a0*0JwPp~#mc5jxGG8`5iyh;LI~cG`GH89MYyYkXVw;Tq}T zrQUt1$Zq_29n7IiL^oN2I_bT1#D@+M|CW$1RRS}TM@R6-A&G}2H0S4^ph3%sY`&R3 z_exp!JHh)uY+uW955dZ|hsjyr4tO5>CJncP;)f=ToP-G{(&P0hJZ)(_)CuPPC(OUF z@pv!rj`H+me4V%HKP>1uugUq7#~biXpvFkO!groyqjdny_qv`wuSKM$>Ri18XWIoBXC|i z)i?+e>Z~VxBY3D1e5j`fdui@lP#V>V^mn9ti4w%06Y2dJ72P$6^b^Mw#0wcn62eFt z#fjjhOxSrgXcOqk5_M}(2W#WTfjybl|Db?EmPI9r99qe>&Tonn_S|m-7Lue;XaBhG7 z`Iv){7}gi@?w@T-YX*k8ni%dnF8-Y|p4p`aZ7r9`y7kg^{R_&ihRm(wm7BCti>NBU z@0_G#NK$PuGDU5%l(;6}*c#Lluw5(LBqW1HdYCw&RIF*9BteW>lP&=)Vp+O)wp*dx znrMndsVjk|$0w>@g{aM*kQJ=agkF;-fhs~p%ES<|;uk#%6&m8-K%s%2c$)MZJXT0( zs0nZ64Dy5yqz+l4Bd5&Z`yP|o%ZkBlGA1vo4AO)QB+B>jX%0y#QYE4UZBiy(qLC$M zp@smISIK?)aA+<%>Wot2Hi_bXsZuGDJbIM-zll5%9I$7BO~Hp!!-R-kA~v_fuGEN5 z60;~l@dxC}FeKd4)Fx^1G_(_r4;h$hgv?PU8j_s~bj3HMmKAb@vP2b-ltPtB#S$c% zL~6*Afn}0N4gPOv5$OTd9)yfnq+$jZ$>9O%Ai`Xd$>DlLTBC42n^IVF_vlhBf$&;qhGg-NAp_Gri}1Oo^TL0jy(Y zNBlGR@qgtG{R9DVu>WszmhHb9JS6c?$ys?L8%qZl(;sHm#?ah}fbFNpM9kjK`G3;0 zOh5G~%s&MY>_24^oSf|c2+#ie_@VzNKKrxspVPDd3O)WK2KgV;hgcXm|1)|valo#K z0p(xYQLYMsuz_n(2umd68`E8vr@a9H$wjST9LI_L_mH$_jN(e{%WK|>8bhV;GSVG z&uHSizwZ4oIiaCciv9VTt0f1zhQG@s#k56>RW^rX&riEadg5-`r6q37m~I?P2TDD$BKU#zB_jj(C1l%wZCd-5`ULtm^Z~5<=mV{rxX&Nkte=Z` zNO`GmIM?%TtRwRa^?B{FEm8ABn&DGAyXs6|&EO3^vCJ=s`+P*->a1^w+u}`oVxE6Y z+w$$?kMK9pjlrqCLu!FvkQ?)3TYFJK-w0pm7wEOoslKGI$G17dC+)x756sN(p)JBp z^~JUd?0wm?uj~kg*O1N7@`hexb-%BDFL4w|`T7AwdQEBkvl;&Xj4%4nX7-;ly#K;# z|Igx-{|>+V@76&5yZiqR3;bVR{~wv*e?8X!5P!t>FGu4a56gdyKVth&{3|>KB9WEbrf457Tta-MvsioCOg91XNK>1O=1;0R1U+6EML5LOm8oT^Ao2 z*<>x)MVblQ84Y$_=0fKM6zZl`nwnOoi?pBKL(M+58Wg#?zuDYFQJP(OCx5^Fa_7G1 zINW}A&%Sx>?aOwmsx94(c(i~e8rM_O)X~ja(g;HEL?*PM)6_G6Qeypv+sq>(8BSB9 zuefwAz=Vhp!)Wr86cs*G?Ab&9<%d#`@ISiy3#cf&wtpBV1O*f%Bo&Zu7#L;-=`QJR z>F#b60qK@*6qE*$?(PQZRO#;gX3*+m4B=pKAZI2nOfvQvMN%lG28f-5$-KyV#MXHt+kx5J%2{nn3xbA zL3ihz#p6pFaUyFC-W!@Ox^j`c5qE;xP^z- z;6-S7S8MEBOo-x{hVFosisqqtm&X^p7?)9pchu(FWX2@G8qxNMT0DYkCvnPdXwwa3n$Zy9rMb zs^KH1UIz-$hHxScI%TG~JgN3E6MkLJvd^~miUlE^7#a1UdWe%aUUmmQ^n|`whYz^; zX`XLKcq+;9AuUg9d*Fm)*$vgOcvI4mokU%9in`R{Qx=k{$VU5gl6}HSiDl}n&lP{< zm$)K7L&~(278}B&>sNWNB7+{z9&kpyO%7M4m8|y~9SupoFa`}6Cos?CWhq}+idiRY zg)mQoNs~%v6shP^D&NZ=p25w+MhNkZ2&QOSXZj>RmFXc%X-!H!+l}qj|Sot2qFOGW&WnOTM&~5_pqa* zDok>HtD15`rEy=Hn{*Z5^5qVagYR#i4$t_?uk!0DklRYJ^W9 zuqsXnW=$`%K?hDgaS-%2LiTP~=BAlk&^gZZ9gkw&5Nr>~Z09v_2qQsZWzOo;OE?6& zFh4@&4HCNFN=k6?S-<>~^g}t#iL-6FPM7)%59iu&+Gc}b7U7t{+?=B!Z z3L*p8IGaok!qbAY`0l=v&F6-!x;k_=__=Tw@fuhR0i&NZ@u0W?CBiU3#}3pi@o`0t zIvXJEI$QQRqeeMp1J=wpcW&SsR3AU0jSuBgmUYZA*t}RIYFQ@j z=$MjtVBs{pyI4t}vP@U2f4W)1Lj(dgXIn9GgmXh^pjj*gU0QxiU8A`*Ho zeGtYMI?3r9e?^5vSmbz8ImDtJ+7VfrR>aGY0CY2Pcr|H&gG2GUv^{{tYG!}8MWfKe zdAWxkY!x9%Qt!N&70y(9vdDCfe#P9lrNxESJM>DQ0E4b6uI9z8*deF8L;9o!`A1pR zH~IS`V0Cfh&Op*E)P&kGwiV5h`#Up(jRZ{za_#0L80*3BNq~=L*}hZaTrTg~+PllU z!Er`&xZ(s!idT6szT<3)v5=4kAyITp=d=dz$=5zE3R3AXUn<|LR=gSY8EqU*A6*!Y z7#$ofR_q}x711Owh@8kB&z&$CH0Xeil(yV9fkv4VZ@L~w$zwlc8xA6NlTK_59EaPErRk@XskOQAfB zWH9i1$%2K2W2^ZM0bYIC(o>aYA3x~PN@enHP@Hzq>>}jg#Jg6m8qvE<_sSQ8`*7j> zfrgt*&(!*#hCztD6cukaKl8Dd@a;|Gm9+pcU0fpJ{~Z`$gw zv5QF_CK$Y8e?4~6>v_|?qm%C47H4x%7OfX9=^_?Gg*_8)_(=p=QeEE+ z20yvDt9rQ9vh$Gfls+n7QqEAC{y4onPdG^Ug>aP6B0l`Wg%@O+PfLdqf?NEA+Xz8g zkBUAosT_iMfQ zm@>9g&&8GFyrtdItaALA1M~PrOZ?E2p&=wBlxZBbf;;Mcr1bB3_l_5Mt|oO?Tf?yn zITZK;-uv4sNQ=Gb-Bcj9kZ@SeJ;n0g1X%OM_HL}c=(hjb15W1raMFIX0k+m|@FM4+ zetw=o!R5gl<%H=#M-lkI+U+3MdjA+u}0zw=6riCLEj^0 z2}<2rHxh$G|2}Wv5n3@F()lKoioR4YkCwP?SxCRO3;Oe`(jlvE(KE<=yfy1UNAgR= zd?r3k@Z!tOtF83qj&VZ<5wfpBi{cNfF6F85W&^QWJ^4(6PnERhpU?0`|xzI8Fz^Dv#YVUpXh9yhsJ zp>L&Wd_{Oew+?nn{uXi;_6)|#?b)rfDTUvXKGhLhqLV~krLKeG}_@(sHH zW9etTk4EAvBkodbYB$$PJvGjrC?qVJr-gH4koqL$p6PQu7+(A!*mQ}!`e~Z{nq6Cin#Ylcty*TYz ztRikHx|Zk*R*1vsu|vC$gs2`h^oO>3;uIIJey8_Mdm~-?!ph55fWc@+W|!LfYdLPA zy6aBx2*`5HE2r3VEh569d9?Ujbz?$s!`tJ#(FfC5TnTI z+(*;&u-@`W;Vv0upog?Q{}J9(HnVbLHzfSpJ7gw~uS7`r-n>9%Auj_oPQUpQ-nDAD zyN}L-UppMiqurTqs+a;KkUotMnbTenRWd5)n2uO$c}yA6Bqmkau2~i!vPK^(w{LH3uob9a~U8lJF`=x8P&s zMgg&O6PrYg&SgJI*hO)yQ7#zaE2JXo^KZf(^kjS&Y>3|bgmsn#NB?=m@OB0o?r7T8 zrUelj{F=C1=7)+SmEejkZgK{*=I9wGyyh*YcH&&XL!ris_-9Aq<|U+ArrLyRabJ5f z!Dw@~v=Kw_3Q<*0PmHmswnthc;@-|xIN6JKgTu<+c&s3S6%pUc6E z_3-D~c)2}SKNrYZ2lhd23kn}6zev8Dn^y*sXc#5vSDt?tm@KJvb# zloaBNI(>YdC4uW7_@+r>ZQJ*2^lJhZ8a8V!GNhGQr|K8XTDxSa_xAMAwJAUm+%p&f zUyk(h7(S7e-+7&zFivs!_3XLQLeIKw(Ah7WRP@R zki6~32nqQ%MOr0krFS0{*gs4uY7uw0xC*3#WGWsqwxap@P5D*NntqmcW{0g@ zE6gg~DvTdHfifdn zUu;9x^dINf-5poXkgegzRUZ_=45!8gYU>Rp6H(#kW{SWuN$0;K9~i_O_WPWKmyLN< zz62c1GC6G6#C8oSRh!}O#zp535~bNZsoi0F$w+m{V==HHem@bK})Yz03?MF%nq$ZsK2OBboI!`dLz-;3!cX6fH z4NnX!reBe93l+j|3Ce!prtO@Tp`Hddi8QdJ7=)6FO%(EPohtR2du{PBe>o&90Jiep z^E0I+X~I+Ur829d)bRFU+pDIWOzAnMsp2)DG}5M}$5^Js-Jufrn%k;n5}L5kkL+m} zixf~&?W0+Cv%6W^E*|}v!Snd8yYh0c`$x?KBajnM?bXr*qoWji-@N9`IM99LM8@I) z>SXoC#d|f)fcd)|rCKB?NK;2a1gf1hKy{bf?`QaV&OFrcw*u^e3TU3xqG9aV<2)USYg4l_V^e_?GmX zkXAa64f?gI3H;~>;ua@r+U^E;#=`q_&1H`m_eG?3F;T`*$cBOmWAnWpT4Rm&lHH4` zf&>Xg&}3{PSY>%vhsmVnt=DPWN(Ze!>aqumE*v>f24_sK8aG!!!VdUFy#kIqgi3M z$6(QWMMqThz%+!)s>j=M z;`QntJT89z=w9kgSM!c1@`{e42eQIZBsFP-HL#EnI;R(MWOfZ zm1{li)K1W2j!$=`7zRnKJJvGBzY zvtV_xZrb`<aPIi*N;3(# z^zEM03aO2^eB&B0L)VFy;EfRD9P9pguGlNDm~Oogu=`AM4Z~(wg<3~^h#-09a~_Xn zT?lBgWwiq=ee(vFW0xVBKYSSEX0^k}^+=|{(cBM5v|@xk!k?#myw!xL(}@h&(l~L) z1)B}4}jJa%n&FFq!j>K z>_p)xIeAtJ+Dz&_-(-)QA=r?j$lf(;Jc`a(UrYo*5<=v{NAPQvc89QNkUYppQ;?mJ zu-JtAnvolYTIWPpL!TU;_bhxKYd#^ZUQI1}Gtk!{AXSdH+c3b$OP^>Gjw-;YE*0!b zZZ&jGJCluudLoC0#j1Mw?)9J?p#h*nlt#imRi&ZJbDOJ5$GHoR(#S9{D5tyyP`|U` z+b6Sqah}$oRpG>$;;(bPbm6%1nOo3$ki_JzP4&rAH)F#rMa;1HSl+h%rst8Ll+5{g znkBbA?&)Ti#;8dlH*PITk6JNl2}!3$Bw;e4d`{Uzdf$5#n0XQLWNNZO5-l4Dl$2~& znVA>GmYCl*EO(YsYd4F4uaK%GbTtOn=GvO0HRs-?yPqwnG|L8YlhNRxMK8P^apYDg5TlIZaKPd4$QLLl^D%`~2+Z-O&&F zMbb{_H}rE=cIWqJUTJOa(wg>85==jkHs*p5*tIcnzk7rXS7E&X=65^j}4OLP_z!n7AbKw+R&DpS;Jey|GloERf^g zqTGciuu8uq{Q=kG#zfJQgx#VwVgXKX&|E+y8WBDb(M{nn0+Aen;jT!iSkQ4)z*;0% zGaizA+qx&Y$f{^N6~FZKh+#IZR(l@mTCx0u>-d;s#s-~9brSjILUWJj=-0A#=g_oX zv%PD3vb1Yo)XzozCpV8W!U>25i{OoThl-6ROUupU7&S&ti!HU96n5$_6t8^+(Ru8A zwOdDuU7rivd8~Ku9ojx4nGaX!pT!{?=ea(en&-NPTm{gxFHdKQHuNRNSLb1y9mSE- zaW8CCJf(Tq;7hdUd&+#+o+Bo^ZvY_NH+azFG!{W!X5iZJ_6^Pbyk>)fJr4{I)&5N$ zyCqXLU7|iN$K&-iTjPNhcDJyd2a8rEFIVO6twb5+W7kFUTRdRRQr4nj6$&7%T1wjy z=NK^aYG>$mIwsFb=y+mdgh;Xw`-P>B)_TtKx|%=|>)^A&_v_CrT>z;a6)>+k_7E>v z*CJCnbxn?*1jg2^`6WM%HwT#8XikHb*TlK5753FKS1ZIV@PwmS2)TqQ$g~1VlGc?^ph9m=o>O_#9n68{qmBHKaxp3L^Q`&qX7epM` zA@T5)#nQcM>^Q0s-}1v3tW57Xqiwwy`|+4lAXTULXMKqJ8F*YXSMFP-6ZKbK$vjhR z>%~oxKAOSyPtM5^gERqL`SvwQng$~gNYcyhtU_L**T&i@4uU{@}k4f z^dnf&H{Sgi(YDR_xrZ5bYZXbXtV;+vE5I6ZY(t9aWibIlNNc;OKlAU8^i1+vHC?LZ zX_#8ZIpm3J!KE!Jj;_FDK%gol(0IF^TPLKk6B+m6qK*@+S*&xTf2l<89jd(Nz z$dIZLOM(Cn-^Vy#|Hy)gRRob7kNvV zd$%O{e7AzPK)OT#=VOny`_JdvzkT%y84nKj88_Zicn3#w+6G7V@e2k8IRX`Y1jahT zi);{IR@^jQM>>;sxna0qQ_i z<=7>=F}s=cC?$NGp>xxY;H>h4RyB3@l_0{Ws3t?jS8TTMj*DSvvV*k_@XoRmNiL8u zT)d;}tO~>i0R_Jg0;F30B#voU!yhsyuZSBJ-5nz4u&@fAe(U48P813D&H|f09yZBrPH$Hi? zgbLj){{kr@73pq)KdLZR;)Qq6<+m>z_qhvYEI)Gc?>iAVBk)ew79^}=5B1`#&4imTwKb`-dHVc=*5mZD*z_`1yQzR^xVH*-X*e9=zVJlZ z!U?eUe2@{_T)8W$2kKVbD^XF$V7VYjr_T*fXYlR=1vl6@zm?@6LMkt5NzWo zS?oH2!EQmF*BS+>p7$Gt!=;X&Kj9P`Gf|^_H-ex}*eGsvt%52GVnv7v4e@~|BB1uN zB43^wur{FK#7}(?TCbibmxJlJNb@)VrHMlEev|fLYWsU;Q z4Rk|d7^w5G#%RxO}WE4mRCieBK%I zDm@D1rk-Bw^Bo|0cJIFC)9e$cD5(l{zu~!*AWiGa6OwX^@bF@8D$^{~a+6WHQonSX zd_?2%ce(Zm^A5$r@!1qa^GyChwp^a*-y2?b9M;ZJjemD|zRcOtd3BA!>5X>B8$C9Y zjw@G~XijhRn!hz^NV%k~VY0FX*OXtdj!emp=2#cKu7=3NP3P*sZ+~2d%PEd)#)=g1 zrW93z5xA=au?uwFS6NP=Zg7e`_CWKRaGr8L+E$D4%XDCssa(v27`E6?LHf4=xuE;wfN6c^`3)0CLO z{fb?hbso;c)~8cQYxMIW`ZVOcI>6Nkf5S3kKl3^*a-)t*M549t^97Jt_nn@$fm)lD zgc@g~k|#ByA#;c8akGa+c}E4Wda|K_&E6BUae|aQeFCf507045K zXPEFhbU*MFGezAc+N5q~al@vYtN9uG`AKHdp}d;;S?K<(Va(E^aASKVYks}9gW!60 zn+uq6P8?$^J$NsAvj*||c598hPF4WiLEIXH-kpiBND2E8_xRVvpXEZQ150{#AsiVz zrsE%wLKhgjk+ZYgwY0WXyj}bvhjj4OB(|>sa_n`+M)r>XPIlt z%U#aS1ySDKNPG4Rj-&&csVYJl5a6U0+Gy5Wld3k>(zY3kNz5w?k94n2E!>8uxYnU< z%oI_owdBpq{Q0w*g&tas0()QclZg(I-}fDaiOshQE3Q0T-6PmVkCXkZJDs%wwsMcD zFFB61p65B)A~#QRR&YCGy|O(CVSj*;uU1#88*20MYes<6C!m#EKF!kZy5RTzC+eOM zvZbS0Yt8FRhYi!((`%iZ^Xt3gl>_&Q5xL(WBnk}89xu|2A`^pIXyWg@{sKLZ5uBL1 zXSQdFD;Mk&q7HA)2p=iJN)htG>|}4byC$(WzNl_(uj}%Q+&T0J6|3w}N_YK-)5r3P zv3S}RoEnCWmD(aEYZn!OWrz<10l#*5Ce*|n}K7-8m;ZgLRHhJ5;B`rA{DmH>7&5AcOW zo0R{(V7ZupTz!h{XhDx`UFA1cbdo+`xi+GKyV(wRDfnEG*GTZSX7W(9dRGeT-2^8Y z09882O;pl+z!fi2hI+OE2A0NFBoK%elOcZVolw$gFfZMr%~;V#UfR4OuARnrIe47? zF}2t2H64#3)-prAIr}&JO|e-5$bFQKVP}&4i`1>_NM(;J!j>cDH+Ng2hmkHtT-*<^ zMepBS<`|${FTa6A&OPzc``+JR!l%i5om;z1A4eF#iU#V=eMsxrA-bfrU#f}vxO9@e zxo4FUGw0!eRokI&V&>Z22bW43uQ!*!IUVRpRUXrEmnty5BYMPJ6Nvj}aS1gwj$%si zVn0fH=gCuQU+LF-`39&f)Y0ejJdaPe*BdJy>@BRI1iedsurXmh^~viB`Kika`u8>Z z8y7_R=s0aGk>b&nW>J!39z_UVcpKGbc*g*f#rdNDMKXVUjeZ9SZ&KAD=htVbD)x2* z1?zR=Hzf4MU`2!Dd74}T85}Rt?2p;Hh}Xf$A;>qndynY^lZL1i1D_2&9Ss`Kirusn zt;9`_mPJby!h6yB?36q3ss784X`bU*@`E*fxkOq*JLE)j{?hg|n+-%StTKt!yKEXB z^a;2}J`mBt38A^uUNY$}M{Ct`vP6H%py*n&%k_y+WFDRn^?z1K|ANek980txOI!NwS36$*y?xKj33a{uwfA&nvgf$->GOTDCI?AvWHy3Hu z`EtMG;|ryrb;BdbQS^Eodn94adx3+}Z`SHMTZmKK)v8*tR%zP}hZ*N>=h)iU+6T4A zL>>Ui1LLrdB{mYtS$LgwS&CrC(Fif2z}p<%RP=!Uz0ErA9F2*9ad01u)^+>bKS$Bv4)Cv#PjAw!IIVc@H~ zBH*myW6R{6#OGa5!zkdMQp5O^+eXc_r_;x&X4*pZEPVSjx}J4T&DOg~e;&Jv2PU6B zqn4bVr-#zI^5p1l0AqhR`O$$WGb zLtEEa%^rcH#&4YU>{ngx2BeN~^2a z_iSy^S9P>WG&VjK(b~SPHhT-v&r5bx^S~DjjvN<_a#SrCG1c14w<*9UHowAn^JdKK zf*R4TO&Q6KWaAUL_nu7N6|ZsW(dXD6cwuubsgf2oHO;c#b-KDILCQ%x`5zdHzCM0E zWY|wgonM~)zVc)L+MANM<8XT{5AGp@+Eh0*$Co}Lo3rmermDo9fN%P$B>5s1i!U)W zpWeQjLt9gR=_7QJ*Md)rfbT99N1oZsrpRQ<$QJnc7IjUH4LVw8|05q?%A?r+kJU@h z{AEmCk#=41eLJaD(X`$<())amY~i3{?_Vd3%c^hfYJzmXEZ%QBa+D5hNk;*YzKaTS zyW3(Q?5dTJSC1a?fx(%%wS9sn|4#8yIZJ9Jwtj(w-Nz~q^Bz6qe9V^d5c@Gz^Ays% z_*&?>)m;sirv8t83XDPu?aRWLKV|kRosFP8zyI!tU8y)dTE?L=zq}CN-12JaU4PWG z@vPlS1jQ&!#ifsSF>KGwI?T(3cXM4z%&Vdm(oHZ$(`8UTYC4kotG|mAe^;%87-Kv> zRjNm7Rx;AZ&W9LN>+&$AkZv%T(EMFqyQ^qvf#ZX*{$V{;8fAX7-I4AkWaNh7uQbez z#zD%Oa(6%8eE_GvX=Bs324Xl~inyPXv%@AE7B)s;2T9;PVyo+0!cnOC-`>wL8#f6VcvNQe&S zI?BLY>rroM)oOftP{E^KU!OV`WM#ZK26}CT*Do2BtIjVwybD!*-y-B7(LAGAi1mp#F45v|ZKM7*DD%NzK3y6Unqn*uKD3 zZT!SvwaK%-VRcc7Z65m3elOn)L_4lM{L~t9L$=!cW_o^S?T#jE|Vk-qn}X(KOlr7c8u&MLqUtKz+oQ2ok4rC5T zQijG#jkg!s=)NF?F6wNjZKeBdmMsIZ-SsWp%jbP7l5p^*yVk57A<=1QE36PT|-5k4$)r2!}>M z$V-4W73=C9SXLdj_IbMU(MhM)hb3P9%5gerI7JtUNBD)q9ZBf}FVwj9X^0EwD^cq60Y{Uy9JO`&bT$7$LZc{5?&p=F;5$&}9QjD-am zLJD;ELiFXek=B&oB{}rhM^*0;lc*bOHNWKau@URmE11&homf(iVWtnKzf0oiZQ-cq zm^>|)*%c9}l7+13+dYJp`({1j(E~wB6UZf1y2~krfH@$fIMV@N;qIi{lMts&z1#x5 zbTE-p)2XV-JN`!s@C`_w#b#$I*j_0t#vGbYSmdF<=Pbt|?R^#0jat@|u7zZu>>&aO zutuU$vMKNf1jAc#gp@UV;N@%drp=<~L7JZRh;QrFs~sn|5H8yOK9?AC7ILn?6^|WNlcDRC@&}+juEn zi_*K~XT)6e(t-W@;pv~9#ui|?B{$XLTtxLkAhrQ;zqp*E))7ZLYnB;8uDGvBui>FMK2{HmR{AnwxJ&mv|bshS>dx zf~c9VkzA`?LQ1L)b-KJSt~$KQf}f?=CUz9)frU$aAxDz-1Tuu@yG1MGD*cv|%R~6v zj#foEhcxl5sn3u*J<`Wrm+&-%7gf0VXulnB;c!6SKi5`5tSq_H4lwJU@nlEzFab;u z3p;b0&-ABFc}tG)k$lI`)@{=iac*9S0}#~CZFy8-hXJgrRCZmzHY|*p&k%QZ?d3hb zGclqtos&RZQ^g$wnZ54k5JRAcD53N4?xWiRO2fCOjf?kEbBQ?krg5gbsu=qjzB%m> z`k2>E6LUqWqRaH`GyWe4vRgiVm<_3@eDf>nv;nT8T!w zR0AEVJx!zcp)OlsLUd!R)Eqv=KIV$jShg@>d*fjqozvGyHKVD4u+71joc*AeRLX9ZGaT#{h z|9aj7U#0Ubq1{xuxbG{_pvm6v?enmgWGF~kUAsvb=4F@)a7AQcNE#nHxmo=cI#;_E z4kka2xE8%qOV#MkpT(dY?~_ErXunbOq{p*6w_nizdWgp_gBd49*m%--wAzn@t}Bv8 z+_!T0&X#9o@6qrXTf1=kKyrN~5@I%M!a;CXsBUVLip26`+FEi-ViVtY_S9Ru`7C}T zaa|m-Euwe`By74KPCDV4;giYZT~>2+ERX6`9LS8}oT=>z6AX6zmDpyV#kRYG<5AlL z@UO2FX|TlXb*M2G)EW-$XNOZ}s5iI@4SBzITUZ4rcqkIaIqH(&l~!K$+vxMy`}n)A zKt>AETs`9-d@Je*<66GPp3i99&*xTsMWC5xH-nFRY`Z+)qU51M)mo0Fy)$}rw$&8r z{^IycS}b}muRikW)XM~)CBK~AlGuvSjUA=SGOV(5^VF9dGbvbEd~6k=lN;WA&A}E%3m$zcP4m{ExD?>F$}p>S>fyhG?u!h2{aTgc)#cb zFJEdS&qKnpe2u+IxX_CH>zfED<+Pnn_Yi?Q)Yh4e^ODVko6aT|9<+=&7a2xE3)TKN z-YB%6JWt0$dTrSEK1b@*4M|rLx=e2j^5%${f;Rn>n^K4;7d{H2*o@h^5b{Wb-nUWO z``p_hR?E2W)$D#}&Uee6HY4V+kc>NKCUeCI;cW5Vnb)JUZIP_QCzSI~@T@h{=x0qR zz~gTwiXOxk4p2^PEtO}i=*+i^-&Bj&hmzk&b%A3%Quqqbqlyy6!RcS5#GO0Bzi;ve z-6RXt*DgiWTTrPyULlFOys~~eJWqS3aqsL^R8LRm_n6BG%>Bt6{$XQqR}TM*Jlomp zsNfin%gD4t042#;Bt}w~4)1RCwM5rl4Ts^oUMp8hD|LG-2s4`aGW`ns+nnlaS`u?Z zQT8#lQeBe)&xa>v_wl@;-)>riqS=xxhY2L+(pL`Y_McG}$?elo<~X^DYsDmIuiT+5 zlC^uh@Z^ND<1qVRKr~xg;@ZQZ{_s2b%7A%mmZ-(>(Ai3^7MC75v%p1B(#$!8c2rZO~YUVi`H46og5 zE(>z0#*p{G(nqyn>W#mF6i&pM4>Oc@cmb_#*yN+Y8l#Bf#4QE-cOxnZB_#N=nK zfZsc;f&B~^Db2U3^StXM)TO$LR3epd_vs~+2|E#E^3x4CD32W7KFlSJI=?WukmQOZ~`qf&}($^IxH&k>?1Tgvc~;axV@%a~aT$*>4{iR2gv z4Xv6*qy&vxNXW1r8tr=nOiDCbH5M6aMwW;(bi19672?XOj=0_t%)wQTdIJz;8BGEK z7DeB4QsEdJd3nCB**q~GO4oXdxF`abY@lycGP%Jy3o9e1Y$E8bfec7;@}+^9Q93X- ziq;0)#$UR?v~jQNJ_W&GB;f6HX|Q;7pMhP#iwg7BL!dS7tk5v$ojcB^PQEeUq=ujE z+E$k3tW(y!{KC0QSSdMXo~_6&zSZbdBbY4ICB&z@Bo!sl^;*|}i?XY6!Qd_dm`;@t zoD%ZRpjS-C^ggBdNZ0D=3)4e~sC&GDF%*rBcO*obmgSl#c;Z|6>6s#0%`V@4AvZ7x z2?q|xg={|jQVI}>##t8B!>{gJdQ)RDd{1KgRiyJ|r;TncFgZ#$Mo58mH0jIb2&D!U z!ID%aP2l12TQb_f;;+6Zt~o6%9%@1sv%e z15EFR$SCh;dk5?iUgUvAk*AFi5*;fI|a@^g_fj3FI46cVT1W9dqCtvc?5pFA(Gfb_z=&Gw?QQ#YP-ir3HH+xS`^QS z2L`~)x|6BYWkT08pK2l`yjp5G{}Ym6jhjvJ~*1(l&+19w;k z#d&&H7b>gmd3re~wToUKPHBhlDJXk9nT9xBad@AXaP$rYT(DdQ#eI=+O(>XfC6cjE z9XQ&3SKr#4nR>EyS)D{YVBg6b5Z>|7zQkBG=G#>Jv@F;*|H8gk*|4f#rDpb7u;;~m z%{$}Hz0u43j>)mULcqrHE zbTv0qrx-rFZG@qn$k}r|2WG$KDT~>?&H7>?~Tq+^0Xs z+NU?7S;2_Uh|mEDKK0H`hdxt*HW*CdbwJ&aiTBjI_;N+1w~5+obbke7;c!I-dM)Zr zyVN^w4X;kUBxc)NDH_b8Zir90WIN9vx%Qcl)?vAucHDvAxzoqHr;!Tu{t|oHIQfS%IZ&(&%N}~0xs#SnN^9q*C)*Du z;N^}_h&sM9@%@XPf&YKZi1dGDSO2<^8uI^tGNhjysQ>GY(Ek@3uK!CSqQK5Un4Xq5U^~_LF!T%gJ!NqlZ8U!?Z8mxU(W?4IHeFZ}Y4Q5#(5oSe0 z7YD6htNp2qvbx5G%(A+6u#{?SKQPD}+FLu?=^NUU-u5BSEM;h5stZfi26L()04ph& zgH?-J)Xv(`2HLp-v!Wd|$D0kT4SiQ;K?P`vHYZbkLwQjFW^qynJ4Ztv9%e!4c@@wu z>`8Ay{xXa|PsaE^jpug5{x5ib*{-kXY6D}<|5^Uro(=E|9>6aX+5ZY4z^zjJis%=` z``RtF@=!UDSo{!>N>S_bxve zAVHqnY@ZGqKc*#BHFek=2jYO@*ZOD5x@FL>dJg`@7yKAF%kQIujqE47Uwi)tIq1Ja z{_n^@ASUP;OuvBpAtGt$983!S(?#48ev=UF2&G%e{x~1zRzQ$jt3my32tX(kZ-oN8 z!k7+a?mq&8!H3<$=(oawmid2pm_QJaiS1v8DQjowM0(5q-{kR&P5qlZ*nR?Jg=)&J z=0L9^Fd6(D1WYb4ZMl60qu*-Ozw#eig9-2(uv?xp|KR^$ruB=9{#Rho9$}sSSHNH( zVH}72yt4i)KmY{71nu>Il=la|AB_7U^joZuKb`k2;Wu6RU8&iijQMY|LSeGN%YotH92~*KqM<)zL4Ml(J{Mh~- zIV*^j3Cg{H2mZtF{ZNTNXU|*5@EeQSe!36HZFux!Vu0NG`rq9L8|c3u(trFhY#2~h zfS^*iy$b(lIJZ6gM-c36Oi)Gs_u>4-`@bf)-?jQbo!?FdKS0Cy3X=!y84#)!!2g*f zegneJ#?A!!RU>{l(w|xYeehdw1S|PZ0QqlP@ISr%fdVRN7z&t8vHwTHx1rX5bQ8z| zU}FClB)3-oQ&vAjd^><&!jW6y{U+i+`12oO{1D1N{{D6fgQB{1qfi}$@#}Wd{i(~h zF7+QiLTNCs1+%W(`moP1J%-kYxn0oD`nR%xd5xbs{+ms}Xg@vQZQlY=Zv3m&vi@*# zKdly83?2VNue+ElBNds8l<;I zMS5!^q__SIx*!Qt2U5VTiIGBAC~rUA`Zv-avLwBYRpm*4;D@#KLrVa#L)!j%A&0

R<>8m}jR*Xstw7*7qkY6WPJ40OuYrB7fIH*8x0Q6KnuzTY|7Ip#u@pbugq6ddAAa z%F4pV0)qZyX9cKJ)BeI77dt~ER2EVQ2P#z2e*Tey*r8@hYD9WVgDwk$VQhx|ky`zr z!R`T2LBRh0hsMgm4s|8J(qK!TGSq_?y{tp_2g9Xa( zU&}%30@$Hq|CPqV0^xwg@xRdktRUE&_$v)smyPAmegUlDziA*K@UQW*0fB$@0fI(m zzxM$(eZZe%gZ9hL@h6|5HV&v4{If0xJIu%b-X6!_;{~#@{>c~URL1%j4}fey*uvp&?E#@+ z{_GbB1pKAyh59&o= z-u1VBK`cPnQso~sFl;LPodyQLqWM2*Y=7zy)S}t`90v#t{)?y3DGKJze`^m6ge_+O zMPvOF3m6Dt{lgZZuUG(>d;YyWcDBEC4Z;qBeLwYEIVg?ePrg9dA+T55-^+p6{?c&> zGzj}czR=T#q5k{#x-c4S&E?njpfsql{z+qndj7v?P|$zTpdJ570|NfE52&p|k1zeJ z91s>`{f-3)V*i7G(7I3~{IeW8)N}krWBpUF0MH2RZ+`_f%fGO&|K-D=bvgdV41&&_ zfA$Mv{Zluf{slUZ{Z$V9E3X{vbWJS`?O^MZ3Z`y`&}ooa-rCxM^fqLGF4>D)8CjFw zPUf%=LZlj`T*9n^5D=S?kdUAtY<^ 1: diff --git a/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py b/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py deleted file mode 100644 index 6ca414b61..000000000 --- a/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_ast.py +++ /dev/null @@ -1,301 +0,0 @@ -from cool_compiler.semantic.v0_parser_return.factory_parser_return_ast import AtrDef - - -result = '@result' -self_name = 'self' -super_value = '' - -class StackData: - def __init__(self, x = None) -> None: - self.x = x - - def __str__(self) -> str: - return self.x - -class Local(StackData): - pass - -class Param(StackData): - pass - -class Node: - def get_pos_to_error(self, lineno, index): - self.lineno = lineno - self.index = index - -class Program(Node): - 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(Node): - 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(Node): - def __init__(self, name, value) -> None: - self.name = name - self.value = value - - def __str__(self) -> str: - return f'\tdata {self.name}: {self.value}' - -class String(Data): - pass - -class Int(Data): - pass - -class Bool(Data): - pass - -class Function(Node): - 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(Local(name)) - return name - - def force_parma(self,name, scope): - self.var_dir[name] = 1 - scope.define_variable(name, name) - self.param.append(Param(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(Param(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(Local(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(Node): - 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 - - 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): - pass - -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 CmpInt(Expression): - pass - -class CmpStr(Expression): - pass - -class CmpRef(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 Load(Expression): - pass - -class ALLOCATE(Expression): - pass - -class IfGoTo(Expression): - pass - -class GoTo(Expression): - pass - -class Label(Expression): - pass - -class TypeOf(Expression): - pass - -class New(Expression): - pass - -class Neg(Expression): - pass - -class Complemnet(Expression): - pass - -class Comment(Expression): - def __str__(self) -> str: - return "" - - diff --git a/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py b/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py deleted file mode 100644 index 92553aa67..000000000 --- a/src/cool_compiler/codegen/v0_type_data_code-odd/type_data_code_visitor.py +++ /dev/null @@ -1,536 +0,0 @@ -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 type_data_code_ast as ASTR -from .type_data_code_ast import Arg, CmpInt, result, super_value - -CoolInt = CoolTypeBuildInManager().find("Int") -CoolBool = CoolTypeBuildInManager().find("Bool") -CoolStr = CoolTypeBuildInManager().find("String") -CoolObject = CoolTypeBuildInManager().find(OBJECT_NAME) - - -class CILGenerate: - def __init__(self, errors) -> None: - self.errors = errors - self.label_list = {} - self.type_dir = { - OBJECT_NAME: 1 - } - - 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] - - @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') - - scope = Scope() - - _dictt = CoolTypeBuildInManager().dictt - for key in _dictt.keys(): - self.create_type(_dictt[key], 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.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.Arg('self')) - main.expr_push(ASTR.SimpleCall('new_ctr_Main')) - main.expr_push(ASTR.Arg('self')) - main.expr_push(ASTR.VCall(result, 'Main', 'main')) - main.expr_push(ASTR.Return(0)) - self.program.add_func(main) - - return self.program - - 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 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) - - @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_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.Load(tn, _type.name)) - self.new_type_func.expr_push(ASTR.Comment(f'Cargando el nombre del tipo desde el data')) - self.new_type_func.expr_push(ASTR.SetAttr('self', 'type_name', tn)) - self.new_type_func.expr_push(ASTR.Comment(f'Assignando el nombre del tipo en el campo type')) - - @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 = self.visit(node.expr, self.new_class_scope) - exp_list[-1].set_value(attr_name) - exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.name], attr_name)) - exp_list.append(ASTR.Comment(f"Assignando el resultado de la expression al atributo {node.name} de la clase {self.currentType.name}")) - self.new_type_func.expr += exp_list - elif node.type in [CoolInt, CoolBool]: - default = self.new_type_func.local_push('default_prop', self.new_class_scope) - self.new_type_func.expr_push(ASTR.Assign(default, 0)) - self.new_type_func.expr += self.value_def(default, node.type.name, scope) - self.new_type_func.expr[-1].set_value(default) - self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], default)) - else: - null = self.new_type_func.local_push('null', scope) - self.new_type_func.expr_push(ASTR.Load(null, '_______null_______')) - self.new_type_func.expr_push(ASTR.SetAttr('self', self.currentType.attr[node.name], null)) - - 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) - self.currentFunc.force_local(result, func_scope) - cond = expr_list[-1].try_set_value(result) - - expr_list.append(ASTR.Return(result if cond else 'self')) - expr_list.append(ASTR.Comment(f"Final de la function {node.name}")) - - self.currentFunc.expr = expr_list - - @visitor.when(AST.CastingDispatch) - def visit(self, node: AST.CastingDispatch, scope: Scope): - 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 += 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(f'Agrega a la pila el paramentro {i} al CastingDispatch {node.id}') - - 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 = self.visit(node.expr, scope) - instance_name = self.currentFunc.local_push(f'instance_to_call_{node.id}', scope) - instance_expr_list[-1].set_value(instance_name) - instance_expr_list.append(ASTR.Comment(f"Fin de la exprecion previa al Dispatch {node.id}")) - - arg_list = [instance_name] - for i, param in enumerate(node.params): - 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 Dispatch {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(f'Agrega a la pila el paramentro {i} al Dispatch {node.id}') - - 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): - arg_list = ['self'] - param_expr_list = [] - for i, param in enumerate(node.params): - param_expr_list += self.visit(param, scope) - param_name = self.currentFunc.local_push(f'param_{i}_to_{node.id}', scope) - param_expr_list[-1].set_value(param_name) - param_expr_list.append(ASTR.Comment(f"Fin del paramentro {i} al StaticDispatch {node.id}")) - arg_list.append(param_name) - - for i, arg in enumerate(arg_list): - param_expr_list.append(ASTR.Arg(arg)) - param_expr_list.append(ASTR.Comment(f'Agrega a la pila el paramentro {i} al StaticDispatch {node.id}')) - - param_expr_list.append(ASTR.VCall(super_value, self.currentClass.name, node.id)) - return param_expr_list - - @visitor.when(AST.Assing) - def visit(self, node: AST.Assing, scope: Scope): - exp_list = self.visit(node.expr, scope) - result_local = self.currentFunc.local_push(f'result@assing@{node.id}', scope) - exp_list[-1].set_value(result_local) - exp_list.append(ASTR.Comment(f'Fin de la expresion lista para ser asignada')) - - var = scope.find_variable(node.id) - if not var is None: - exp_list.append(ASTR.Assign(var.type, result_local)) - exp_list.append(ASTR.Assign(super_value, var.type)) - else: - exp_list.append(ASTR.SetAttr('self', self.currentType.attr[node.id], result_local)) - 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 = self.visit(node.condition, scope) - expr_list[-1].set_value(cond_result) - expr_list.append(ASTR.Comment(f'Fin de la evaluacion de la condicion de un IF')) - result_if = self.currentFunc.local_push('result@if', scope) - - label_then = new_name(f'then_{self.currentFunc.name}', self.label_list) - label_fin = new_name(f'fin_{self.currentFunc.name}', self.label_list) - expr_list.append(self.get_value(cond_result, 'Bool')) - expr_list.append(ASTR.IfGoTo(cond_result, label_then)) - - expr_list.append(ASTR.Comment(f'Else case')) - else_list = self.visit(node.else_expr, scope) - else_list[-1].set_value(result_if) - 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(result_if) - - 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, result_if)] - - @visitor.when(AST.While) - def visit(self, node: AST.While, scope: Scope): - while_cond = new_name('while_cond', self.label_list) - while_back = 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_local) - result_list += [ASTR.Label(while_cond)] - result_list.append(ASTR.Comment(f'Fin del cuerpo e inicio de la condicion de un While')) - - cond_local = self.currentFunc.local_push('cond@while', scope) - result_list += self.visit(node.condition, scope) - result_list[-1].set_value(cond_local) - result_list.append(self.get_value(cond_local, 'Bool')) - result_list.append(ASTR.IfGoTo(cond_local, while_back)) - result_list.append(ASTR.Comment(f'Fin de la condicion de un While')) - - 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 = self.currentFunc.local_push('step@block', scope) - 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) - - 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, _, expr in node.assing_list: - local_name = self.currentFunc.force_local(name, let_scope) - if not expr is None: - 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}')) - - - return result_list + self.visit(node.expr, let_scope) - - def basic_cond_case(self, node: AST.Case, scope: Scope, expr_cond_list): - if not node.expr.static_type in [CoolBool, CoolInt, CoolStr]: return [] - - for name, atype , expr in node.case_list: - if node.expr.static_type.conforms_to(atype): - case_scope = scope.create_child('basic_case') - self.currentFunc.force_local(name, case_scope) - expr_cond_list[-1].set_value(name) - expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) - return expr_cond_list + self.visit(expr, case_scope) - - return expr_cond_list - - def object_case_with_ref_cond(self, node: AST.Case, scope: Scope, expr_cond_list): - for name, atype , expr in node.case_list: - if node.expr.static_type.conforms_to(atype): - case_scope = scope.create_child('basic_case') - self.currentFunc.force_local(name, case_scope) - expr_cond_list[-1].set_value(name) - expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) - return expr_cond_list + self.visit(expr, case_scope) - if not atype in [CoolBool, CoolInt, CoolStr]: break - return [] - - def general_case(self, node: AST.Case, scope: Scope, expr_cond_list): - cond_result = self.currentFunc.local_push('cond@result', scope) - expr_cond_list[-1].set_value(cond_result) - type_result = self.currentFunc.local_push('cond@type', scope) - expr_cond_list.append(ASTR.TypeOf(type_result, cond_result)) - final_result = self.currentFunc.local_push('case_result', scope) - - expr_list = [] - end_label = new_name('case_end', self.label_list) - step_case = self.currentFunc.local_push('step@case', scope) - for name, atype , expr in node.case_list: - step_label = new_name(f'{atype.name}_step_case', self.label_list) - expr_cond_list.append(ASTR.CheckType(step_case, type_result, self.map_type(atype.name))) - expr_cond_list.append(ASTR.Comment(f'Check case tipo {atype.name} en un case')) - expr_cond_list.append(ASTR.IfGoTo(step_case, 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 += self.visit(expr, step_scope) - expr_list[-1].set_value(final_result) - expr_cond_list.append(ASTR.Comment(f'Expression correspondiente al tipo {atype.name} en un case')) - expr_list.append(ASTR.GoTo(end_label)) - - return ( - expr_cond_list - + expr_list - + [ASTR.Label(end_label)] - + [ASTR.Assign(super_value, final_result)] - ) - - @visitor.when(AST.Case) - def visit(self, node: AST.Case, scope: Scope): - expr_cond_list = self.visit(node.expr, scope) - - result = self.basic_cond_case(node, scope, expr_cond_list) - if any(result): return result - - result = self.object_case_with_ref_cond(node, scope, expr_cond_list) - if any(result): return result - - return self.general_case(node, scope, expr_cond_list) - - def binary_op(self, name, node, astr_node, scope: Scope, _type = 'Int', type_result = 'Int'): - op_1 = self.currentFunc.local_push(f'{name}@_a', scope) - op_2 = self.currentFunc.local_push(f'{name}@_b', scope) - - 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 opercion {name}')) - result_list.append(self.get_value(op_1, _type)) - - 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 opercion {name}')) - result_list.append(self.get_value(op_2, _type)) - - op_result = self.currentFunc.local_push(f'{name}@_result', scope) - return result_list + [astr_node(op_result, op_1, op_2)] + self.value_def(op_result, type_result, scope) - - @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, type_result='Bool') - - @visitor.when(AST.LessOrEquals) - def visit(self, node: AST.LessOrEquals, scope: Scope): - return self.binary_op('le', node, ASTR.LessOrEqual, scope, type_result='Bool') - - @visitor.when(AST.Equals) - def visit(self, node: AST.Equals, scope: Scope): - if node.left.static_type in [CoolInt, CoolBool]: - return self.binary_op('int_eq', node, ASTR.CmpInt, scope) - if node.left.static_type == CoolStr: - return self.binary_op('str_eq', node, ASTR.CmpStr, scope, 'String', 'Bool') - - op_1 = self.currentFunc.local_push(f'ref@_a', scope) - op_2 = self.currentFunc.local_push(f'ref@_b', scope) - - 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 opercion cmpref')) - - 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 opercion cmpref')) - - op_result = self.currentFunc.local_push(f'ref@_result', scope) - return result_list + [CmpInt(op_result, op_1, op_2)] + self.value_def(op_result, 'Bool', scope) - - @visitor.when(AST.New) - def visit(self, node: AST.New, scope: Scope): - instance = self.currentFunc.local_push(f'instance_{node.item.name}', scope) - return [ - ASTR.ALLOCATE(instance, node.item.name), - ASTR.Arg(instance), - ASTR.New(super_value, node.item.name) - ] - - def unary_op(self, name, node, astr_node, scope: Scope, _type): - op = self.currentFunc.local_push(f'{name}@_unary', scope) - result_list = self.visit(node.item, scope) - result_list[-1].set_value(op) - - op_result = self.currentFunc.local_push(f'ref@_result', scope) - return result_list + [self.get_value(op, _type), astr_node(op_result, op)] + self.value_def(op_result, _type, scope) - - @visitor.when(AST.Complement) - def visit(self, node: AST.Complement, scope: Scope): - return self.unary_op('compl', node, ASTR.Complemnet, scope, 'Int') - - @visitor.when(AST.Neg) - def visit(self, node: AST.Neg, scope: Scope): - return self.unary_op('neg', node, ASTR.Neg, scope, 'Bool') - - @visitor.when(AST.Void) - def visit(self, node: AST.Void, scope: Scope): - op_1 = self.currentFunc.local_push('void@_op', scope) - null = self.currentFunc.local_push('void@_null', scope) - unary_list = self.visit(node.item, scope) - unary_list[-1].set_value(op_1) - op_result = self.currentFunc.local_push(f'void@_result', scope) - return ( - [ASTR.Load(null, "_______null_______"), ASTR.Comment("void check")] - + unary_list - + [ASTR.CmpInt(op_result, null, op_1)] - + self.value_def(op_result, 'Bool', scope) - ) - - @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.Assign(super_value, var.type)] - else: - return [ASTR.GetAttr(super_value, 'self', self.currentType.attr[node.item])] - - def get_value(self, memory_dir, _type): - return ASTR.GetAttr(memory_dir, memory_dir, f'{_type}@value') - - def value_def(self, _value, type_name, scope): - upper_type = type_name.upper() - _type = self.currentFunc.local_push(f'type_{upper_type}', scope) - _instance = self.currentFunc.local_push(f'{upper_type}_instance', scope) - - return [ - # ASTR.Load(string_value, name), - # ASTR.Comment("Carga la referecia a string"), - ASTR.ALLOCATE(_instance, type_name), - ASTR.SetAttr(_instance, f'{type_name}@value', _value), - ASTR.Comment(f"Setear la propiedad value al {upper_type} en la variable {_value}"), - ASTR.Load(_type, type_name), - ASTR.SetAttr(_instance, 'type_name', _type), - ASTR.Comment(f"Setear la propiedad type_name al string en la variable {_value}"), - ASTR.Assign(super_value, _instance), - ] - - @visitor.when(AST.Int) - def visit(self, node: AST.Int, scope: Scope) -> ASTR.Node: - int_value = self.currentFunc.local_push('value_int', scope) - return [ - ASTR.Assign(int_value, node.item), ASTR.Comment(f"Int value {node.item}") - ] + self.value_def(int_value, 'Int', scope) - - @visitor.when(AST.Bool) - def visit(self, node: AST.Bool, scope: Scope) -> ASTR.Node: - boolean_value = self.currentFunc.local_push('value_boolean', scope) - if node.item == 'true': value = 1 - else: value = 0 - return [ - ASTR.Assign(boolean_value, value), ASTR.Comment(f"Bool value {node.item}") - ] + self.value_def(boolean_value, 'Bool', scope) - - @visitor.when(AST.Str) - def visit(self, node: AST.Str, scope: Scope): - name = self.program.add_data('string', node.item) - string_value = self.currentFunc.local_push('value_string', scope) - - return [ - ASTR.Load(string_value, name), - ASTR.Comment("Carga la referecia a string"), - ] + self.value_def(string_value, 'String', scope) \ No newline at end of file diff --git a/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py deleted file mode 100644 index d98e88799..000000000 --- a/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate.py +++ /dev/null @@ -1,533 +0,0 @@ -from cool_compiler.codegen.v1_mips_generate.stack import Stack -from ...cmp import visitor -from ..v0_type_data_code import type_data_code_ast as AST -from . import mipsgenerate_ast as ASTR - -class MipsGenerate: - def __init__(self, errors) -> None: - self.func_list = ['main'] - self.native_fun = { - "IO_out_string": ASTR.Out_String, - "IO_in_int":ASTR.In_Int, - "IO_in_string":ASTR.In_String, - "IO_out_int":ASTR.Out_Int, - "String_length":ASTR.Length, - "String_concat": ASTR.Concat, - "String_substr":ASTR.SubStr, - 'Compare_String': ASTR.Compare_String, - "Object_copy": ASTR.Copy, - "Object_type_name":ASTR.Type_Name, - "Object_abort": ASTR.Abort, - "String_substr":ASTR.SubStr - } - - @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: - if func in self.native_fun: - self.new_program.func[func] = self.native_fun[func]() - else: - self.visit(self.cil_func[func]) - - for func in list(self.cil_func.keys()) + list(self.native_fun.keys()): - if func in self.func_list: continue - self.new_program.func[func] = ASTR.Func(func) - self.new_program.func[func].cmd += [ASTR.Comment("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.visit(param) - - for _local in node.local + [AST.Local('$ra')]: - new_func.cmd += self.visit(_local) - - new_func.cmd += ( - [ASTR.SW('$ra', "0($sp)")] + - [ASTR.Comment(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 - - #stack_pointer = 0 - #bsp = self.base_stack_pointer - - - @visitor.when(AST.ALLOCATE) - def visit(self, node: AST.ALLOCATE): - memory_dir = node.x - _type = node.y - - stack_plus = self.stack.index(memory_dir) - attr_list = self.cil_type[_type].attributes - _len = len(attr_list) * 4 - - result = [ - ASTR.Header_Comment(f"Allocate a una class {_type} puntero en sp + {stack_plus}"), - ] - - 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(), - ASTR.SW('$v0', f'{stack_plus}($sp)'), - ASTR.Comment(f'Guardando en la pila el pintero 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] - - stack_plus_dest = self.stack.index(memory_dest) - stack_plus_instance = self.stack.index(memory_dir_instance) - attr_plus = self.cil_type[_type].attributes.index(attr) * 4 - - return [ - ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), - ASTR.Comment(f'Buscando la instancia de la clase {_type} en la pila'), - ASTR.LW('$t1', f'{attr_plus}($t0)'), - ASTR.Comment(f'Buscando el valor de la propiedad {attr}'), - ASTR.SW('$t1', f'{stack_plus_dest}($sp)'), - ASTR.Comment(f'Salvando el valor de la propiedad {attr} en la pila en el valor local {memory_dest}'), - ] - - @visitor.when(AST.SetAttr) - def visit(self, node: AST.SetAttr): - if node.y == 'type_name': - attr_plus = 0 - attr = 'type_name' - _type = "SELF" - 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 - - stack_plus_dir_value = self.stack.index(memory_dir_value) - stack_plus_instance = self.stack.index(memory_dir_instance) - - return [ - ASTR.LW('$t0', f'{stack_plus_instance}($sp)'), - ASTR.Comment(f'Buscando en la pila la variable {node.x} y guarda la direccion a la que apunta'), - ASTR.LW('$t1', f'{stack_plus_dir_value}($sp)'), - ASTR.Comment(f'Buscando el valor que se va a guardar en la propiedad'), - ASTR.SW('$t1', f'{attr_plus}($t0)'), - ASTR.Comment(f'Seteando el valor {memory_dir_value} en la direccion de la memoria del la propiedad {attr} del objeto de typo {_type}'), - ] - - @visitor.when(AST.Arg) - def visit(self, node: AST.Arg): - memory_dir = node.x - - stack_plus = self.stack.index(memory_dir) - self.stack.push(memory_dir) - - return [ - ASTR.LW('$t0', f'{stack_plus}($sp)'), - ASTR.Comment(f'Saca de la pila {node.x}'), - ASTR.AddI('$sp', '$sp', -4), - ASTR.SW('$t0', '0($sp)'), - ASTR.Comment(f'Mete para la pila {node.x}'), - ] - - def call(self, func, memory_dest): - self.stack.clean() - stack_plus = self.stack.index(memory_dest) - - return [ - ASTR.JAL(func), - ASTR.Comment(f'Call a la function {func}'), - ASTR.SW('$s0', f'{stack_plus}($sp)' ), - ASTR.Comment(f'Save el resultado de la funcion que esta en $s0 pa la pila'), - ] - - @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: -2] - - @visitor.when(AST.VCall) - def visit(self, node: AST.VCall): - memory_dest = node.x - _type = node.y - 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) - - @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 - instance_stack = self.stack.index(node.y) - _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_fun.keys() - 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 = [ - ASTR.LW('$t0', f'{instance_stack}($sp)'), - ASTR.Comment(f"Sacando la instancia de la pila (en {instance_stack - self.stack.local_push * 4}) de una clase que hereda de {_type}"), - ASTR.LW('$t1', '0($t0)'), - ASTR.Comment(f"Leyendo el tipo de la instancia que hereda de {_type}"), - ASTR.LW('$t3', f'{func_address}($t1)'), - ASTR.Comment(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 - stack_plus = self.stack.index(memory_dest) - - return [ - ASTR.LW('$s0', f'{stack_plus}($sp)'), - ASTR.Comment("Envia el resultado de la funcion en $s0"), - ASTR.LW('$ra', '0($sp)'),#f'{(len(self.stack) - 1)* 4}($sp)'), - ASTR.Comment("Lee el $ra mas profundo de la pila para retornar a la funcion anterior"), - ASTR.AddI('$sp', '$sp', self.stack.close()), - ASTR.Comment("Limpia la pila"), - ASTR.JR('$ra') - ] - - @visitor.when(AST.Load) - def visit(self, node: AST.Load): - memory_dest = node.x - data_label = node.y - - stack_plus = self.stack.index(memory_dest) - - return [ - ASTR.LA('$t0', data_label), - ASTR.SW('$t0', f'{stack_plus}($sp)') - ] - - @visitor.when(AST.Comment) - def visit(self, node: AST.Comment): - return [ASTR.Comment(node.x)] - - @visitor.when(AST.CmpInt) - def visit(self,node:AST.CmpInt): - memory_dest = node.x - dir_cmp1 = node.y - dir_cmp2 = node.z - - stack_plus_opr_1 = self.stack.index(dir_cmp1) - stack_plus_opr_2 = self.stack.index(dir_cmp2) - stack_plus_dest = self.stack.index(memory_dest) - - return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , - ASTR.Comment(f"carga en $t1 {dir_cmp1} de la pos {stack_plus_opr_1} "), - ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"carga en $t2 {dir_cmp2} de la pos {stack_plus_opr_2} "), - ASTR.SEQ ('$t3','$t2','$t1'), - ASTR.Comment(f"$t3 = {dir_cmp1} $t0 == {dir_cmp2} $ t1" ), - ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), - ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") - ] - - @visitor.when(AST.CmpStr) - def visit(self,node:AST.CmpStr): - memory_dest = node.x - memory_str1 = node.y - memory_str2 = node.z - - stack_plus_str1 = self.stack.index(memory_str1) - self.stack.push(memory_str1) - stack_plus_str2 = self.stack.index(memory_str2) - self.stack.push(memory_str2) - - func = 'Compare_String' - if not func in self.func_list: self.func_list.append(func) - - return [ - ASTR.Header_Comment("COMPARACION DE STR\n"), - ASTR.LW('$t0', f'{stack_plus_str1}($sp)'), - ASTR.Comment(f'Saca de la pila {node.y}'), - ASTR.AddI('$sp', '$sp', -4), - ASTR.SW('$t0', '0($sp)'), - ASTR.Comment(f'Mete para la pila {node.y}'), - ASTR.LW('$t0', f'{stack_plus_str2}($sp)'), - ASTR.Comment(f'Saca de la pila {node.z}'), - ASTR.AddI('$sp', '$sp', -4), - ASTR.SW('$t0', '0($sp)'), - ASTR.Comment(f'Mete para la pila {node.z}'), - ] + self.call('Compare_String', memory_dest) + [ASTR.Header_Comment("Fin de la Comparacion\n")] - - @visitor.when(AST.Less) - def visit (self,node:AST.Less): - memory_dest = node.x - dir_cmp1 = node.y - dir_cmp2 = node.z - - stack_plus_opr_1 = self.stack.index(dir_cmp1) - stack_plus_opr_2 = self.stack.index(dir_cmp2) - stack_plus_dest = self.stack.index(memory_dest) - - return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , - ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), - ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), - ASTR.SLT ('$t3','$t1','$t2'), - ASTR.Comment(f"$t3 = $t1 < $ t2 osea {dir_cmp1} < {dir_cmp2}" ), - ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), - ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") - ] - - @visitor.when(AST.LessOrEqual) - def visit (self,node:AST.LessOrEqual): - memory_dest = node.x - dir_cmp1 = node.y - dir_cmp2 = node.z - - stack_plus_opr_1 = self.stack.index(dir_cmp1) - stack_plus_opr_2 = self.stack.index(dir_cmp2) - stack_plus_dest = self.stack.index(memory_dest) - - return [ ASTR.LW('$t1', f'{stack_plus_opr_1}($sp)') , - ASTR.Comment(f"carga en $t1 {dir_cmp1} lo que hay en {stack_plus_opr_1} "), - ASTR.LW ('$t2', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"carga en $t2 {dir_cmp2} lo que hay en {stack_plus_opr_2} "), - ASTR.SLE ('$t3','$t1','$t2'), - ASTR.Comment(f"$t3 = $t1 <= $t2 osea {dir_cmp1} <= {dir_cmp2}" ), - ASTR.SW ('$t3',f'{stack_plus_dest}($sp)'), - ASTR.Comment(f"Pon en la posicion {stack_plus_dest} el valor de $t3") - ] - - @visitor.when(AST.Assign) - def visit(self,node:AST.Assign): - memory_dest = node.x - dir_value = node.y - stack_plus = self.stack.index(memory_dest) - - if type(dir_value) in [type(int()), type(float())]: - return [ - ASTR.LI('$t0' , str(dir_value)), - ASTR.Comment(f"Guarda el numbero que se va a asignar"), - ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"Escribe en la pila el numero que se le asigno a {memory_dest}") - ] - else: - stack_plus_dir_value = self.stack.index(dir_value) - return [ - ASTR.LW ('$t0',f'{stack_plus_dir_value}($sp)'), - ASTR.Comment(f"Lee de la pila {dir_value} en {stack_plus_dir_value} para assignar"), - ASTR.SW ('$t0',f'{stack_plus}($sp)'), - ASTR.Comment(f"Escribe en la pila el valor que se le asigno a {memory_dest}") - ] - - @visitor.when(AST.Neg) - def visit(self,node:AST.Neg): - memory_dest = node.x - memory_op1 = node.y - stack_plus_memory_dest = self.stack.index(memory_dest) - stack_plus_opr_1 = self.stack.index(memory_op1) - - return [ - ASTR.LW ('$t0',f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"Carga la pos {stack_plus_opr_1} en $t0"), - ASTR.AddI ('$t1','$t0',-1 ), - ASTR.Comment("$t1 = $t0 + (-1)"), - ASTR.MUL ('$t0','$t1',-1), - ASTR.Comment("$t0 = $t1 * (-1)"), - ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el contenido de $t0") - ] - - @visitor.when(AST.Complemnet) - def visit(self, node: AST.Complemnet): - pass - - @visitor.when(AST.Sum) - def visit(self,node:AST.Sum): - memory_dest=node.x - memory_op1=node.y - memory_op2=node.z - - stack_plus_memory_dest = self.stack.index(memory_dest) - stack_plus_opr_1 = self.stack.index(memory_op1) - stack_plus_opr_2 = self.stack.index(memory_op2) - - return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), - ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"poner en registro $t1 {memory_op2} lo que hay en {stack_plus_opr_2}"), - ASTR.Add('$t0' , '$t0','$t1'), - ASTR.Comment("en $t0 pon el resultado de la suma"), - ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en la posicion {stack_plus_memory_dest} el resultado ") - ] - - @visitor.when(AST.Rest) - def visit(self,node:AST.Rest): - memory_dest=node.x - memory_op1=node.y - memory_op2=node.z - - stack_plus_memory_dest = self.stack.index(memory_dest) - stack_plus_opr_1 = self.stack.index(memory_op1) - stack_plus_opr_2 = self.stack.index(memory_op2) - - return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), - ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), - ASTR.SUB('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la RESTA"), - ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la RESTA "), - - ] - - @visitor.when(AST.Mult) - def visit(self , node :AST.Mult): - memory_dest=node.x - memory_op1=node.y - memory_op2=node.z - - stack_plus_memory_dest = self.stack.index(memory_dest) - stack_plus_opr_1 = self.stack.index(memory_op1) - stack_plus_opr_2 = self.stack.index(memory_op2) - - return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), - ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment(f"poner en registro $t1 {memory_op2} lo que hay en {stack_plus_opr_2}"), - ASTR.MUL('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la MULT "), - ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la multiplicacion "), - - ] - - - @visitor.when(AST.Div) - def visit (self,node:AST.Div): - memory_dest=node.x - memory_op1=node.y - memory_op2=node.z - - stack_plus_memory_dest = self.stack.index(memory_dest) - stack_plus_opr_1 = self.stack.index(memory_op1) - stack_plus_opr_2 = self.stack.index(memory_op2) - - return [ASTR.LW('$t0', f'{stack_plus_opr_1}($sp)'), - ASTR.Comment(f"poner en registro $t0 {memory_op1} lo que hay en {stack_plus_opr_1}"), - ASTR.LW('$t1', f'{stack_plus_opr_2}($sp)'), - ASTR.Comment("poner en registro $t1 {memory_op2} lo que hay en f'{stack_plus_opr_2}"), - ASTR.DIV('$t0' , '$t0','$t1'), - ASTR.Comment("poner en registro $t0 la DIV "), - ASTR.SW ('$t0', f'{stack_plus_memory_dest}($sp)'), - ASTR.Comment(f"poner en {stack_plus_memory_dest} el resultado de la Division entera el resto esta en LO "), - ] - - @ visitor.when(AST.IfGoTo) - def visit(self,node:AST.IfGoTo): - memory_cmp = node.x - label_memory = node.y - - stack_plus_memory_cmp = self.stack.index(memory_cmp) - - return [ASTR.LI("$t0" ,1), - ASTR.Comment("Cargar 1 a $t0 pa comparar"), - ASTR.LW("$t1", f'{stack_plus_memory_cmp}($sp)' ), - ASTR.Comment(f"Cargar el valor {memory_cmp} de la pos {stack_plus_memory_cmp} a $t1 pa comparar"), - ASTR.BEQ("$t0","$t1", label_memory), - ASTR.Comment(f"if $t1==$t0 then jump {label_memory}") - ] - - - - @visitor.when(AST.CheckType) - def visit(self,node:AST.CheckType): - memory_dir = node.x - memory_instance = node.y - type_name = node.z - - stack_plus_memory_dir = self.stack.index(memory_dir) - stack_plus_memory_instance = self.stack.index(memory_instance) - - return [ - ASTR.LW('$s2',f'{stack_plus_memory_instance}($sp)'), - ASTR.Comment(f' pon en $s2 {memory_instance} el contenido de {stack_plus_memory_instance}($sp)'), - ASTR.LW('$a1', type_name), - ASTR.Comment(f"guarda en $a1 {type_name} "), - ASTR.JAL('Contain'), - ASTR.Comment("Salta para Contain"), - ASTR.SW ('$s0',f'{stack_plus_memory_dir}($sp)'), - ASTR.Comment(f"Guarda en la pos {stack_plus_memory_dir}($sp) el contenido de $s0") - ] - - @ visitor.when(AST.GoTo) - def visit(self,node:AST.GoTo): - label = node.x - return [ASTR.Jump (label), - ASTR.Comment(f"Salta para {label} ") - ] - - - @visitor.when(AST.Complemnet) - def visit (self,node:AST.Complemnet): - memory_dest = node.x - memory_number = node.y - - stack_plus_memory_dest= self.stack.index(memory_dest) - stack_plus_memory_number = self.stack.index(memory_number) - - # return [ASTR.LW('$t1', f'{stack_plus_memory_number}($sp)'), - # ASTR.MUL('$s0','$t1',-1), - # ASTR.SW ('$s0', f'{stack_plus_memory_dest}($sp)') - - - - # ] - return [ASTR.LI ('$t0',4294967295), - ASTR.LW ('$t1', f'{stack_plus_memory_number}($sp)'), - ASTR.XOR ("$s0" , '$t0','$t1'), - ASTR.Add ('$s0' ,'$s0' ,'1'), - ASTR.SW ('$s0', f'{stack_plus_memory_dest}($sp)') - ] - - diff --git a/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py b/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py deleted file mode 100644 index 9b243655b..000000000 --- a/src/cool_compiler/codegen/v1_mips_generate_old/mipsgenerate_ast.py +++ /dev/null @@ -1,580 +0,0 @@ -from ast import Compare - -class Program: - def __init__(self) -> None: - self.data = {} - self.func = {} - - 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' - - return result - -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) -> None: - self.name = name - self.cmd = [] - - def __str__(self) -> str: - result = f'{self.name}:\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 Compare_String: - def __init__(self) -> None: - pass - - def __str__(self) -> str: - return """ -Compare_String: - -lw $t4 , 4($sp) # segundo str2 a comparar -lw $t5 , 0($sp) # primer str1 a comparar - -LOOP_Str: - lb $t0, 0($t4) # primera letra str1 - lb $t1, 0($t5) # primera letra de str2 - add $t4, $t4, 1 # proximo caracter de str1 - add $t5, $t5, 1 #proximo caracter de str2 - - beqz $t0, LOOP_END_Str # temrino de analizar str1 - beqz $t1, LOOP_END_Str # temrino de analizar str2 - beq $t0, $t1, LOOP_Str # Alguno de los caracteres son diferentes - li $s0 , 0 # devuelve false - j END_Str - -EQUAL_Str: - li $s0, 1 #Devuelve True - j END_Str - -LOOP_END_Str: - - beq $t0, $t1, EQUAL_Str # si ambos terminaron en son iguales - li $s0 , 0 # else false - j END_Str - -END_Str: -add $sp, $sp, 8 #saca str1,str2 -jr $ra - """ - -class Comment: - def __init__(self, msg) -> None: - self.msg = msg - self.is_comment = True - - def __str__(self) -> str: - return f'#{self.msg}' - -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 Load: - def __init__(self, cmd ,registry, memory_dir) -> None: - self.registry = registry - self.memory_dir = memory_dir - self.cmd = cmd - - def __str__(self) -> str: - return f'{self.cmd} {self.registry}, {self.memory_dir}' - -class Store: - def __init__(self, cmd ,registry, memory_dir) -> None: - self.registry = registry - self.memory_dir = memory_dir - self.cmd = cmd - - def __str__(self) -> str: - return f'{self.cmd} {self.registry}, {self.memory_dir}' - -class CmpNotJump: - def __init__(self, cmd ,r_dest, r_src_1, r_src_2) -> None: - self.r_assign = r_dest - self.r_op_1 = r_src_1 - self.r_op_2 = r_src_2 - self.cmd = cmd - - def __str__(self) -> str: - return f'{self.cmd} {self.r_assign}, {self.r_op_1}, {self.r_op_2}' - -class JumpInconditional: - def __init__(self,cmd,dest) -> None: - self.cmd=cmd - self.dest = dest - - - def __str__(self) -> str: - return f'{self.cmd} {self.dest}' - -class JumpConditional: - def __init__(self,cmd,reg1,reg2,label) -> None: - self.cmd=cmd - self.reg1=reg1 - self.reg2 = reg2 - self.label = label - - def __str__(self) -> str: - return f'{self.cmd} {self.reg1} {self.reg2} {self.label}' - -class SysCall : - def __init__(self) -> None: - pass - - def __str__(self) -> str: - return f'{"syscall"}' - -class Operation: - def __init__(self,cmd,dest,op1,op2) -> None: - self.cmd=cmd - self.dest = dest - self.op_1 = op1 - self.op_2 = op2 - - def __str__(self) -> str: - return f'{self.cmd} {self.dest}, {self.op_1}, {self.op_2}' - -class Move : - def __init__(self,cmd ,Rds) -> None: - self.cmd = cmd - self.Rds = Rds - - def __str__(self) -> str: - return f'{self.cmd} {self.Rds}' - -############################# Move ################################################### -class MFHI(Move): - def __init__(self,Rds) -> None: - super().__init__('mfhi', Rds) - -class MFLO(Move): - def __init__(self,Rds) -> None: - super().__init__('mflo', Rds) -############################ Loads ################################################## -class LW(Load): - def __init__(self, registry, memory_dir) -> None: - super().__init__('lw', registry, memory_dir) - -class LI(Load): - def __init__(self, registry, memory_dir) -> None: - super().__init__('li', registry, memory_dir) - -class LA(Load): - def __init__(self, registry, memory_dir) -> None: - super().__init__('la', registry, memory_dir) -############################ Store ################################################## -class SW(Store): - def __init__(self, registry, memory_dir) -> None: - super().__init__('sw', registry, memory_dir) -############################ Cmp ################################################## -class SEQ(CmpNotJump): #comparacion igualdad - def __init__(self ,r_dest, r_src_1, r_src_2) -> None: - super().__init__( 'seq' ,r_dest, r_src_1, r_src_2) - -class SGE(CmpNotJump): #>= - def __init__(self ,r_dest, r_src_1, r_src_2) -> None: - super().__init__( 'sge' ,r_dest, r_src_1, r_src_2) - -class SGT (CmpNotJump): #> - def __init__(self, r_dest, r_src_1, r_src_2) -> None: - super().__init__('sgt', r_dest, r_src_1, r_src_2) - -class SLT (CmpNotJump): #< - def __init__(self ,r_dest, r_src_1, r_src_2) -> None: - super().__init__( 'slt' ,r_dest, r_src_1, r_src_2) - -class SLE(CmpNotJump): # <= - def __init__(self ,r_dest, r_src_1, r_src_2) -> None: - super().__init__( 'sle' ,r_dest, r_src_1, r_src_2) - -########################### Jump ##################################################### -class JAL(JumpInconditional): - def __init__(self,dest) -> None: - super().__init__('jal',dest) - -class JR(JumpInconditional): - def __init__(self,dest) -> None: - super().__init__('jr',dest) - -class Jump(JumpInconditional): - def __init__(self,dest) -> None: - super().__init__('j',dest) -################################# JUMPConditional ####################################### -class BEQ (JumpConditional): - def __init__(self ,register1, register2, label) -> None: - super().__init__( 'beq' ,register1, register2,label) -################################# Operator ############################################## -class AddI(Operation): - def __init__(self,dest,op1,op2) -> None: - super().__init__('addi',dest,op1,op2) - -class Add(Operation): - def __init__(self,dest,op1,op2) -> None: - super().__init__('add',dest,op1,op2) - -class MUL (Operation): - def __init__(self,dest,op1,op2) -> None: - super().__init__('mul',dest,op1,op2) - -class SUB (Operation): - def __init__(self,dest,op1,op2) -> None: - super().__init__('sub',dest,op1,op2) - -class DIV (Operation): - def __init__(self, dest, op1, op2) -> None: - super().__init__('div', dest, op1, op2) - -class XOR(Operation): - def __init__(self, dest, op1, op2) -> None: - super().__init__('xor', dest, op1, op2) - -################################# Native Func IO ################################################ -class Out_String: - def __str__(self) -> str: - return """ -IO_out_string: -lw $t1 , 4($sp) #Guardando self -lw $t0, 0($sp) #Guarda en $t0 la direccion del string -li $v0, 4 -lw $a0, 4($t0) #Pintando la propiedad value del string -syscall -addi $sp, $sp, 8 -move $s0, $t1 #return self -jr $ra -""" - -class Out_Int: - def __str__(self) -> str: - return """ -IO_out_int: -lw $t1 , 4($sp) #guarda self -lw $t0, 0($sp) #Guarda en $t0 la direccion del int -li $v0, 1 -lw $a0, 4($t0) #Pintando la propiedad value del int -syscall -addi $sp, $sp, 8 -move $s0, $t1 #return self -jr $ra""" - -class In_String: - def __str__(self) -> str: - return """ -IO_in_string: - -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 # Restun string - -#Allocate a una class String puntero en sp + 12 -#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 $t4, String -sw $t4, 0($v0) # Asigna el tipo String al string -sw $s0, 4($v0) # Asigan el nombre de la clase a la propiededa value del string - -move $s0, $v0 -addi $sp, $sp, 4 - -jr $ra -""" - -class In_Int: - def __str__(self) -> str: - return """ -IO_in_int: -li $v0, 5 -syscall -move $t6 $v0 - -#Allocate a una class Int puntero en sp + 12 -#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 $t4, Int -sw $t4, 0($v0) # Asigna el tipo Int al int -sw $t6, 4($v0) # Asigan el nombre de la clase a la propiededa value del int - -move $s0 , $v0 -addi $sp, $sp, 4 -jr $ra -""" - -class Contain: - def __str__(self) -> str: - return """ -Contain: - -loop: - lw $s0 , ($s2) - beq $s0, $a1, Equal # if $s0 ==a$t1 then target - beq $s0 , $zero, END - add $s2,$s2,4 - j loop - -Equal: -li $s0 , 1 -adii $sp , $sp ,4 -jr $ra - -END: -li $s0 , 0 -addi $sp , $sp , 4 -jr $ra -""" - -################################# Native Func Str ################################################ -class Length: - def __str__(self) -> str: - return """ -String_length: -lw $t4 , ($sp) #self -li $t0 , -1 #contador -lw $s2 , 4($t4) # propiedad value - -loop_len: -lb $s0 , ($s2) # Guarda la primara letra -beq $s0 , $zero, end_len -add $t0 , $t0, 1 # Suma al contador -add $s2, $s2, 1 # Mueve el punteron del string en 1 -j loop_len - -end_len: -#Allocate a una class Int puntero en sp + 12 -#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 $t4, Int -sw $t4, 0($v0) # Asigna el tipo Int al int -sw $t0, 4($v0) # Asigan el nombre de la clase a la propiededa value del int - -move $s0 , $v0 -addi $sp, $sp, 4 -jr $ra""" - - -class Concat: - def __str__(self) -> str: - return """ -String_concat: -lw $t2, 4($sp) #self -lw $t1, 0($sp) # str1 -lw $s1, 4($t2) # propiedad value self -lw $s2, 4($t1) # propiedad value str1 - -li $a0, 100 -li $v0, 9 -syscall #genere espacio para crear string -move $s3, $v0 - -#Allocate a una class String puntero en sp + 12 -#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 $t4, String -sw $t4, 0($v0) # Asigna el tipo String al string -sw $s3, 4($v0) # Asigan el nombre de la clase a la propiededa value del string -move $t7, $v0 - -loop_str1: - lb $t0, ($s1) # primera letra del puntero al string self - beq $t0, $zero, loop_str2 - add $s1, $s1, 1 # mueve el puntero del sstring self - sb $t0, ($s3) # guarda la letra en el nuevo string - add $s3, $s3, 1 # mueve el puntero del nuevo string - j loop_str1 - -loop_str2: - lb $t0, ($s2) # primera letra del puntero al string str1 - beq $t0, $zero, ENDConcat - add $s2, $s2, 1 # mueve el puntero del sstring str1 - sb $t0, ($s3) # guarda la letra en el nuevo string - add $s3, $s3, 1 # mueve el puntero del nuevo string - j loop_str1 - -ENDConcat: - move $s0 , $t7 - addi $sp, $sp, 8 - jr $ra -""" - -class SubStr: - def __str__(self) -> str: - return """ -String_substr: -lw $s5, 8($sp) # self. -lw $t0, 4($sp) # lee el int indice -lw $s1, 4($t0) # guarda el value de indece -lw $t0, ($sp) # lee el int j -lw $t4, 4($t0) # guarda el value de indece - -li $t0, 0 # Inicia el contador en 0 -li $s6, 1 # Contador de tamaño - -lw $s3, 4($s5) # tomar la propiedad value self - -li $a0 ,100 # reserva memoria para el string -li $v0,9 -syscall #genere espacio para crear string -move $s4, $v0 - -#Allocate a una class String puntero en sp + 12 -#atributo type_name en puntero + 0 -#atributo value en puntero + 4 -li $a0,8 -li $v0 , 9 -syscall -la $t9, String -sw $t9, 0($v0) # Asigna el tipo String al string -sw $s4, 4($v0) # Asigan el nombre de la clase a la propiededa value del string - - -find_index: - beq $t0, $s1, find_length # si el contador es el indice comiensa a crear el sub - add $s3, $s3, 1 # mueve el puntero del string de self - add $t0, $t0, 1 # mueve el contador - j find_index - -find_length: - lb $t1, ($s3) # guarda la primera letra del string self - sb $t1, ($s4) # guarda la primera letra del string self en el nuevo string - beq $s6, $t4, END_Substring # si el contador del tamaño es igual a j end - add $s4, $s4, 1 # Mueve el puntero del nuevo string - add $s3, $s3, 1 # Mueve el puntero del string self - add $s6, $s6, 1 # Contador de tamaño += 1 - j find_length - -END_Substring: - move $s0 , $v0 - addi $sp, $sp, 12 - jr $ra -""" -################################# Native Func Obj ################################################ -class Copy: - def __str__(self) -> str: - return """ -Object_copy: -lw $t0, 0($sp) #Guarda en $t0 self -lw $t1, 0($t0) #Guarda definicion del tipo -lw $t3, 4($t1) #En la segunda posicion la definicion de tipo contiene el - -mul $t3, $t3, 4 -move $a0, $t3 #tamaño que ocupa en la pila -li $v0, 9 -syscall #En $v0 la nueva instancia -move $s0, $v0 - -copy_loop: - beq $t3, $zero, end_copy - lw $t1, 0($t0) - sw $t1, 0($v0) - addi $t3, $t3, -4 - add $t0, $t0, 4 - add $v0, $v0, 4 - jr copy_loop -end_copy: - -addi $sp, $sp, 4 -jr $ra -""" - -class Abort: - def __str__(self) -> str: - return """ -Object_abort: -li $v0, 4 # system call #4 - print string -la $a0, _______error______ -syscall -lw $t0 0($sp) #Guarda en $t0 self -lw $t1 0($t0) #Guarga en tipo de self -lw $t2 0($t1) -li $v0, 4 # system call #4 - print string -la $a0, ($t2) -syscall -li $v0, 10 -syscall # execute -""" - -class Type_Name: - def __str__(self) -> str: - return """ -Object_type_name: -lw $t0 0($sp) #Guarda en $t0 la direccion del self -lw $t1 0($t0) #La primera posicion de self es la propiedad type_name -lw $t2 0($t1) #La propiedad type_name apunta a la definicion del tipo -la $t3 0($t2) #La definicion de tipo tiene en la primera poscion su nombre - -#Allocate a una class String puntero en sp + 12 -#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 $t4, String -sw $t4, 0($v0) # Asigna el tipo String al string -sw $t3, 4($v0) # Asigan el nombre de la clase a la propiededa value del string - -addi $sp, $sp, 4 -move $s0, $v0 - -jr $ra -""" - - From 1e947a12e9f467bfdb921ac767d5e2f33ad3e247 Mon Sep 17 00:00:00 2001 From: Yulii01 Date: Thu, 10 Mar 2022 12:51:22 -0500 Subject: [PATCH 90/91] int_value --- .../general_macros/int_valor.mips | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/cool_compiler/codegen/v1_mips_generate/general_macros/int_valor.mips 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 +########################################################################################################## From 146e71b565582cd041a706da6cd51fa2d4fa6e2f Mon Sep 17 00:00:00 2001 From: Daniel Orlando Ortiz Pacheco <58240840+danielorlando97@users.noreply.github.com> Date: Mon, 21 Nov 2022 08:16:49 -0500 Subject: [PATCH 91/91] Update Readme.md --- Readme.md | 179 ++++++++---------------------------------------------- 1 file changed, 25 insertions(+), 154 deletions(-) diff --git a/Readme.md b/Readme.md index a47d48b9e..e3df113ac 100755 --- 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 -```