From ebac6da2052b0bfdb937e6427df7339f9a192484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 12:56:03 -0500 Subject: [PATCH 001/191] Added Author names to cool.sh --- src/coolc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coolc.sh b/src/coolc.sh index 3088de4f..986b3677 100755 --- a/src/coolc.sh +++ b/src/coolc.sh @@ -4,8 +4,8 @@ INPUT_FILE=$1 OUTPUT_FILE=${INPUT_FILE:0: -2}mips # Si su compilador no lo hace ya, aquí puede imprimir la información de contacto -echo "LINEA_CON_NOMBRE_Y_VERSION_DEL_COMPILADOR" # TODO: Recuerde cambiar estas -echo "Copyright (c) 2019: Nombre1, Nombre2, Nombre3" # TODO: líneas a los valores correctos +echo "DLR MATCOM COOL COMPILER V 0.1" # TODO: Recuerde cambiar estas +echo "Copyright (c) 2020: Leonel Alejandro García López, Jorge Daniel Valle Díaz, Roberto Marti Cedeño" # TODO: líneas a los valores correctos # Llamar al compilador echo "Compiling $INPUT_FILE into $OUTPUT_FILE" From 6e44e6841a0a9bbbfb60eae69fae1ec42b4727fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 13:02:12 -0500 Subject: [PATCH 002/191] Added lexer.py and engine folder --- src/engine/lexer.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/engine/lexer.py diff --git a/src/engine/lexer.py b/src/engine/lexer.py new file mode 100644 index 00000000..e69de29b From fe3d4bce2f878d1d4f5aa9139633a96d97ecbe9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 13:12:47 -0500 Subject: [PATCH 003/191] Added members names to Readme.md --- doc/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Readme.md b/doc/Readme.md index 402477c8..505e1caf 100644 --- a/doc/Readme.md +++ b/doc/Readme.md @@ -4,9 +4,9 @@ **Nombre** | **Grupo** | **Github** --|--|-- -Nombre1 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/) -Nombre2 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/) -Nombre3 Apellido1 Apellido2 | C4xx | [@github_user](https://github.com/) +Leonel Alejandro García López | C412 | [@stdevlag](https://github.com/stdevlag) +Jorge Daniel Valle Díaz | C411 | [@thenai310](https://github.com/thenai310) +Roberto Marti Cedeño | C412 | [@rmarticedeno](https://github.com/rmarticedeno) ## Readme From 5fef3f418fc9b56d9917943cd6602985d5e63b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 15:36:35 -0500 Subject: [PATCH 004/191] Added basic lexer structure --- src/engine/lexer.py | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index e69de29b..d36c0178 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -0,0 +1,85 @@ +import ply.lex as lex + +####### Tokens ####### + +keywords = [ + 'CLASS', + 'ELSE', + ### false case is independently treated + 'FI', + 'IF', + 'IN', + 'INHERITS', + 'ISVOID', + 'LET', + 'LOOP', + 'POOL', + 'THEN', + 'WHILE', + 'CASE', + 'ESAC', + 'NEW', + 'OF', + 'NOT' + ### true case is independently treated +] + +literals = ['+', '-', '*', '/', ':', ';', '(', ')', '{', '}', '@', '.', ','] + +tokens = [ + # Identifiers + 'TYPE', 'ID', + # Primitive data types + 'INTEGER', 'STRING', 'BOOL', + # Special keywords + 'ACTION', + # Operators + 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', 'NOT', +] + list(keywords) + +####### Extra Methods ####### + +def iskeyword(t): + d = t.value.upper() + if d in keywords: + t.type = d + +##### TOKEN RULES ##### + +t_ignore = ' \t\f\r\v' +t_ignore_single_comment = r'\-\-[^\n]*' + +def t_BOOL(t): + r't[rR][uU][eE]|f[aA][lL][sS][eE]' + d = t.value.lower() + t.value = True if d == 'true' else False + return t + +def t_INTEGER(t): + r'[0-9]+' + t.value = int(t.value) + return t + +def t_TYPE(t): + r'[A-Z][A-Za-z0-9_]*' + iskeyword(t) + return t + +def t_ID(t): + r'[a-z][A-Za-z0-9_]*' + iskeyword(t) + return t + +t_ASSIGN = r'<-' +t_LESS = r'<' +t_LESSEQUAL = r'<=' +t_EQUAL = r'=' +t_INT_COMPLEMENT = r'~' + +t_ACTION = r'=>' + +states = ( + ('string','exclusive'), + ('comment','exclusive') + ) + From 684f0132deeb377237957013d0a571da78c0a8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 16:04:26 -0500 Subject: [PATCH 005/191] Added comment lexer rules --- src/engine/lexer.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index d36c0178..c91e0867 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -83,3 +83,20 @@ def t_ID(t): ('comment','exclusive') ) +def t_comment(t): + r'\(' + t.lexer.comments = 1 + #t.lexer.unterminated_slash = False + t.lexer.begin('comment') + +t_comment_ignore = '' + +def t_comment_opar(t): + r'\(\*' + t.lexer.comments += 1 + +def t_comment_cpar(t): + r'\*\)' + t.lexer.comments -=1 + if not t.lexer.comments: + t.lexer.begin('INITIAL') From 9822b817ed6dcee4fa041325f78ecd6c526dbe4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 16:22:41 -0500 Subject: [PATCH 006/191] Added newline tracking and eof in comment --- src/engine/lexer.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index c91e0867..2b2c95bd 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -37,6 +37,10 @@ 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', 'NOT', ] + list(keywords) +def t_newline(t): + r'\n+' + t.lexer.lineno += len(t.value) + ####### Extra Methods ####### def iskeyword(t): @@ -44,6 +48,10 @@ def iskeyword(t): if d in keywords: t.type = d +def find_position(input, token): + line_start = input.rfind('\n', 0, token.lexpos) + 1 + return (token.lexpos - line_start) + 1, token.lineno + ##### TOKEN RULES ##### t_ignore = ' \t\f\r\v' @@ -84,7 +92,7 @@ def t_ID(t): ) def t_comment(t): - r'\(' + r'\(\*' t.lexer.comments = 1 #t.lexer.unterminated_slash = False t.lexer.begin('comment') @@ -100,3 +108,11 @@ def t_comment_cpar(t): t.lexer.comments -=1 if not t.lexer.comments: t.lexer.begin('INITIAL') + +def t_comment_eof(t): + #error eof in comment + pass + +def t_comment_error(t) + print(t.values, 'error en comment') + lexer.skip(1) From db824bc966eb4c2b7bcc773932e0eb1ca4457fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 17:57:25 -0500 Subject: [PATCH 007/191] Added string state rules --- src/engine/lexer.py | 74 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 2b2c95bd..97223532 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -37,10 +37,6 @@ 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', 'NOT', ] + list(keywords) -def t_newline(t): - r'\n+' - t.lexer.lineno += len(t.value) - ####### Extra Methods ####### def iskeyword(t): @@ -48,6 +44,9 @@ def iskeyword(t): if d in keywords: t.type = d +def addline(t): + t.lexer.lineno += len(t.value) + def find_position(input, token): line_start = input.rfind('\n', 0, token.lexpos) + 1 return (token.lexpos - line_start) + 1, token.lineno @@ -113,6 +112,69 @@ def t_comment_eof(t): #error eof in comment pass -def t_comment_error(t) +def t_comment_error(t): print(t.values, 'error en comment') - lexer.skip(1) + t.lexer.skip(1) + +# count line number +def t_INITIAL_comment_newline(t): + r'\n+' + addline(t) + +def t_string(t): + r'\"' + t.lexer.begin('string') + t.lexer.string = '' + +t_string_ignore = '' + +def t_string_end(t): + r'\"' + if not t.lexer.unterminated_slash: + t.value = t.lexer.string + t.type = 'STRING' + t.lexer.begin('INITIAL') + return t + else: + t.lexer.string += '"' + t.lexer.unterminated_slash = False + +def t_string_newline(t): + r'\n' + t.lexer.lineno += 1 + if not t.lexer.unterminated_slash: + # error non-escaped newline may not appear in a string + pass + else: + t.lexer.string += '\n' + +def t_string_slash(t): + r'\\' + if t.lexer.unterminated_slash: + t.lexer.string += '\\' + t.lexer.unterminated_slash = False + else: + t.lexer.unterminated_slash = True + +def t_string_eof(t): + # eof in string + pass + +def t_string_all(t): + r'[^\n]' + if t.lexer.unterminated_slash: + spec = {'b':'\b','t':'\t','n':'\n','f':'\f'} + if t.value == '0': + #null character in string + t.lexer.unterminated_slash = False + pass + elif t.value in ['b','t','n','f']: + t.string += spec[t.value] + if t.value == 'n': + t.lineno+=1 + t.lexer.unterminated_slash = False + else: + t.string += t.value + else: + t.lexer.string += t.value + \ No newline at end of file From 1ab980a6b49862b12e16a436fb8753a2a759b147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 18:21:50 -0500 Subject: [PATCH 008/191] Added tokenizer method --- src/engine/lexer.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 97223532..979d54a2 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -56,6 +56,11 @@ def find_position(input, token): t_ignore = ' \t\f\r\v' t_ignore_single_comment = r'\-\-[^\n]*' +# count line number +def t_INITIAL_comment_newline(t): + r'\n+' + addline(t) + def t_BOOL(t): r't[rR][uU][eE]|f[aA][lL][sS][eE]' d = t.value.lower() @@ -116,11 +121,7 @@ def t_comment_error(t): print(t.values, 'error en comment') t.lexer.skip(1) -# count line number -def t_INITIAL_comment_newline(t): - r'\n+' - addline(t) - +# string state def t_string(t): r'\"' t.lexer.begin('string') @@ -177,4 +178,20 @@ def t_string_all(t): t.string += t.value else: t.lexer.string += t.value - \ No newline at end of file + +lex.lex(debug=1) + +###### TOKENIZER ###### + +def tokenizer(code): + tokens = [] + lex.input(code) + while True: + token = lex.token() + if token is None: + break + ##Add token + pass + #tokens.append(Token('$', CoolGrammar.EOF)) + + return tokens, lex.errors From 76b99d95b6316c9cce5a23ced2d299f692f09bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 20:36:15 -0500 Subject: [PATCH 009/191] Added errors.py --- src/engine/errors.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/engine/errors.py diff --git a/src/engine/errors.py b/src/engine/errors.py new file mode 100644 index 00000000..e69de29b From bf5e4d733b852620aaded6cb57f02f178a54df14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 21:56:43 -0500 Subject: [PATCH 010/191] Added Generic Error and Lexicographical Error --- src/engine/errors.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/errors.py b/src/engine/errors.py index e69de29b..94312748 100644 --- a/src/engine/errors.py +++ b/src/engine/errors.py @@ -0,0 +1,5 @@ +# Generic Error +ERROR = '(%d, %d) - %s: %s' + +def LexicographicError(line, col, message): + return ERROR % (line, col, "LexicographicError", message) \ No newline at end of file From 641f6056111c56fd1f1f788b0bb1e1354dc38d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 21:57:34 -0500 Subject: [PATCH 011/191] Added lexer errors structure --- src/engine/lexer.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 979d54a2..d61d2fae 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -1,4 +1,6 @@ import ply.lex as lex +from errors import LexicographicError + ####### Tokens ####### @@ -49,7 +51,11 @@ def addline(t): def find_position(input, token): line_start = input.rfind('\n', 0, token.lexpos) + 1 - return (token.lexpos - line_start) + 1, token.lineno + return (token.lineno, (token.lexpos - line_start) + 1) + +def lexer_error(t, message): + t.lexer.errors.append(LexicographicError(*find_position(t.lexer.lexdata, t), message)) + ##### TOKEN RULES ##### @@ -82,6 +88,10 @@ def t_ID(t): iskeyword(t) return t +def t_error(t): + lexer_error(t,f'ERROR "{t.value}"') + t.lexer.skip(1) + t_ASSIGN = r'<-' t_LESS = r'<' t_LESSEQUAL = r'<=' @@ -114,11 +124,10 @@ def t_comment_cpar(t): t.lexer.begin('INITIAL') def t_comment_eof(t): - #error eof in comment - pass + lexer_error(t,'EOF in comment') def t_comment_error(t): - print(t.values, 'error en comment') + print(t.value, 'error en comment') t.lexer.skip(1) # string state @@ -144,7 +153,7 @@ def t_string_newline(t): r'\n' t.lexer.lineno += 1 if not t.lexer.unterminated_slash: - # error non-escaped newline may not appear in a string + lexer_error(t,'Unterminated string constant') pass else: t.lexer.string += '\n' @@ -158,7 +167,7 @@ def t_string_slash(t): t.lexer.unterminated_slash = True def t_string_eof(t): - # eof in string + lexer_error(t,'EOF in string constant') pass def t_string_all(t): @@ -166,7 +175,7 @@ def t_string_all(t): if t.lexer.unterminated_slash: spec = {'b':'\b','t':'\t','n':'\n','f':'\f'} if t.value == '0': - #null character in string + lexer_error(t,'String contains null character') t.lexer.unterminated_slash = False pass elif t.value in ['b','t','n','f']: @@ -179,19 +188,21 @@ def t_string_all(t): else: t.lexer.string += t.value -lex.lex(debug=1) +lexer = lex.lex(debug=1) +lexer.errors = [] +lexer.unterminated_slash = False ###### TOKENIZER ###### def tokenizer(code): tokens = [] - lex.input(code) + lexer.input(code) while True: - token = lex.token() + token = lexer.token() if token is None: break ##Add token pass #tokens.append(Token('$', CoolGrammar.EOF)) - return tokens, lex.errors + return tokens, lexer.errors From bbe9bec5ec93c49f74331bcf51f33a72228a44eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 21:59:46 -0500 Subject: [PATCH 012/191] Added Compilers2 project files --- src/engine/cp/__init__.py | 7 + src/engine/cp/automata.py | 208 +++++++++++++ src/engine/cp/evaluation.py | 34 ++ src/engine/cp/grammartools.py | 324 +++++++++++++++++++ src/engine/cp/pycompiler.py | 519 +++++++++++++++++++++++++++++++ src/engine/cp/semantic.py | 331 ++++++++++++++++++++ src/engine/cp/utils.py | 88 ++++++ src/engine/cp/visitor.py | 80 +++++ src/engine/parser.py | 310 ++++++++++++++++++ src/engine/semantic_errors.py | 13 + src/engine/visitors/__init__.py | 5 + src/engine/visitors/builder.py | 113 +++++++ src/engine/visitors/checker.py | 419 +++++++++++++++++++++++++ src/engine/visitors/collector.py | 35 +++ src/engine/visitors/format.py | 114 +++++++ src/engine/visitors/inferer.py | 335 ++++++++++++++++++++ 16 files changed, 2935 insertions(+) create mode 100644 src/engine/cp/__init__.py create mode 100644 src/engine/cp/automata.py create mode 100644 src/engine/cp/evaluation.py create mode 100644 src/engine/cp/grammartools.py create mode 100644 src/engine/cp/pycompiler.py create mode 100644 src/engine/cp/semantic.py create mode 100644 src/engine/cp/utils.py create mode 100644 src/engine/cp/visitor.py create mode 100644 src/engine/parser.py create mode 100644 src/engine/semantic_errors.py create mode 100644 src/engine/visitors/__init__.py create mode 100644 src/engine/visitors/builder.py create mode 100644 src/engine/visitors/checker.py create mode 100644 src/engine/visitors/collector.py create mode 100644 src/engine/visitors/format.py create mode 100644 src/engine/visitors/inferer.py diff --git a/src/engine/cp/__init__.py b/src/engine/cp/__init__.py new file mode 100644 index 00000000..10d8ca17 --- /dev/null +++ b/src/engine/cp/__init__.py @@ -0,0 +1,7 @@ +from .automata import * +from .evaluation import * +from .grammartools import * +from .pycompiler import * +from .semantic import * +from .utils import * +from .visitor import * \ No newline at end of file diff --git a/src/engine/cp/automata.py b/src/engine/cp/automata.py new file mode 100644 index 00000000..0b986338 --- /dev/null +++ b/src/engine/cp/automata.py @@ -0,0 +1,208 @@ +try: + import pydot +except: + pass + +class State: + def __init__(self, state, final=False, formatter=lambda x: str(x)): + self.state = state + self.final = final + self.transitions = {} + self.epsilon_transitions = set() + self.tag = None + self.formatter = formatter + + def set_formatter(self, formatter, visited=None): + if visited is None: + visited = set() + elif self in visited: + return + + visited.add(self) + self.formatter = formatter + for destinations in self.transitions.values(): + for node in destinations: + node.set_formatter(formatter, visited) + for node in self.epsilon_transitions: + node.set_formatter(formatter, 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 f'{self.tag}\n{self.formatter(self.state)}' if self.tag else 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='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 + + 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] + +def empty_formatter(state): + return '' \ No newline at end of file diff --git a/src/engine/cp/evaluation.py b/src/engine/cp/evaluation.py new file mode 100644 index 00000000..e0d0e808 --- /dev/null +++ b/src/engine/cp/evaluation.py @@ -0,0 +1,34 @@ +from .pycompiler import EOF +from .grammartools import ShiftReduceParser, Action + +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 == Action.SHIFT: + token = next(tokens) + # stack.append(token.lex) + stack.append(token) + elif operation == Action.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/engine/cp/grammartools.py b/src/engine/cp/grammartools.py new file mode 100644 index 00000000..11786eb4 --- /dev/null +++ b/src/engine/cp/grammartools.py @@ -0,0 +1,324 @@ +from queue import Queue +from .pycompiler import Grammar, Item +from .automata import State +from .utils import ContainerSet + +class GrammarTools: + @staticmethod + def compute_local_first(firsts, alpha): + """ + Computes First(alpha), given First(Vt) and First(Vn) + alpha in (Vt U Vn)* + """ + first_alpha = ContainerSet() + + try: + alpha_is_epsilon = alpha.IsEpsilon + except: + alpha_is_epsilon = False + + # alpha == epsilon ? First(alpha) = { epsilon } + if alpha_is_epsilon: + first_alpha.set_epsilon() + + # alpha = X1 ... XN + # First(Xi) subset of First(alpha) + # epsilon in First(X1)...First(Xi) ? First(Xi+1) subset of First(X) & First(alpha) + # epsilon in First(X1)...First(XN) ? epsilon in First(X) & First(alpha) + else: + for symbol in alpha: + first_symbol = firsts[symbol] + first_alpha.update(first_symbol) + if not first_symbol.contains_epsilon: + break + else: + first_alpha.set_epsilon() + + return first_alpha + + @staticmethod + def compute_firsts(G: Grammar): + """ + Computes First(Vt) U First(Vn) U First(alpha) + P: X -> alpha + """ + firsts = {} + change = True + + # init First(Vt) + for terminal in G.terminals: + firsts[terminal] = ContainerSet(terminal) + + # init First(Vn) + for nonterminal in G.nonTerminals: + firsts[nonterminal] = ContainerSet() + + while change: + change = False + + # P: X -> alpha + for production in G.Productions: + X = production.Left + alpha = production.Right + + # get current First(X) + first_X = firsts[X] + + # init First(alpha) + try: + first_alpha = firsts[alpha] + except: + first_alpha = firsts[alpha] = ContainerSet() + + # CurrentFirst(alpha)??? + local_first = GrammarTools.compute_local_first(firsts, alpha) + + # update First(X) and First(alpha) from CurrentFirst(alpha) + change |= first_alpha.hard_update(local_first) + change |= first_X.hard_update(local_first) + + # First(Vt) + First(Vt) + First(RightSides) + return firsts + + @staticmethod + def compute_follows(G: Grammar, firsts): + """ + Computes Follow(Vn) + """ + follows = { } + change = True + + local_firsts = {} + + # init Follow(Vn) + for nonterminal in G.nonTerminals: + follows[nonterminal] = ContainerSet() + follows[G.startSymbol] = ContainerSet(G.EOF) + + while change: + change = False + + # P: X -> alpha + for production in G.Productions: + X = production.Left + alpha = production.Right + + follow_X = follows[X] + + # X -> zeta Y beta + # First(beta) - { epsilon } subset of Follow(Y) + # beta ->* epsilon or X -> zeta Y ? Follow(X) subset of Follow(Y) + for i, symbol in enumerate(alpha): + if symbol.IsNonTerminal: + follow_symbol = follows[symbol] + beta = alpha[i + 1:] + try: + first_beta = local_firsts[beta] + except KeyError: + first_beta = local_firsts[beta] = GrammarTools.compute_local_first(firsts, beta) + change |= follow_symbol.update(first_beta) + if first_beta.contains_epsilon or len(beta) == 0: + change |= follow_symbol.update(follow_X) + + return follows + + @staticmethod + def _register(table, state, symbol, value): + if state not in table: + table[state] = dict() + + row = table[state] + + if symbol not in row: + row[symbol] = [] + + cell = row[symbol] + + if value not in cell: + cell.append(value) + + return len(cell) == 1 + +class Action(tuple): + SHIFT = 'SHIFT' + REDUCE = 'REDUCE' + OK = 'OK' + + def __str__(self): + try: + action, tag = self + return f"{'S' if action == Action.SHIFT else 'OK' if action == Action.OK else ''}{tag}" + except: + return str(tuple(self)) + + __repr__ = __str__ + +class ShiftReduceParser: + def __init__(self, G, verbose=False): + self.G = G + self.verbose = verbose + self.action = {} + self.goto = {} + self._build_parsing_table() + + def _build_parsing_table(self): + raise NotImplementedError() + + def __call__(self, w): + stack = [ 0 ] + cursor = 0 + output, operations = [], [] + + while True: + state = stack[-1] + lookahead = w[cursor].token_type + if self.verbose: print(stack, w[cursor:]) + + # (Detect error) + try: + action, tag = self.action[state][lookahead][0] + # (Shift case) + if action == Action.SHIFT: + stack.append(tag) + cursor += 1 + operations.append(action) + # (Reduce case) + elif action == Action.REDUCE: + for _ in range(len(tag.Right)): stack.pop() + stack.append(self.goto[stack[-1]][tag.Left][0]) + output.append(tag) + operations.append(action) + # (OK case) + elif action == Action.OK: + # output.reverse() + return output, operations + # (Invalid case) + else: + assert False, 'Must be something wrong!' + except KeyError: + print('Parsing Error:', stack, w[cursor:]) + return w[cursor:][0], None + +class LR1Parser(ShiftReduceParser): + @staticmethod + def expand(item, firsts): + next_symbol = item.NextSymbol + if next_symbol is None or not next_symbol.IsNonTerminal: + return [] + + lookaheads = ContainerSet() + # (Compute lookahead for child items) + for preview in item.Preview(): + lookaheads.hard_update(GrammarTools.compute_local_first(firsts, preview)) + + assert not lookaheads.contains_epsilon + # (Build and return child items) + return [Item(prod, 0, lookaheads) for prod in next_symbol.productions] + + @staticmethod + def compress(items): + centers = {} + + for item in items: + center = item.Center() + try: + lookaheads = centers[center] + except KeyError: + centers[center] = lookaheads = set() + lookaheads.update(item.lookaheads) + + return { Item(x.production, x.pos, set(lookahead)) for x, lookahead in centers.items() } + + @staticmethod + def closure_lr1(items, firsts): + closure = ContainerSet(*items) + + changed = True + while changed: + changed = False + + new_items = ContainerSet() + for item in closure: + new_items.extend(LR1Parser.expand(item, firsts)) + + changed = closure.update(new_items) + + return LR1Parser.compress(closure) + + @staticmethod + def goto_lr1(items, symbol, firsts=None, just_kernel=False): + assert just_kernel or firsts is not None, '`firsts` must be provided if `just_kernel=False`' + items = frozenset(item.NextItem() for item in items if item.NextSymbol == symbol) + return items if just_kernel else LR1Parser.closure_lr1(items, firsts) + + + def build_LR1_automaton(self): + G = self.augmentedG = self.G.AugmentedGrammar(True) + + firsts = GrammarTools.compute_firsts(G) + firsts[G.EOF] = ContainerSet(G.EOF) + + start_production = G.startSymbol.productions[0] + start_item = Item(start_production, 0, lookaheads=(G.EOF,)) + start = frozenset([start_item]) + + closure = LR1Parser.closure_lr1(start, firsts) + automaton = State(frozenset(closure), True) + + pending = [ start ] + visited = { start: automaton } + + while pending: + current = pending.pop() + current_state = visited[current] + + for symbol in G.terminals + G.nonTerminals: + # (Get/Build `next_state`) + kernels = LR1Parser.goto_lr1(current_state.state, symbol, just_kernel=True) + + if not kernels: + continue + + try: + next_state = visited[kernels] + except KeyError: + pending.append(kernels) + visited[pending[-1]] = next_state = State(frozenset(LR1Parser.goto_lr1(current_state.state, symbol, firsts)), True) + + current_state.add_transition(symbol.Name, next_state) + + # automaton.set_formatter(empty_formatter) + self.automaton = automaton + + def _build_parsing_table(self): + self.is_lr1 = True + self.build_LR1_automaton() + + for i, node in enumerate(self.automaton): + if self.verbose: print(i, '\t', '\n\t '.join(str(x) for x in node.state), '\n') + node.idx = i + node.tag = f'I{i}' + + for node in self.automaton: + idx = node.idx + for item in node.state: + # - Fill `self.Action` and `self.Goto` according to `item`) + # - Feel free to use `self._register(...)`) + if item.IsReduceItem: + prod = item.production + if prod.Left == self.augmentedG.startSymbol: + self.is_lr1 &= GrammarTools._register(self.action, idx, self.augmentedG.EOF, + Action((Action.OK, ''))) + else: + for lookahead in item.lookaheads: + self.is_lr1 &= GrammarTools._register(self.action, idx, lookahead, + Action((Action.REDUCE, prod))) + else: + next_symbol = item.NextSymbol + if next_symbol.IsTerminal: + self.is_lr1 &= GrammarTools._register(self.action, idx, next_symbol, + Action((Action.SHIFT, node[next_symbol.Name][0].idx))) + else: + self.is_lr1 &= GrammarTools._register(self.goto, idx, next_symbol, + node[next_symbol.Name][0].idx) + pass \ No newline at end of file diff --git a/src/engine/cp/pycompiler.py b/src/engine/cp/pycompiler.py new file mode 100644 index 00000000..bba9423d --- /dev/null +++ b/src/engine/cp/pycompiler.py @@ -0,0 +1,519 @@ +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) + self._symbols = [] + + + def __str__(self): + # return "e" + return u'\N{GREEK SMALL LETTER EPSILON}' + + 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 + self.nonTerminals.insert(0, term) + else: + raise Exception("Cannot define more than one start symbol.") + else: + 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." + + # for avoid repeated productions + if production not in production.Left.productions: + 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' + nonterminals = ', '.join(['%s'] * len(self.nonTerminals)) + '\n' + + ans += nonterminals % tuple(self.nonTerminals) + + ans += 'Terminals:\n\t' + + # terminals = mul * (len(self.terminals)-1) + '%s\n' + terminals = ', '.join(['%s'] * len(self.terminals)) + '\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 i, noTerm in enumerate(data['NonTerminals']): + dic[noTerm] = G.NonTerminal(noTerm, not i) + + for p in data['Productions']: + head = p['Head'] + # dic[head] %= Sentence(*[dic[term] for term in p['Body']]) + dic[head] %= sum((dic[term] for term in p['Body'][1:]), dic[p['Body'][0]]) + + 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/engine/cp/semantic.py b/src/engine/cp/semantic.py new file mode 100644 index 00000000..fd5cbd24 --- /dev/null +++ b/src/engine/cp/semantic.py @@ -0,0 +1,331 @@ +import itertools as itt + +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.param_infos = [VariableInfo(f'_{name}_{pname}', ptype) for pname, ptype in zip(param_names, params_types)] + self.return_type = return_type + self.return_info = VariableInfo(f'_{name}', 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.return_type == self.return_type and \ + other.param_types == self.param_types + +class Type: + def __init__(self, name:str, sealed=False, built_in = False): + self.name = name + self.attributes = [] + self.methods = {} + self.parent = None + self.sealed = sealed + self.built_in = built_in + + def set_parent(self, parent): + if self.parent is not None: + raise SemanticError(f'Parent type is already set for {self.name}.') + if parent.sealed: + raise SemanticError(f'Parent type "{parent.name}" is sealed. Can\'t inherit from it.') + self.parent = parent + + def type_union(self, other): + if self == other: + return other + + t1 = [self] + while t1[-1] != None: + t1.append(t1[-1].parent) + + t2 = [other] + while t2[-1] != None: + t2.append(t2[-1].parent) + + while t1[-2] == t2[-2]: + t1.pop() + t2.pop() + + return t1[-1] + + 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 self.methods[name] + except KeyError: + 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 self.methods: + raise SemanticError(f'Method "{name}" already defined in {self.name}') + # raise SemanticError(f'Method "{name}" already defined in {self.name} with a different signature.') + + method = self.methods[name] = Method(name, param_names, param_types, return_type) + return method + + 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.values()) + output += '\n' if self.methods else '' + output += '}\n' + return output + + def __repr__(self): + return str(self) + +class SelfType(Type): + def __init__(self): + Type.__init__(self, 'SELF_TYPE') + self.sealed = True + + def conforms_to(self, other): + return False + + def bypass(self): + return True + + def __eq__(self, other): + return isinstance(other, SelfType) + +class AutoType(Type): + def __init__(self): + Type.__init__(self, 'AUTO_TYPE') + self.sealed = True + + def union_type(self, other): + return self + + def conforms_to(self, other): + return True + + def bypass(self): + return True + + def __eq__(self, other): + return isinstance(other, Type) + +class ErrorType(Type): + def __init__(self, message = ""): + Type.__init__(self, '') + self.sealed = True + self.message = message + + def union_type(self, other): + return self + + def conforms_to(self, other): + return True + + def bypass(self): + return True + + def __eq__(self, other): + return isinstance(other, Type) + +class Context: + def __init__(self): + self.types = {} + + def create_type(self, name:str, builtin = False): + if name in self.types: + raise SemanticError(f'Type with the same name ({name}) already in context.') + typex = self.types[name] = Type(name,built_in=builtin) + return typex + + def add_type(self, typex): + if typex.name in self.types: + raise SemanticError(f'Type with the same name ({typex.name}) already in context.') + self.types[typex.name] = typex + return typex + + def get_type(self, name:str): + 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 + self.infered = not isinstance(vtype, AutoType) + self.calls = [] + self.assigns = [] + + def set_calls(self, typex): + if not self.infered and not isinstance(typex, AutoType): + self.calls.append(typex) + + def set_assigns(self, typex): + if not self.infered: + self.assigns.append(typex) + + def infer_type(self): + if not self.infered: + message = "" + t = all(not x.built_in for x in self.calls + self.assigns) + #print(t) + if t: + call = None + for typex in self.calls: + if not call or typex.conforms_to(call): + call = typex + elif call.conforms_to(typex): + pass + else: + call = ErrorType() + break + + assign = None + for typex in self.assigns: + assign = typex if not assign else assign.type_union(typex) + + if assign: + self.type = assign if not call or assign.conforms_to(call) else ErrorType() + else: + self.type = call + + if not self.type or isinstance(self.type, ErrorType): + self.type = AutoType() + + self.infered = not isinstance(self.type, AutoType) + self.calls = [] + self.assigns = [] + + return self.infered, message + + else: + self.type = None + for x in self.assigns + self.calls: + if x.built_in: + self.type = x + break + error = [] + + #print(self.type.name) + + for x in self.assigns + self.calls: + if not x.conforms_to(self.type): + error.append(x) + + message = f"Incompatible Types {self.type.name} and " + " ".join(e.name for e in error) if error else "" + + self.infered = True + + self.calls = [] + self.assigns = [] + + return True, message + + + return False, "" + + def __repr__(self): + return str(self) + + def __str__(self): + return f'Variable Name: {self.name}, Variable Type: {self.type} \n' + + +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) + + def __repr__(self): + return str(self) + + def __str__(self): + return "".join(str(i) for i in self.locals) + "".join(str(s) for s in self.children) + #return f'Scope: {self.index}\n' + "\n".join(str(x) for x in self.locals) + "\n".join(str(s) for s in self.children) \ No newline at end of file diff --git a/src/engine/cp/utils.py b/src/engine/cp/utils.py new file mode 100644 index 00000000..80f649d8 --- /dev/null +++ b/src/engine/cp/utils.py @@ -0,0 +1,88 @@ +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 items(self): + return self.set.union({u'\N{GREEK SMALL LETTER EPSILON}'} if self.contains_epsilon else {}) + + 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 + +class Token: + """ + Basic token class. + + Parameters + ---------- + lex : str + Token's lexeme. + token_type : Enum + Token's type. + """ + + def __init__(self, lex, token_type, line=0, column=0): + self.lex = lex + self.token_type = token_type + self.line = line + self.column = column + + def __str__(self): + return f'{self.token_type}: {self.lex}' + + def __repr__(self): + return str(self) + + @property + def is_valid(self): + return True diff --git a/src/engine/cp/visitor.py b/src/engine/cp/visitor.py new file mode 100644 index 00000000..500298bc --- /dev/null +++ b/src/engine/cp/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/engine/parser.py b/src/engine/parser.py new file mode 100644 index 00000000..5dab3c23 --- /dev/null +++ b/src/engine/parser.py @@ -0,0 +1,310 @@ +from .cp import Grammar, LR1Parser + +# AST Classes +class Node: + pass + +class ProgramNode(Node): + def __init__(self, declarations): + self.declarations = declarations + self.line = declarations[0].line + self.column = declarations[0].column + +class DeclarationNode(Node): + pass + +class ClassDeclarationNode(DeclarationNode): + def __init__(self, idx, features, parent=None): + self.id = idx + self.parent = parent + self.features = features + self.line = idx.line + self.column = idx.column + +class AttrDeclarationNode(DeclarationNode): + def __init__(self, idx, typex, expression=None): + self.id = idx + self.type = typex + self.expression = expression + self.line = idx.line + self.column = idx.column + +class FuncDeclarationNode(DeclarationNode): + def __init__(self, idx, params, return_type, body): + self.id = idx + self.params = params + self.type = return_type + self.body = body + self.line = idx.line + self.column = idx.column + +class ExpressionNode(Node): + pass + +class IfThenElseNode(ExpressionNode): + def __init__(self, condition, if_body, else_body): + self.condition = condition + self.if_body = if_body + self.else_body = else_body + self.line = condition.line + self.column = condition.column + +class WhileLoopNode(ExpressionNode): + def __init__(self, condition, body): + self.condition = condition + self.body = body + self.line = condition.line + self.column = condition.column + + +class BlockNode(ExpressionNode): + def __init__(self, expressions): + self.expressions = expressions + self.line = expressions[-1].line + self.column = expressions[-1].column + +class LetInNode(ExpressionNode): + def __init__(self, let_body, in_body): + self.let_body = let_body + self.in_body = in_body + self.line = in_body.line + self.column = in_body.column + +class CaseOfNode(ExpressionNode): + def __init__(self, expression, branches): + self.expression = expression + self.branches = branches + self.line = expression.line + self.column = expression.column + +class AssignNode(ExpressionNode): + def __init__(self, idx, expression): + self.id = idx + self.expression = expression + self.line = idx.line + self.column = idx.column + +class UnaryNode(ExpressionNode): + def __init__(self, expression): + self.expression = expression + self.line = expression.line + self.column = expression.column + +class NotNode(UnaryNode): + pass + +class BinaryNode(ExpressionNode): + def __init__(self, left, right): + self.left = left + self.right = right + self.line = left.line + self.column = left.column + +class LessEqualNode(BinaryNode): + pass + +class LessNode(BinaryNode): + pass + +class EqualNode(BinaryNode): + pass + +class ArithmeticNode(BinaryNode): + pass + +class PlusNode(ArithmeticNode): + pass + +class MinusNode(ArithmeticNode): + pass + +class StarNode(ArithmeticNode): + pass + +class DivNode(ArithmeticNode): + pass + +class IsVoidNode(UnaryNode): + pass + +class ComplementNode(UnaryNode): + pass + +class FunctionCallNode(ExpressionNode): + def __init__(self, obj, idx, args, typex=None): + self.obj = obj + self.id = idx + self.args = args + self.type = typex + self.line = idx.line + self.column = idx.column + +class MemberCallNode(ExpressionNode): + def __init__(self, idx, args): + self.id = idx + self.args = args + self.line = idx.line + self.column = idx.column + +class NewNode(ExpressionNode): + def __init__(self, typex): + self.type = typex + self.line = typex.line + self.column = typex.column + +class AtomicNode(ExpressionNode): + def __init__(self, token): + self.token = token + self.line = token.line + self.column = token.column + +class IntegerNode(AtomicNode): + pass + +class IdNode(AtomicNode): + pass + +class StringNode(AtomicNode): + pass + +class BoolNode(AtomicNode): + pass + + + +# grammar +CoolGrammar = Grammar() + +# non-terminals +program = CoolGrammar.NonTerminal('', startSymbol=True) +class_list, def_class = CoolGrammar.NonTerminals(' ') +feature_list, feature = CoolGrammar.NonTerminals(' ') +param_list, param = CoolGrammar.NonTerminals(' ') +expr, member_call, expr_list, let_list, case_list = CoolGrammar.NonTerminals(' ') +truth_expr, comp_expr = CoolGrammar.NonTerminals(' ') +arith, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') +atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') + +# terminals +classx, inherits = CoolGrammar.Terminals('class inherits') +ifx, then, elsex, fi = CoolGrammar.Terminals('if then else fi') +whilex, loop, pool = CoolGrammar.Terminals('while loop pool') +let, inx = CoolGrammar.Terminals('let in') +case, of, esac = CoolGrammar.Terminals('case of esac') +semi, colon, comma, dot, at, opar, cpar, ocur, ccur, larrow, rarrow = CoolGrammar.Terminals('; : , . @ ( ) { } <- =>') +plus, minus, star, div, isvoid, compl = CoolGrammar.Terminals('+ - * / isvoid ~') +notx, less, leq, equal = CoolGrammar.Terminals('not < <= =') +new, idx, typex, integer, string, boolx = CoolGrammar.Terminals('new id type integer string bool') + +# productions +program %= class_list, lambda h, s: ProgramNode(s[1]) + +# ??? +class_list %= def_class + class_list, lambda h, s: [s[1]] + s[2] +class_list %= def_class, lambda h, s: [s[1]] + +# ??? +def_class %= classx + typex + ocur + feature_list + ccur + semi, lambda h, s: ClassDeclarationNode(s[2], s[4]) +def_class %= classx + typex + inherits + typex + ocur + feature_list + ccur + semi, lambda h, s: ClassDeclarationNode(s[2], s[6], s[4]) + +# ??? +feature_list %= feature + feature_list, lambda h, s: [s[1]] + s[2] +feature_list %= CoolGrammar.Epsilon, lambda h, s: [] + +# ??? +feature %= idx + colon + typex + semi, lambda h, s: AttrDeclarationNode(s[1], s[3]) +feature %= idx + colon + typex + larrow + expr + semi, lambda h, s: AttrDeclarationNode(s[1], s[3], s[5]) + +# ??? +feature %= idx + opar + param_list + cpar + colon + typex + ocur + expr + ccur + semi, lambda h, s: FuncDeclarationNode(s[1], s[3], s[6], s[8]) +feature %= idx + opar + cpar + colon + typex + ocur + expr + ccur + semi, lambda h, s: FuncDeclarationNode(s[1], [], s[5], s[7]) + +# ??? +param_list %= param, lambda h, s: [s[1]] +param_list %= param + comma + param_list, lambda h, s: [s[1]] + s[3] + +# ??? +param %= idx + colon + typex, lambda h, s: (s[1], s[3]) + +# ??? +expr %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) +expr %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) +expr %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) +expr %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) +expr %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) +expr %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) +expr %= truth_expr, lambda h, s: s[1] + +# ??? +expr_list %= expr + semi, lambda h, s: [s[1]] +expr_list %= expr + semi + expr_list, lambda h, s: [s[1]] + s[3] + +# ??? +let_list %= idx + colon + typex, lambda h, s: [(s[1], s[3], None)] +let_list %= idx + colon + typex + larrow + expr, lambda h, s: [(s[1], s[3], s[5])] +let_list %= idx + colon + typex + comma + let_list, lambda h, s: [(s[1], s[3], None)] + s[5] +let_list %= idx + colon + typex + larrow + expr + comma + let_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] + +# ??? +case_list %= idx + colon + typex + rarrow + expr + semi, lambda h, s: [(s[1], s[3], s[5])] +case_list %= idx + colon + typex + rarrow + expr + semi + case_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] + +# ??? +truth_expr %= notx + truth_expr, lambda h, s: NotNode(s[2]) +truth_expr %= comp_expr, lambda h, s: s[1] + +# ??? +comp_expr %= comp_expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) +comp_expr %= comp_expr + less + arith, lambda h, s: LessNode(s[1], s[3]) +comp_expr %= comp_expr + equal + arith, lambda h, s: EqualNode(s[1], s[3]) +comp_expr %= arith, lambda h, s: s[1] + +# ??? +arith %= arith + plus + term, lambda h, s: PlusNode(s[1], s[3]) +arith %= arith + minus + term, lambda h, s: MinusNode(s[1], s[3]) +arith %= term, lambda h, s: s[1] + +# ??? +term %= term + star + factor, lambda h, s: StarNode(s[1], s[3]) +term %= term + div + factor, lambda h, s: DivNode(s[1], s[3]) +term %= factor, lambda h, s: s[1] + +# ??? +factor %= isvoid + factor_2, lambda h, s: IsVoidNode(s[2]) +factor %= factor_2, lambda h, s: s[1] + +# ??? +factor_2 %= compl + atom, lambda h, s: ComplementNode(s[2]) +factor_2 %= atom, lambda h, s: s[1] + +# ??? +atom %= atom + func_call, lambda h, s: FunctionCallNode(s[1], *s[2]) +atom %= member_call, lambda h, s: s[1] +atom %= new + typex, lambda h, s: NewNode(s[2]) +atom %= opar + expr + cpar, lambda h, s: s[2] +atom %= idx, lambda h, s: IdNode(s[1]) +atom %= integer, lambda h, s: IntegerNode(s[1]) +atom %= string, lambda h, s: StringNode(s[1]) +atom %= boolx, lambda h, s: BoolNode(s[1]) + +# ??? +func_call %= dot + idx + opar + arg_list + cpar, lambda h, s: (s[2], s[4]) +func_call %= dot + idx + opar + cpar, lambda h, s: (s[2], []) +func_call %= at + typex + dot + idx + opar + arg_list + cpar, lambda h, s: (s[4], s[6], s[2]) +func_call %= at + typex + dot + idx + opar + cpar, lambda h, s: (s[4], [], s[2]) + +# ??? +arg_list %= expr, lambda h, s: [s[1]] +arg_list %= expr + comma + arg_list, lambda h, s: [s[1]] + s[3] + +# ??? +member_call %= idx + opar + arg_list + cpar, lambda h, s: MemberCallNode(s[1], s[3]) +member_call %= idx + opar + cpar, lambda h, s: MemberCallNode(s[1], []) + +# parser +CoolParser = LR1Parser(CoolGrammar) + +if __name__ == '__main__': + if CoolParser.is_lr1: + print('The grammar is LR1') + print(CoolGrammar) \ No newline at end of file diff --git a/src/engine/semantic_errors.py b/src/engine/semantic_errors.py new file mode 100644 index 00000000..a57f776d --- /dev/null +++ b/src/engine/semantic_errors.py @@ -0,0 +1,13 @@ +ERROR_ON_LN_COL = 'Line %d, Column %d: ' +WRONG_SIGNATURE = 'Method "%s" of "%s" already defined in "%s" with a different signature.' +SELF_IS_READONLY = 'Variable "self" is read-only.' +LOCAL_ALREADY_DEFINED = 'Variable "%s" is already defined in method "%s".' +INCOMPATIBLE_TYPES = 'Cannot convert "%s" into "%s".' +VARIABLE_NOT_DEFINED = 'Variable "%s" is not defined in "%s".' +INVALID_OPERATION = 'Operation is not defined between "%s" and "%s".' +CYCLIC_HERITAGE = 'Type "%s" froms a cyclic heritage chain' +INFERENCE_ON = 'Ln %d, Col %d: ' +INF_ATTR = 'On class "%s", attribute "%s": type "%s"' +INF_PARAM = 'On method "%s" of class "%s", param "%s": type "%s"' +INF_RETRN = 'Return of method "%s" in class "%s", type "%s"' +INF_VAR = 'Varible "%s", type "%s"' \ No newline at end of file diff --git a/src/engine/visitors/__init__.py b/src/engine/visitors/__init__.py new file mode 100644 index 00000000..bb8960c8 --- /dev/null +++ b/src/engine/visitors/__init__.py @@ -0,0 +1,5 @@ +from .builder import Builder +from .checker import Checker +from .collector import Collector +from .format import Format +from .inferer import Inferer \ No newline at end of file diff --git a/src/engine/visitors/builder.py b/src/engine/visitors/builder.py new file mode 100644 index 00000000..9217175e --- /dev/null +++ b/src/engine/visitors/builder.py @@ -0,0 +1,113 @@ +from engine.cp import ErrorType, SelfType, SemanticError, visitor +from engine.parser import AttrDeclarationNode, FuncDeclarationNode, ProgramNode, ClassDeclarationNode +from engine.semantic_errors import ERROR_ON_LN_COL + +class Builder: + def __init__(self, context, errors = []): + self.context = context + self.current_type = None + self.errors = errors + + #Construyendo tipos Build-In + + self.object_type = self.context.get_type('Object') + + self.io_type = self.context.get_type('IO') + self.io_type.set_parent(self.object_type) + + self.int_type = self.context.get_type('Int') + self.int_type.set_parent(self.object_type) + self.int_type.sealed = True + + self.string_type = self.context.get_type('String') + self.string_type.set_parent(self.object_type) + self.string_type.sealed = True + + self.bool_type = self.context.get_type('Bool') + self.bool_type.set_parent(self.object_type) + self.bool_type.sealed = True + + self.object_type.define_method('abort', [], [], self.object_type) + self.object_type.define_method('type_name', [], [], self.string_type) + self.object_type.define_method('copy', [], [], SelfType()) + + self.io_type.define_method('out_string', ['x'], [self.string_type], SelfType()) + self.io_type.define_method('out_int', ['x'], [self.int_type], SelfType()) + self.io_type.define_method('in_string', [], [], self.string_type) + self.io_type.define_method('in_int', [], [], self.int_type) + + self.string_type.define_method('length', [], [], self.int_type) + self.string_type.define_method('concat', ['s'], [self.string_type], self.string_type) + self.string_type.define_method('substr', ['i', 'l'], [self.int_type, self.int_type], self.string_type) + + @visitor.on('node') + def visit(self, node): + pass + + @visitor.when(ProgramNode) + def visit(self, node): + for class_def in node.declarations: + self.visit(class_def) + try: + self.context.get_type('Main').get_method('main') + except SemanticError: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "Class Main and feature main needed") + + @visitor.when(ClassDeclarationNode) + def visit(self, node): + self.current_type = self.context.get_type(node.id.lex) + + parent = node.parent + if parent: + try: + parent_type = self.context.get_type(parent.lex) + self.current_type.set_parent(parent_type) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + self.current_type.set_parent(self.object_type) + else: + self.current_type.set_parent(self.object_type) + + for feature in node.features: + self.visit(feature) + + @visitor.when(AttrDeclarationNode) + def visit(self, node): + try: + attr_type = self.context.get_type(node.type.lex) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + attr_type = ErrorType() + + try: + self.current_type.define_attribute(node.id.lex, attr_type) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + + @visitor.when(FuncDeclarationNode) + def visit(self, node): + arg_names, arg_types = [], [] + for ids, types in node.params: + try: + arg_type = self.context.get_type(types.lex) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + arg_type = ErrorType() + else: + if isinstance(arg_type, SelfType): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Type "{arg_type.name}" can not be used as a parameter type') + arg_type = ErrorType() + + arg_names.append(ids.lex) + arg_types.append(arg_type) + + try: + ret_type = self.context.get_type(node.type.lex) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + ret_type = ErrorType() + + try: + self.current_type.define_method(node.id.lex, arg_names, arg_types, ret_type) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) \ No newline at end of file diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py new file mode 100644 index 00000000..2f319657 --- /dev/null +++ b/src/engine/visitors/checker.py @@ -0,0 +1,419 @@ +from engine.cp import visitor, ErrorType, SelfType, AutoType, SemanticError, Scope +from engine.parser import ProgramNode, ClassDeclarationNode, AttrDeclarationNode, FuncDeclarationNode +from engine.parser import IfThenElseNode, WhileLoopNode, BlockNode, LetInNode, CaseOfNode +from engine.parser import AssignNode, UnaryNode, BinaryNode, LessEqualNode, LessNode, EqualNode, ArithmeticNode +from engine.parser import NotNode, IsVoidNode, ComplementNode, FunctionCallNode, MemberCallNode, NewNode, AtomicNode +from engine.parser import IntegerNode, IdNode, StringNode, BoolNode +from engine.semantic_errors import ERROR_ON_LN_COL, WRONG_SIGNATURE, SELF_IS_READONLY, LOCAL_ALREADY_DEFINED, INCOMPATIBLE_TYPES, VARIABLE_NOT_DEFINED, INVALID_OPERATION, CYCLIC_HERITAGE + +class Checker: + def __init__(self, context, errors=[]): + self.context = context + self.current_type = None + self.current_method = None + self.errors = errors + + #Tipos Built-in + self.object_type = self.context.get_type('Object') + self.io_type = self.context.get_type('IO') + self.int_type = self.context.get_type('Int') + self.string_type = self.context.get_type('String') + self.bool_type = self.context.get_type('Bool') + + @visitor.on('node') + def visit(self, node, scope): + pass + + @visitor.when(ProgramNode) + def visit(self, node, scope = None): + scope = Scope() + for d in node.declarations: + self.visit(d,scope.create_child()) + return scope + + @visitor.when(ClassDeclarationNode) + def visit(self, node, scope): + self.current_type = self.context.get_type(node.id.lex) + + #Verificando ciclos en la herencia + parent = self.current_type.parent + + while parent: + if parent == self.current_type: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + CYCLIC_HERITAGE % (parent.name)) + self.current_type.parent = self.object_type + break + + parent = parent.parent + + for a in self.current_type.attributes: + scope.define_variable(a.name, a.type) + + for f in node.features: + self.visit(f, scope.create_child()) + + @visitor.when(FuncDeclarationNode) + def visit(self, node, scope): + self.current_method = self.current_type.get_method(node.id.lex) + + #Verificar funciones redefinidas + parent = self.current_type.parent + if parent: + try: + p_method = parent.get_method(node.id.lex) + except SemanticError: + pass + else: + if p_method.return_type != self.current_method.return_type or p_method.param_types != self.current_method.param_types: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + + scope.define_variable('self', self.current_type) + + for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): + scope.define_variable(pname, ptype) + + body = node.body + self.visit(body, scope.create_child()) + + body_type = body.static_type + return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type + + if not body_type.conforms_to(return_type): + self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) + + @visitor.when(AttrDeclarationNode) + def visit(self, node, scope): + expr = node.expression + if expr: + self.visit(expr, scope.create_child()) + expr_type = expr.static_type + + attr = self.current_type.get_attribute(node.id.lex) + node_type = attr.type + node_type = self.current_type if isinstance(node_type, SelfType) else node_type + if not expr_type.conforms_to(node_type): + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + + @visitor.when(FuncDeclarationNode) + def visit(self, node, scope): + self.current_method = self.current_type.get_method(node.id.lex) + + # check ilegal redefined func + parent = self.current_type.parent + if parent: + try: + parent_method = parent.get_method(node.id.lex) + except SemanticError: + pass + else: + if parent_method.param_types != self.current_method.param_types or parent_method.return_type != self.current_method.return_type: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + + scope.define_variable('self', self.current_type) + + for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): + scope.define_variable(pname, ptype) + + body = node.body + self.visit(body, scope.create_child()) + + body_type = body.static_type + return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type + + if not body_type.conforms_to(return_type): + self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) + + @visitor.when(IfThenElseNode) + def visit(self, node, scope): + condition = node.condition + self.visit(condition, scope.create_child()) + + condition_type = condition.static_type + if not condition_type.conforms_to(self.bool_type): + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + + self.visit(node.if_body, scope.create_child()) + self.visit(node.else_body, scope.create_child()) + + if_type = node.if_body.static_type + else_type = node.else_body.static_type + node.static_type = if_type.type_union(else_type) + + @visitor.when(WhileLoopNode) + def visit(self, node, scope): + condition = node.condition + self.visit(condition, scope.create_child()) + + condition_type = condition.static_type + if not condition_type.conforms_to(self.bool_type): + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + + self.visit(node.body, scope.create_child()) + + node.static_type = self.object_type + + @visitor.when(BlockNode) + def visit(self, node, scope): + for expr in node.expressions: + self.visit(expr, scope.create_child()) + + node.static_type = node.expressions[-1].static_type + + @visitor.when(LetInNode) + def visit(self, node, scope): + for idx, typex, expr in node.let_body: + try: + node_type = self.context.get_type(typex.lex) + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) + node_type = ErrorType() + + id_type = self.current_type if isinstance(node_type, SelfType) else node_type + child = scope.create_child() + + if expr: + self.visit(expr, child) + expr_type = expr.static_type + if not expr_type.conforms_to(id_type): + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) + + scope.define_variable(idx.lex, id_type) + + self.visit(node.in_body, scope.create_child()) + + node.static_type = node.in_body.static_type + + @visitor.when(CaseOfNode) + def visit(self, node, scope): + self.visit(node.expression, scope.create_child()) + + node.static_type = None + + for idx, typex, expr in node.branches: + try: + node_type = self.context.get_type(typex.lex) + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) + node_type = ErrorType() + else: + if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + f'Type "{node_type.name}" can not be used as case type') + node_type = ErrorType() + + id_type = node_type + + child_scope = scope.create_child() + child_scope.define_variable(idx.lex, id_type) + self.visit(expr, child_scope) + expr_type = expr.static_type + + node.static_type = node.static_type.type_union(expr_type) if node.static_type else expr_type + + @visitor.when(AssignNode) + def visit(self, node, scope): + expression = node.expression + self.visit(expression, scope.create_child()) + expr_type = expression.static_type + + if scope.is_defined(node.id.lex): + var = scope.find_variable(node.id.lex) + node_type = var.type + + if var.name == 'self': + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + SELF_IS_READONLY) + elif not expr_type.conforms_to(node_type): + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) + + node.static_type = expr_type + + @visitor.when(NotNode) + def visit(self, node, scope): + expression = node.expression + self.visit(expression, scope.create_child()) + + expr_type = expression.static_type + if not expr_type.conforms_to(self.bool_type): + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, self.bool_type.name)) + + node.static_type = self.bool_type + + @visitor.when(LessEqualNode) + def visit(self, node, scope): + self.visit(node.left, scope.create_child()) + left_type = node.left.static_type + + self.visit(node.right, scope.create_child()) + right_type = node.right.static_type + + if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (right_type.name, self.int_type.name)) + + node.static_type = self.bool_type + + @visitor.when(LessNode) + def visit(self, node, scope): + self.visit(node.left, scope.create_child()) + left_type = node.left.static_type + + self.visit(node.right, scope.create_child()) + right_type = node.right.static_type + + if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (right_type.name, self.int_type.name)) + + node.static_type = self.bool_type + + @visitor.when(EqualNode) + def visit(self, node, scope): + self.visit(node.left, scope.create_child()) + left_type = node.left.static_type + + self.visit(node.right, scope.create_child()) + right_type = node.right.static_type + + if isinstance(left_type, AutoType) or isinstance(right_type, AutoType): + pass + elif left_type.conforms_to(self.int_type) ^ right_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + elif left_type.conforms_to(self.string_type) ^ right_type.conforms_to(self.string_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + elif left_type.conforms_to(self.bool_type) ^ right_type.conforms_to(self.bool_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + + node.static_type = self.bool_type + + @visitor.when(ArithmeticNode) + def visit(self, node, scope): + self.visit(node.left, scope.create_child()) + left_type = node.left.static_type + + self.visit(node.right, scope.create_child()) + right_type = node.right.static_type + + if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + + node.static_type = self.int_type + + @visitor.when(IsVoidNode) + def visit(self, node, scope): + self.visit(node.expression, scope.create_child()) + + node.static_type = self.bool_type + + @visitor.when(ComplementNode) + def visit(self, node, scope): + expression = node.expression + self.visit(expression, scope.create_child()) + + expr_type = expression.static_type + if not expr_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, self.int_type.name)) + + node.static_type = self.int_type + + @visitor.when(FunctionCallNode) + def visit(self, node, scope): + self.visit(node.obj, scope.create_child()) + obj_type = node.obj.static_type + + try: + if node.type: + try: + node_type = self.context.get_type(node.type.lex) + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + ex.text) + node_type = ErrorType() + else: + if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): + self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + f'Type "{node_type}" cannot be used as type dispatch') + node_type = ErrorType() + + if not obj_type.conforms_to(node_type): + self.errors.append(ERROR_ON_LN_COL % (node.obj.line, node.obj.column) + INCOMPATIBLE_TYPES % (obj_type.name, node_type.name)) + + obj_type = node_type + + obj_method = obj_type.get_method(node.id.lex) + + node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + node_type = ErrorType() + obj_method = None + + for arg in node.args: + self.visit(arg, scope.create_child()) + + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, param_type in zip(node.args, obj_method.param_types): + arg_type = arg.static_type + + if not arg_type.conforms_to(param_type): + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" can not be dispatched') + + node.static_type = node_type + + @visitor.when(MemberCallNode) + def visit(self, node, scope): + obj_type = self.current_type + + try: + obj_method = obj_type.get_method(node.id.lex) + + node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + node_type = ErrorType() + obj_method = None + + for arg in node.args: + self.visit(arg, scope.create_child()) + + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, param_type in zip(node.args, obj_method.param_types): + arg_type = arg.static_type + + if not arg_type.conforms_to(param_type): + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" canot be dispatched') + + node.static_type = node_type + + @visitor.when(NewNode) + def visit(self, node, scope): + try: + node_type = self.context.get_type(node.type.lex) + except SemanticError as ex: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + node_type = ErrorType() + + node.static_type = node_type + + @visitor.when(IntegerNode) + def visit(self, node, scope): + node.static_type = self.int_type + + @visitor.when(StringNode) + def visit(self, node, scope): + node.static_type = self.string_type + + @visitor.when(IdNode) + def visit(self, node, scope): + if scope.is_defined(node.token.lex): + var = scope.find_variable(node.token.lex) + node_type = var.type + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name)) + node_type = ErrorType() + + node.static_type = node_type + + @visitor.when(BoolNode) + def visit(self, node, scope): + node.static_type = self.bool_type \ No newline at end of file diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py new file mode 100644 index 00000000..3f5473b7 --- /dev/null +++ b/src/engine/visitors/collector.py @@ -0,0 +1,35 @@ +from engine.cp import SemanticError, visitor, Context, SelfType, AutoType +from engine.parser import ProgramNode, ClassDeclarationNode +from engine.semantic_errors import ERROR_ON_LN_COL + +class Collector: + def __init__(self, errors = []): + self.context = Context() + self.errors = errors + + #Tipos especiales + self.context.add_type(SelfType()) + self.context.add_type(AutoType()) + + #Tipos Buit-In + self.context.create_type('Object',builtin = True) + self.context.create_type('IO',builtin = True) + self.context.create_type('Int',builtin = True) + self.context.create_type('String',builtin = True) + self.context.create_type('Bool',builtin = True) + + @visitor.on('node') + def visit(self, node): + pass + + @visitor.when(ProgramNode) + def visit(self, node): + for class_def in node.declarations: + self.visit(class_def) + + @visitor.when(ClassDeclarationNode) + def visit(self, node): + try: + self.context.create_type(node.id.lex) + except SemanticError as se: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) \ No newline at end of file diff --git a/src/engine/visitors/format.py b/src/engine/visitors/format.py new file mode 100644 index 00000000..72329938 --- /dev/null +++ b/src/engine/visitors/format.py @@ -0,0 +1,114 @@ +from engine.cp import visitor +from engine.parser import ProgramNode, ClassDeclarationNode, AttrDeclarationNode, FuncDeclarationNode +from engine.parser import IfThenElseNode, WhileLoopNode, BlockNode, LetInNode, CaseOfNode +from engine.parser import AssignNode, UnaryNode, BinaryNode +from engine.parser import FunctionCallNode, MemberCallNode, NewNode, AtomicNode + +class Format: + @visitor.on('node') + def visit(self, node, tabs): + pass + + @visitor.when(ProgramNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__ProgramNode [ ... ]' + statements = '\n'.join(self.visit(child, tabs + 1) for child in node.declarations) + return f'{ans}\n{statements}' + + @visitor.when(ClassDeclarationNode) + def visit(self, node, tabs=0): + parent = '' if node.parent is None else f"inherits {node.parent.lex}" + ans = '\t' * tabs + f'\\__ClassDeclarationNode: class {node.id.lex} {parent} {{ ... }}' + features = '\n'.join(self.visit(child, tabs + 1) for child in node.features) + return f'{ans}\n{features}' + + @visitor.when(AttrDeclarationNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__AttrDeclarationNode: {node.id.lex}: {node.type.lex}' + (' <- ' if node.expression else '') + ';' + expr = self.visit(node.expression, tabs + 1) if node.expression else None + return f'{ans}' + (f'\n{expr}' if expr else '') + + @visitor.when(FuncDeclarationNode) + def visit(self, node, tabs=0): + params = ', '.join(': '.join(tok.lex for tok in param) for param in node.params) + ans = '\t' * tabs + f'\\__FuncDeclarationNode: {node.id.lex}({params}): {node.type.lex} {{ }}' + body = self.visit(node.body, tabs + 1) + return f'{ans}\n{body}' + + @visitor.when(IfThenElseNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\_IfThenElseNode: if then else fi' + cond = self.visit(node.condition, tabs + 1) + if_body = self.visit(node.if_body, tabs + 1) + else_body = self.visit(node.else_body, tabs + 1) + return f'{ans}\n{cond}\n{if_body}\n{else_body}' + + @visitor.when(WhileLoopNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\_WhileNode: while loop pool' + cond = self.visit(node.condition, tabs + 1) + body = self.visit(node.body, tabs + 1) + return f'{ans}\n{cond}\n{body}' + + @visitor.when(BlockNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\_BlockNode: {{ ; ... ; }}' + expressions = '\n'.join(self.visit(expr, tabs + 1) for expr in node.expressions) + return f'{ans}\n{expressions}' + + @visitor.when(LetInNode) + def visit(self, node, tabs=0): + let_body = ', '.join(f'{idx.lex}: {typex.lex}' + (' <- ' if expr else '') for idx, typex, expr in node.let_body) + ans = '\t' * tabs + f'\\_LetInNode: let {let_body} in ' + lets = '\n'.join(self.visit(expr, tabs + 1) for _, _, expr in node.let_body if expr) + body = self.visit(node.in_body, tabs + 1) + return f'{ans}\n{lets}\n{body}' + + @visitor.when(CaseOfNode) + def visit(self, node, tabs=0): + case_body = ' '.join(f'{idx.lex}: {typex.lex} => ;' for idx, typex, expr in node.branches) + ans = '\t' * tabs + f'\\_CaseOfNode: case of {case_body} esac' + expression = self.visit(node.expression, tabs + 1) + body = '\n'.join(self.visit(expr, tabs + 1) for _, _, expr in node.branches) + return f'{ans}\n{expression}\n{body}' + + @visitor.when(AssignNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\_AssingNode: {node.id.lex} <- ' + expr = self.visit(node.expression, tabs + 1) + return f'{ans}\n{expr}' + + @visitor.when(UnaryNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__{node.__class__.__name__} ' + expression = self.visit(node.expression, tabs + 1) + return f'{ans}\n{expression}' + + @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(FunctionCallNode) + def visit(self, node, tabs=0): + obj = self.visit(node.obj, tabs + 1) + typex = f'@{node.type.lex}' if node.type else '' + ans = '\t' * tabs + f'\\__FunctionCallNode: {typex}.{node.id.lex}(, ..., )' + args = '\n'.join(self.visit(arg, tabs + 1) for arg in node.args) + return f'{ans}\n{obj}\n{args}' + + @visitor.when(MemberCallNode) + def visit(self, node, tabs=0): + ans = '\t' * tabs + f'\\__MemberCallNode: {node.id.lex}(, ..., )' + args = '\n'.join(self.visit(arg, tabs + 1) for arg in node.args) + return f'{ans}\n{args}' + + @visitor.when(NewNode) + def visit(self, node, tabs=0): + return '\t' * tabs + f'\\__ NewNode: new {node.type.lex}' + + @visitor.when(AtomicNode) + def visit(self, node, tabs=0): + return '\t' * tabs + f'\\__ {node.__class__.__name__}: {node.token.lex}' \ No newline at end of file diff --git a/src/engine/visitors/inferer.py b/src/engine/visitors/inferer.py new file mode 100644 index 00000000..0a64a232 --- /dev/null +++ b/src/engine/visitors/inferer.py @@ -0,0 +1,335 @@ +from engine.cp import visitor, ErrorType, SelfType, AutoType, SemanticError +from engine.parser import ProgramNode, ClassDeclarationNode, AttrDeclarationNode, FuncDeclarationNode +from engine.parser import IfThenElseNode, WhileLoopNode, BlockNode, LetInNode, CaseOfNode +from engine.parser import AssignNode, UnaryNode, BinaryNode, LessEqualNode, LessNode, EqualNode, ArithmeticNode +from engine.parser import NotNode, IsVoidNode, ComplementNode, FunctionCallNode, MemberCallNode, NewNode, AtomicNode +from engine.parser import IntegerNode, IdNode, StringNode, BoolNode +from engine.semantic_errors import ERROR_ON_LN_COL, INFERENCE_ON, INF_ATTR, INF_PARAM, INF_RETRN, INF_VAR + +class Inferer: + def __init__(self, context, errors=[], inferences=[]): + self.context = context + self.current_type = None + self.current_method = None + self.errors = errors + self.inferences = inferences + + # search built-in types + self.object_type = self.context.get_type('Object') + self.io_type = self.context.get_type('IO') + self.int_type = self.context.get_type('Int') + self.string_type = self.context.get_type('String') + self.bool_type = self.context.get_type('Bool') + + @visitor.on('node') + def visit(self, node, scope): + pass + + @visitor.when(ProgramNode) + def visit(self, node, scope): + self.changed = False + + for declaration, child_scope in zip(node.declarations, scope.children): + self.visit(declaration, child_scope) + + return self.changed + + @visitor.when(ClassDeclarationNode) + def visit(self, node, scope): + self.current_type = self.context.get_type(node.id.lex) + + for feature, child_scope in zip(node.features, scope.children): + self.visit(feature, child_scope) + + for attr, var in zip(self.current_type.attributes, scope.locals): + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + attr.type = var.type + self.inferences.append(INF_ATTR % (self.current_type.name, attr.name, var.type.name)) + + @visitor.when(AttrDeclarationNode) + def visit(self, node, scope): + expression = node.expression + if expression: + attr = self.current_type.get_attribute(node.id.lex) + + self.visit(expression, scope.children[0], attr.type) + expr_type = expression.static_type + + var = scope.find_variable(node.id.lex) + var.set_calls(expr_type) + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + attr.type = var.type + self.inferences.append(INF_ATTR % (self.current_type.name, attr.name, var.type.name)) + + @visitor.when(FuncDeclarationNode) + def visit(self, node, scope): + self.current_method = self.current_type.get_method(node.id.lex) + + return_type = self.current_method.return_type + self.visit(node.body, scope.children[0], self.current_type if isinstance(return_type, SelfType) else return_type) + + for i, var in enumerate(scope.locals[1:]): + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + self.current_method.param_types[i] = var.type + self.inferences.append(INF_PARAM % (self.current_method.name, self.current_type.name, var.name, var.type.name)) + + body_type = node.body.static_type + var = self.current_method.return_info + var.set_assigns(body_type) + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + self.current_method.return_type = var.type + self.inferences.append(INF_RETRN % (self.current_method.name, self.current_type.name, var.type.name)) + + @visitor.when(IfThenElseNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.condition, scope.children[0], self.bool_type) + + self.visit(node.if_body, scope.children[1]) + self.visit(node.else_body, scope.children[2]) + + if_type = node.if_body.static_type + else_type = node.else_body.static_type + node.static_type = if_type.type_union(else_type) + + @visitor.when(WhileLoopNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.condition, scope.children[0], self.bool_type) + + self.visit(node.body, scope.children[1]) + + node.static_type = self.object_type + + @visitor.when(BlockNode) + def visit(self, node, scope, expected_type=None): + for expr, child_scope in zip(node.expressions[:-1], scope.children[:-1]): + self.visit(expr, child_scope) + # posible inferencia + self.visit(node.expressions[-1], scope.children[-1], expected_type) + + node.static_type = node.expressions[-1].static_type + + @visitor.when(LetInNode) + def visit(self, node, scope, expected_type=None): + for (idx, typex, expr), child_scope, (i, var) in zip(node.let_body, scope.children[:-1], enumerate(scope.locals)): + if expr: + self.visit(expr, child_scope, var.type if var.infered else None) + expr_type = expr.static_type + + var.set_calls(expr_type) + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + typex.name = var.type.name + self.inferences.append(INFERENCE_ON % (idx.line, idx.column) + INF_VAR % (var.name, var.type.name)) + + self.visit(node.in_body, scope.children[-1], expected_type) + + for i, var in enumerate(scope.locals): + val, error = var.infer_type() + if val: + if error: + self.errors.append("On " + node.id.lex + " " + ERROR_ON_LN_COL % (node.line, node.column) + error) + self.changed = True + idx, typex, _ = node.let_body[i] + typex.name = var.type.name + self.inferences.append(INFERENCE_ON % (idx.line, idx.column) + INF_VAR % (var.name, var.type.name)) + + node.static_type = node.in_body.static_type + + @visitor.when(CaseOfNode) + def visit(self, node, scope, expected_type=None): + self.visit(node.expression, scope.children[0]) + + node.static_type = None + + for (idx, typex, expr), child_scope in zip(node.branches, scope.children[1:]): + self.visit(expr, child_scope) + expr_type = expr.static_type + + node.static_type = node.static_type.type_union(expr_type) if node.static_type else expr_type + + @visitor.when(AssignNode) + def visit(self, node, scope, expected_type=None): + var = scope.find_variable(node.id.lex) if scope.is_defined(node.id.lex) else None + + self.visit(node.expression, scope.children[0], var.type if var and var.infered else expected_type) + expr_type = node.expression.static_type + + var.set_assigns(expr_type) + + node.static_type = expr_type + + @visitor.when(NotNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.expression, scope.children[0], self.bool_type) + + node.static_type = self.bool_type + + @visitor.when(LessEqualNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.left, scope.children[0], self.int_type) + + # posible inferencia + self.visit(node.right, scope.children[1], self.int_type) + + node.static_type = self.bool_type + + @visitor.when(LessNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.left, scope.children[0], self.int_type) + + # posible inferencia + self.visit(node.right, scope.children[1], self.int_type) + + node.static_type = self.bool_type + + @visitor.when(EqualNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.left, scope.children[0], node.right.static_type) + + # posible inferencia + self.visit(node.right, scope.children[1], node.left.static_type) + + node.static_type = self.bool_type + + @visitor.when(ArithmeticNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.left, scope.children[0], self.int_type) + + # posible inferencia + self.visit(node.right, scope.children[1], self.int_type) + + node.static_type = self.int_type + + @visitor.when(IsVoidNode) + def visit(self, node, scope, expected_type=None): + self.visit(node.expression, scope.children[0]) + + node.static_type = self.bool_type + + @visitor.when(ComplementNode) + def visit(self, node, scope, expected_type=None): + # posible inferencia + self.visit(node.expression, scope.children[0], self.int_type) + + node.static_type = self.int_type + + @visitor.when(FunctionCallNode) + def visit(self, node, scope, expected_type=None): + node_type = None + if node.type: + try: + node_type = self.context.get_type(node.type.lex) + except SemanticError: + node_type = ErrorType() + else: + if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): + node_type = ErrorType() + + self.visit(node.obj, scope.children[0], node_type) + obj_type = node.obj.static_type + + try: + obj_type = node_type if node_type else obj_type + + obj_method = obj_type.get_method(node.id.lex) + + # setear el expected_type al retorno + node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + except SemanticError: + node_type = ErrorType() + obj_method = None + + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, var, child_scope in zip(node.args, obj_method.param_infos, scope.children[1:]): + self.visit(arg, child_scope, var.type if var.infered else None) + # inferir var.type por arg_type + else: + for arg, child_scope in zip(node.args, scope.children[1:]): + self.visit(arg, child_scope) + + node.static_type = node_type + + @visitor.when(MemberCallNode) + def visit(self, node, scope, expected_type=None): + obj_type = self.current_type + + try: + obj_method = obj_type.get_method(node.id.lex) + + # setear el expected_type al retorno + node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + except SemanticError: + node_type = ErrorType() + obj_method = None + + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, var, child_scope in zip(node.args, obj_method.param_infos, scope.children): + self.visit(arg, child_scope, var.type if var.infered else None) + # inferir var.type por arg_type + else: + for arg, child_scope in zip(node.args, scope.children): + self.visit(arg, child_scope) + + + node.static_type = node_type + + @visitor.when(NewNode) + def visit(self, node, scope, expected_type=None): + try: + node_type = self.context.get_type(node.type.lex) + except SemanticError: + node_type = ErrorType() + + node.static_type = node_type + + @visitor.when(IntegerNode) + def visit(self, node, scope, expected_type=None): + node.static_type = self.int_type + + @visitor.when(StringNode) + def visit(self, node, scope, expected_type=None): + node.static_type = self.string_type + + @visitor.when(IdNode) + def visit(self, node, scope, expected_type=None): + if scope.is_defined(node.token.lex): + var = scope.find_variable(node.token.lex) + + if expected_type: + var.set_calls(expected_type) + + node_type = var.type if var.infered else AutoType() + else: + node_type = ErrorType() + + node.static_type = node_type + + @visitor.when(BoolNode) + def visit(self, node, scope, expected_type=None): + node.static_type = self.bool_type \ No newline at end of file From 9453ffdcf9a351ab8617877c0064026affff6c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 22:16:40 -0500 Subject: [PATCH 013/191] Added CoolGrammar Token and finished tokenizer --- src/engine/lexer.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index d61d2fae..24fc40f1 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -1,6 +1,7 @@ import ply.lex as lex from errors import LexicographicError - +from parser import CoolGrammar +from cp import Token ####### Tokens ####### @@ -192,17 +193,34 @@ def t_string_all(t): lexer.errors = [] lexer.unterminated_slash = False +###### CoolGrammar ###### + +tokens_dict = dict() + +tokens_dict['ACTION'] = CoolGrammar['=>'] +tokens_dict['ASSIGN'] = CoolGrammar['<-'] +tokens_dict['LESS'] = CoolGrammar['<'] +tokens_dict['LESSEQUAL'] = CoolGrammar['<='] +tokens_dict['EQUAL'] = CoolGrammar['='] +tokens_dict['INT_COMPLEMENT'] = CoolGrammar['~'] + +for tok in tokens + literals: + if tok not in tokens_dict: + tokens_dict[tok] = CoolGrammar[tok.lower()] + + ###### TOKENIZER ###### def tokenizer(code): + tokens = [] lexer.input(code) while True: token = lexer.token() if token is None: break - ##Add token - pass - #tokens.append(Token('$', CoolGrammar.EOF)) + tokens.append(Token(token.value, tokens_dict[token.type], *find_position(lexer.lexdata, token))) + + tokens.append(Token('$', CoolGrammar.EOF)) return tokens, lexer.errors From 995b356f76cb3be4f1d77a26476732d90c38598e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 23:37:01 -0500 Subject: [PATCH 014/191] Added main.py and engine __init__.py --- src/engine/__init__.py | 8 ++++++++ src/main.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/engine/__init__.py create mode 100644 src/main.py diff --git a/src/engine/__init__.py b/src/engine/__init__.py new file mode 100644 index 00000000..54573754 --- /dev/null +++ b/src/engine/__init__.py @@ -0,0 +1,8 @@ +from .lexer import tokenizer +from .parser import CoolParser +from .cp import evaluate_reverse_parse +from .visitors import Builder +from .visitors import Checker +from .visitors import Collector +from .visitors import Format +from .visitors import Inferer diff --git a/src/main.py b/src/main.py new file mode 100644 index 00000000..20325866 --- /dev/null +++ b/src/main.py @@ -0,0 +1,32 @@ + #!/usr/bin/python3 + +from engine import * +import sys + +args = sys.argv + +if len(args) != 3: + exit(1) + +input_file = open(args[1], "r") + +t = input_file.read() + +output_file = args[2] + +tokens, errors = tokenizer(t) + +#print(tokens) +if len(errors): + for e in errors: + print(e) + exit(1) + +exit(0) + +# parse, operations = CoolParser(tokens) + +# if not operations: +# print(f"Unexpected token: {parse.lex} at Ln: {parse.line}, Col {parse.column}\n") + +# print(parse) \ No newline at end of file From 43dfb2c4d0c5cde3bfc8754d83b05ddd1d8b241f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 23:38:15 -0500 Subject: [PATCH 015/191] Updated .gitignore --- .gitignore | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 4acafde1..8875552e 100644 --- a/.gitignore +++ b/.gitignore @@ -395,10 +395,10 @@ dmypy.json ### VisualStudioCode ### .vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json +.vscode/settings.json +.vscode/tasks.json +.vscode/launch.json +.vscode/extensions.json ### VisualStudioCode Patch ### # Ignore all local history of files From 78312734f7666d4ffb6b8908f2d1ab4b3d4e7957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 23:39:16 -0500 Subject: [PATCH 016/191] Added run sentence to coolc.sh --- src/coolc.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coolc.sh b/src/coolc.sh index 986b3677..5482a9ed 100755 --- a/src/coolc.sh +++ b/src/coolc.sh @@ -4,8 +4,10 @@ INPUT_FILE=$1 OUTPUT_FILE=${INPUT_FILE:0: -2}mips # Si su compilador no lo hace ya, aquí puede imprimir la información de contacto -echo "DLR MATCOM COOL COMPILER V 0.1" # TODO: Recuerde cambiar estas -echo "Copyright (c) 2020: Leonel Alejandro García López, Jorge Daniel Valle Díaz, Roberto Marti Cedeño" # TODO: líneas a los valores correctos +echo "DLR MATCOM COOL COMPILER V 0.1" +echo "Copyright (c) 2020: Leonel Alejandro García López, Jorge Daniel Valle Díaz, Roberto Marti Cedeño" # Llamar al compilador -echo "Compiling $INPUT_FILE into $OUTPUT_FILE" +#echo "Compiling $INPUT_FILE into $OUTPUT_FILE" + +python3 main.py $INPUT_FILE $OUTPUT_FILE From a12f6b4457345af18f79564fe9e287dc95cf1264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 23:40:25 -0500 Subject: [PATCH 017/191] Finished lexer.py All lexicographycal test passed --- src/engine/lexer.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 24fc40f1..c9da1c07 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -1,7 +1,7 @@ import ply.lex as lex -from errors import LexicographicError -from parser import CoolGrammar -from cp import Token +from .errors import LexicographicError +from .parser import CoolGrammar +from .cp import Token ####### Tokens ####### @@ -37,7 +37,7 @@ # Special keywords 'ACTION', # Operators - 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', 'NOT', + 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', ] + list(keywords) ####### Extra Methods ####### @@ -128,7 +128,7 @@ def t_comment_eof(t): lexer_error(t,'EOF in comment') def t_comment_error(t): - print(t.value, 'error en comment') + #print(t.value, 'error en comment') t.lexer.skip(1) # string state @@ -139,12 +139,17 @@ def t_string(t): t_string_ignore = '' +def t_string_error(t): + #print(t.value, 'error en string ') + t.lexer.skip(1) + def t_string_end(t): r'\"' if not t.lexer.unterminated_slash: t.value = t.lexer.string t.type = 'STRING' t.lexer.begin('INITIAL') + t.lexer.string = '' return t else: t.lexer.string += '"' @@ -155,10 +160,14 @@ def t_string_newline(t): t.lexer.lineno += 1 if not t.lexer.unterminated_slash: lexer_error(t,'Unterminated string constant') - pass else: + t.lexer.unterminated_slash = False t.lexer.string += '\n' +def t_string_null(t): + r'\0' + lexer_error(t,'String contains null character') + def t_string_slash(t): r'\\' if t.lexer.unterminated_slash: @@ -169,7 +178,6 @@ def t_string_slash(t): def t_string_eof(t): lexer_error(t,'EOF in string constant') - pass def t_string_all(t): r'[^\n]' @@ -178,20 +186,21 @@ def t_string_all(t): if t.value == '0': lexer_error(t,'String contains null character') t.lexer.unterminated_slash = False - pass elif t.value in ['b','t','n','f']: - t.string += spec[t.value] + t.lexer.string += spec[t.value] if t.value == 'n': t.lineno+=1 t.lexer.unterminated_slash = False else: - t.string += t.value + t.lexer.string += t.value + t.lexer.unterminated_slash = False else: t.lexer.string += t.value -lexer = lex.lex(debug=1) +lexer = lex.lex(debug=0) lexer.errors = [] lexer.unterminated_slash = False +lexer.string = '' ###### CoolGrammar ###### From 1c332d2607ecd6a5756767c84477268988ccb101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 25 Feb 2020 23:46:33 -0500 Subject: [PATCH 018/191] Removed redundant code inside lexer.py --- src/engine/lexer.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index c9da1c07..48222cb2 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -182,18 +182,12 @@ def t_string_eof(t): def t_string_all(t): r'[^\n]' if t.lexer.unterminated_slash: - spec = {'b':'\b','t':'\t','n':'\n','f':'\f'} - if t.value == '0': - lexer_error(t,'String contains null character') - t.lexer.unterminated_slash = False - elif t.value in ['b','t','n','f']: - t.lexer.string += spec[t.value] - if t.value == 'n': - t.lineno+=1 - t.lexer.unterminated_slash = False + spec = {'b':'\b','t':'\t','f':'\f'} + if t.value in ['b','t','f']: + t.lexer.string += spec[t.value] else: t.lexer.string += t.value - t.lexer.unterminated_slash = False + t.lexer.unterminated_slash = False else: t.lexer.string += t.value From 63600d38a43070f3064e76d71463b525730e4864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 26 Feb 2020 00:46:37 -0500 Subject: [PATCH 019/191] added ply to requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 9eb0cad1..5a914fd8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ pytest pytest-ordering +ply \ No newline at end of file From dc8f0f12f44835db095e61247762ce7bc51026d9 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 10:51:23 -0500 Subject: [PATCH 020/191] [error] add SyntacticError. --- src/engine/errors.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/errors.py b/src/engine/errors.py index 94312748..4f875ca9 100644 --- a/src/engine/errors.py +++ b/src/engine/errors.py @@ -2,4 +2,7 @@ ERROR = '(%d, %d) - %s: %s' def LexicographicError(line, col, message): - return ERROR % (line, col, "LexicographicError", message) \ No newline at end of file + return ERROR % (line, col, "LexicographicError", message) + +def SyntacticError(line, col, message): + return ERROR % (line, col, "SyntacticError", message) \ No newline at end of file From b4fed5d4ce7c2a80db568de833002665254cbc74 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 10:53:12 -0500 Subject: [PATCH 021/191] [main] add to main flow the parser --- src/main.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.py b/src/main.py index 20325866..5ad9726e 100644 --- a/src/main.py +++ b/src/main.py @@ -22,11 +22,12 @@ print(e) exit(1) -exit(0) - -# parse, operations = CoolParser(tokens) -# if not operations: -# print(f"Unexpected token: {parse.lex} at Ln: {parse.line}, Col {parse.column}\n") +parse, operations = CoolParser(tokens) -# print(parse) \ No newline at end of file +if not operations: + message = f'ERROR at or near "{parse.lex}"' + print(SyntacticError(parse.line,parse.column, message)) + exit(1) +#print(parse) +exit(0) From 82da05307de56d06491bc8225eebcdf3ab9d28ad Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 10:54:20 -0500 Subject: [PATCH 022/191] [cp-core] warning silencer --- src/engine/__init__.py | 1 + src/engine/cp/grammartools.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/__init__.py b/src/engine/__init__.py index 54573754..00d42166 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -6,3 +6,4 @@ from .visitors import Collector from .visitors import Format from .visitors import Inferer +from .errors import * diff --git a/src/engine/cp/grammartools.py b/src/engine/cp/grammartools.py index 11786eb4..c9b842d6 100644 --- a/src/engine/cp/grammartools.py +++ b/src/engine/cp/grammartools.py @@ -196,7 +196,8 @@ def __call__(self, w): else: assert False, 'Must be something wrong!' except KeyError: - print('Parsing Error:', stack, w[cursor:]) + if self.verbose: + print('Parsing Error:', stack, w[cursor:]) return w[cursor:][0], None class LR1Parser(ShiftReduceParser): From f8c98eb498365a4b632cb2297836d82349f46b41 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 11:09:21 -0500 Subject: [PATCH 023/191] [gram] fix grammar --- src/engine/parser.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/engine/parser.py b/src/engine/parser.py index 5dab3c23..ea40d8bb 100644 --- a/src/engine/parser.py +++ b/src/engine/parser.py @@ -181,8 +181,7 @@ class BoolNode(AtomicNode): feature_list, feature = CoolGrammar.NonTerminals(' ') param_list, param = CoolGrammar.NonTerminals(' ') expr, member_call, expr_list, let_list, case_list = CoolGrammar.NonTerminals(' ') -truth_expr, comp_expr = CoolGrammar.NonTerminals(' ') -arith, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') +comp_expr, arith, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') # terminals @@ -226,15 +225,6 @@ class BoolNode(AtomicNode): # ??? param %= idx + colon + typex, lambda h, s: (s[1], s[3]) -# ??? -expr %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) -expr %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) -expr %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) -expr %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) -expr %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) -expr %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) -expr %= truth_expr, lambda h, s: s[1] - # ??? expr_list %= expr + semi, lambda h, s: [s[1]] expr_list %= expr + semi + expr_list, lambda h, s: [s[1]] + s[3] @@ -249,9 +239,9 @@ class BoolNode(AtomicNode): case_list %= idx + colon + typex + rarrow + expr + semi, lambda h, s: [(s[1], s[3], s[5])] case_list %= idx + colon + typex + rarrow + expr + semi + case_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] -# ??? -truth_expr %= notx + truth_expr, lambda h, s: NotNode(s[2]) -truth_expr %= comp_expr, lambda h, s: s[1] +# == ??? +expr %= notx + expr, lambda h, s: NotNode(s[2]) +expr %= comp_expr, lambda h, s: s[1] # ??? comp_expr %= comp_expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) @@ -277,6 +267,13 @@ class BoolNode(AtomicNode): factor_2 %= compl + atom, lambda h, s: ComplementNode(s[2]) factor_2 %= atom, lambda h, s: s[1] +# () ??? +atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) +atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) +atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) +atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) +atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) +atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) # ??? atom %= atom + func_call, lambda h, s: FunctionCallNode(s[1], *s[2]) atom %= member_call, lambda h, s: s[1] From 095fc5a8b962aa994d6c20871049beeb69737f52 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 12:22:39 -0500 Subject: [PATCH 024/191] [grammar] fix type for some terminals. --- src/engine/parser.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/parser.py b/src/engine/parser.py index ea40d8bb..78b35979 100644 --- a/src/engine/parser.py +++ b/src/engine/parser.py @@ -190,9 +190,9 @@ class BoolNode(AtomicNode): whilex, loop, pool = CoolGrammar.Terminals('while loop pool') let, inx = CoolGrammar.Terminals('let in') case, of, esac = CoolGrammar.Terminals('case of esac') -semi, colon, comma, dot, at, opar, cpar, ocur, ccur, larrow, rarrow = CoolGrammar.Terminals('; : , . @ ( ) { } <- =>') -plus, minus, star, div, isvoid, compl = CoolGrammar.Terminals('+ - * / isvoid ~') -notx, less, leq, equal = CoolGrammar.Terminals('not < <= =') +semi, colon, comma, dot, at, opar, cpar, ocur, ccur, larrow, rarrow = CoolGrammar.Terminals('; : , . @ ( ) { } assign action') +plus, minus, star, div, isvoid, compl = CoolGrammar.Terminals('+ - * / isvoid int_complement') +notx, less, leq, equal = CoolGrammar.Terminals('not less lessequal equal') new, idx, typex, integer, string, boolx = CoolGrammar.Terminals('new id type integer string bool') # productions From c8878602ac9e33ce237629fc1488a359d2d9f2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 28 Feb 2020 15:10:00 -0500 Subject: [PATCH 025/191] Fixed literals recognition error --- src/engine/lexer.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 48222cb2..017fd318 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -93,13 +93,13 @@ def t_error(t): lexer_error(t,f'ERROR "{t.value}"') t.lexer.skip(1) -t_ASSIGN = r'<-' -t_LESS = r'<' -t_LESSEQUAL = r'<=' -t_EQUAL = r'=' -t_INT_COMPLEMENT = r'~' +t_ASSIGN = r'\<\-' +t_LESS = r'\<' +t_LESSEQUAL = r'\<\=' +t_EQUAL = r'\=' +t_INT_COMPLEMENT = r'\~' -t_ACTION = r'=>' +t_ACTION = r'\=\>' states = ( ('string','exclusive'), @@ -131,6 +131,9 @@ def t_comment_error(t): #print(t.value, 'error en comment') t.lexer.skip(1) +def t_comment_literals(t): + r'\+|\-|\*|\:|\;|\(|\)|\{|\}|\@|\.|\,|\/|\<|\<\-|\<\=|\=|\~|\=|>' + # string state def t_string(t): r'\"' @@ -200,13 +203,6 @@ def t_string_all(t): tokens_dict = dict() -tokens_dict['ACTION'] = CoolGrammar['=>'] -tokens_dict['ASSIGN'] = CoolGrammar['<-'] -tokens_dict['LESS'] = CoolGrammar['<'] -tokens_dict['LESSEQUAL'] = CoolGrammar['<='] -tokens_dict['EQUAL'] = CoolGrammar['='] -tokens_dict['INT_COMPLEMENT'] = CoolGrammar['~'] - for tok in tokens + literals: if tok not in tokens_dict: tokens_dict[tok] = CoolGrammar[tok.lower()] From c6364b90528461f6e14d9deeeb87978f65363dbf Mon Sep 17 00:00:00 2001 From: stdevlag Date: Fri, 28 Feb 2020 15:25:42 -0500 Subject: [PATCH 026/191] [grammar] fix "not" precedence. --- src/engine/parser.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/engine/parser.py b/src/engine/parser.py index 78b35979..99f88e64 100644 --- a/src/engine/parser.py +++ b/src/engine/parser.py @@ -181,7 +181,7 @@ class BoolNode(AtomicNode): feature_list, feature = CoolGrammar.NonTerminals(' ') param_list, param = CoolGrammar.NonTerminals(' ') expr, member_call, expr_list, let_list, case_list = CoolGrammar.NonTerminals(' ') -comp_expr, arith, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') +arith, arith_2, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') # terminals @@ -240,19 +240,23 @@ class BoolNode(AtomicNode): case_list %= idx + colon + typex + rarrow + expr + semi + case_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] # == ??? -expr %= notx + expr, lambda h, s: NotNode(s[2]) -expr %= comp_expr, lambda h, s: s[1] +# expr %= notx + expr, lambda h, s: NotNode(s[2]) +# expr %= comp_expr, lambda h, s: s[1] # ??? -comp_expr %= comp_expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) -comp_expr %= comp_expr + less + arith, lambda h, s: LessNode(s[1], s[3]) -comp_expr %= comp_expr + equal + arith, lambda h, s: EqualNode(s[1], s[3]) -comp_expr %= arith, lambda h, s: s[1] - -# ??? -arith %= arith + plus + term, lambda h, s: PlusNode(s[1], s[3]) -arith %= arith + minus + term, lambda h, s: MinusNode(s[1], s[3]) -arith %= term, lambda h, s: s[1] +expr %= expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) +expr %= expr + less + arith, lambda h, s: LessNode(s[1], s[3]) +expr %= expr + equal + arith, lambda h, s: EqualNode(s[1], s[3]) +expr %= arith, lambda h, s: s[1] + +# ??? +arith %= notx + arith_2, lambda h, s: NotNode(s[2]) +arith %= arith_2, lambda h, s: s[1] + +# ??? +arith_2 %= arith_2 + plus + term, lambda h, s: PlusNode(s[1], s[3]) +arith_2 %= arith_2 + minus + term, lambda h, s: MinusNode(s[1], s[3]) +arith_2 %= term, lambda h, s: s[1] # ??? term %= term + star + factor, lambda h, s: StarNode(s[1], s[3]) From fdea26ccb1f61395cdaef3666d73b747ba1dce5f Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sun, 15 Nov 2020 14:35:02 -0500 Subject: [PATCH 027/191] created Scope --- src/engine/codegen/__init__.py | 3 + src/engine/codegen/cil.py | 233 +++++++++++++++++++ src/engine/codegen/cil_ast.py | 229 +++++++++++++++++++ src/engine/codegen/cil_format.py | 194 ++++++++++++++++ src/engine/codegen/to_cil.py | 371 +++++++++++++++++++++++++++++++ src/engine/codegen/utils.py | 36 +++ 6 files changed, 1066 insertions(+) create mode 100644 src/engine/codegen/__init__.py create mode 100644 src/engine/codegen/cil.py create mode 100644 src/engine/codegen/cil_ast.py create mode 100644 src/engine/codegen/cil_format.py create mode 100644 src/engine/codegen/to_cil.py create mode 100644 src/engine/codegen/utils.py diff --git a/src/engine/codegen/__init__.py b/src/engine/codegen/__init__.py new file mode 100644 index 00000000..f34b2132 --- /dev/null +++ b/src/engine/codegen/__init__.py @@ -0,0 +1,3 @@ +from .ast import * +from .cil import * +from .to_cil import * diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py new file mode 100644 index 00000000..ece58407 --- /dev/null +++ b/src/engine/codegen/cil.py @@ -0,0 +1,233 @@ +from .ast import ProgramNode,TypeNode,DataNode,FunctionNode,ArithmeticNode,ParamNode, \ +LocalNode, AssignNode,GetAttribNode,SetAttribNode,SetIndexNode,AllocateNode,TypeOfNode, \ +LabelNode,GotoNode,IfGotoNode,StaticCallNode,DynamicCallNode,ArgNode,ReturnNode,LoadNode, \ +LengthNode,ConcatNode,PrefixNode,SubstringNode,ToStrNode,ToIntNode,ReadNode,PrefixNode + + +class VariableInfo: + def __init__(self, name, vtype): + self.name = name + self.type = vtype + +class BASE_COOL_CIL_TRANSFORM: + def __init__(self, context): + self.dottypes = [] + self.dotdata = [] + self.dotcode = [] + self.current_type = None + self.current_method = None + self.current_function = None + self.context = context + self.label_count = 0 + self.build_basics() + + @property + def params(self): + return self.current_function.params + + @property + def localvars(self): + return self.current_function.localvars + + @property + def instructions(self): + return self.current_function.instructions + + def register_param(self, vinfo): + param_node = ParamNode(vinfo.name) + self.params.append(param_node) + return vinfo.name + + def register_local(self, vinfo): + vinfo.name = f'local_{self.current_function.name[9:]}_{vinfo.name}_{len(self.localvars)}' + local_node = LocalNode(vinfo.name) + self.localvars.append(local_node) + return vinfo.name + + def define_internal_local(self): + vinfo = VariableInfo('internal', None) + return self.register_local(vinfo) + + def register_instruction(self, instruction): + self.instructions.append(instruction) + return instruction + ############################### + + def to_function_name(self, method_name, type_name): + return f'function_{method_name}_at_{type_name}' + + def to_label_name(self, label_name): + self.label_count += 1 + return f'label_{label_name}{self.label_count}_at_{self.current_function.name[9:]}' + + def register_function(self, function_name): + function_node = FunctionNode(function_name, [], [], []) + self.dotcode.append(function_node) + return function_node + + def register_type(self, name): + type_node = TypeNode(name) + self.dottypes.append(type_node) + return type_node + + def register_data(self, value): + data_node = None + for data in self.dotdata: + if data.value == value: + data_node = data + break + else: + vname = f'data_{len(self.dotdata)}' + data_node = DataNode(vname, value) + self.dotdata.append(data_node) + return data_node + + ################################### + + def build_basics(self): + self.build_basic_object() + self.build_basic_string() + self.build_basic_io() + + def build_basic_object(self): + self.current_type = self.context.get_type('Object') + type_node = self.register_type('Object') + type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] + type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] + ### abort function + self.current_method = self.current_type.get_method('abort') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + self.register_instruction(ErrorNode(0)) + self.current_method = self.current_function = None + ### copy function + self.current_method = self.current_type.get_method('copy') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + copy_inst = self.define_internal_local() + self.register_instruction(CopyNode(copy_inst, self_local)) + self.register_instruction(ReturnNode(copy_inst)) + self.current_method = self.current_function = None + ### type_name + self.current_method = self.current_type.get_method('type_name') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + obj_type = self.define_internal_local() + type_name_inst = self.define_internal_local() + self.register_instruction(TypeOfNode(self_local, obj_type)) + self.register_instruction(TypeNameNode(type_name_inst, obj_type)) + self.register_instruction(ReturnNode(type_name_inst)) + self.current_method = self.current_function = None + self.current_type = None + + def build_basic_io(self): + self.current_type = self.context.get_type('IO') + type_node = self.register_type('IO') + type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] + type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] + ### in_string + self.current_method = self.current_type.get_method('in_string') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + _ = self.register_param(VariableInfo('self', None)) + result_msg = self.define_internal_local() + self.register_instruction(ReadNode(result_msg)) + self.register_instruction(ReturnNode(result_msg)) + self.current_method = self.current_function = None + ### out_string + self.current_method = self.current_type.get_method('out_string') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + out_msg = self.register_param(VariableInfo('x', None)) + self.register_instruction(PrintNode(out_msg)) + self.register_instruction(ReturnNode(self_local)) + self.current_method = self.current_function = None + ### in_int + self.current_method = self.current_type.get_method('in_string') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + _ = self.register_param(VariableInfo('self', None)) + result_msg = self.define_internal_local() + result_int = self.define_internal_local() + self.register_instruction(ReadNode(result_msg)) + self.register_instruction(ToIntNode(result_int, result_msg)) + self.register_instruction(ReturnNode(result_int)) + self.current_method = self.current_function = None + ### out_int + self.current_method = self.current_type.get_method('out_string') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + out_int = self.register_param(VariableInfo('x', None)) + out_msg = self.define_internal_local() + self.register_instruction(ToStrNode(out_msg, out_int)) + self.register_instruction(PrintNode(out_msg)) + self.register_instruction(ReturnNode(self_local)) + self.current_method = self.current_function = None + self.current_type = None + + def build_basic_string(self): + self.current_type = self.context.get_type('String') + type_node = self.register_type('String') + type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] + type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] + ### length + self.current_method = self.current_type.get_method('length') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + length_var = self.define_internal_local() + self.register_instruction(LengthNode(length_var, self_local)) + self.register_instruction(ReturnNode(length_var)) + self.current_method = self.current_function = None + ### concat + self.current_method = self.current_type.get_method('concat') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + param_local = self.register_param(VariableInfo('s', None)) + result_msg = self.define_internal_local() + self.register_instruction(ConcatNode(result_msg, self_local, param_local)) + self.register_instruction(ReturnNode(result_msg)) + self.current_method = self.current_function = None + ### substr + self.current_method = self.current_type.get_method('substr') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + start_parm = self.register_param(VariableInfo('i', None)) + length_param = self.register_param(VariableInfo('l', None)) + result_msg = self.define_internal_local() + length_var = self.define_internal_local() + sum_var = self.define_internal_local() + cmp_var1 = self.define_internal_local() + cmp_var2 = self.define_internal_local() + cmp_var3 = self.define_internal_local() + no_error_label1 = self.to_label_name('error1') + no_error_label2 = self.to_label_name('error2') + no_error_label3 = self.to_label_name('error3') + self.register_instruction(LengthNode(length_var, self_local)) + # start param negative + self.register_instruction(LessEqNode(cmp_var1, 0, start_parm)) + self.register_instruction(IfGotoNode(cmp_var1, no_error_label1)) + self.register_instruction(ErrorNode()) + self.register_instruction(LabelNode(no_error_label1)) + # length param negative + self.register_instruction(LessEqNode(cmp_var2, 0, length_param)) + self.register_instruction(IfGotoNode(cmp_var2, no_error_label2)) + self.register_instruction(ErrorNode()) + self.register_instruction(LabelNode(no_error_label2)) + # substr larger than max length + self.register_instruction(PlusNode(sum_var, start_parm, length_param)) + self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) + self.register_instruction(IfGotoNode(cmp_var3, no_error_label3)) + self.register_instruction(ErrorNode()) + self.register_instruction(LabelNode(no_error_label3)) + self.register_instruction(SubstringNode(result_msg, self_local, start_parm, length_param)) + self.register_instruction(ReturnNode(result_msg)) + self.current_method = self.current_function = None + self.current_type = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py new file mode 100644 index 00000000..757da0ad --- /dev/null +++ b/src/engine/codegen/cil_ast.py @@ -0,0 +1,229 @@ + + +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 EqualNode(ArithmeticNode): + pass + +class GetAttribNode(InstructionNode): + def __init__(self, dest, obj, attrib): + self.dest = dest + self.obj = obj + self.attrib = attrib + +class SetAttribNode(InstructionNode): + def __init__(self, obj, attrib, value): + self.obj = obj + self.attrib = attrib + self.value = value + +class GetIndexNode(InstructionNode): + def __init__(self, dest, array, index): + self.dest = dest + self.array = array + self.index = index + +class SetIndexNode(InstructionNode): + def __init__(self, array, index, value): + self.array = array + self.index = index + self.value = value + +class AllocateNode(InstructionNode): + def __init__(self, dest, itype): + self.dest = dest + self.type = itype + +class TypeOfNode(InstructionNode): + def __init__(self, obj, dest): + self.obj = obj + self.dest = dest + +class LabelNode(InstructionNode): + def __init__(self, label): + self.label = label + +class GotoNode(InstructionNode): + def __init__(self, label): + self.label = label + +class IfGotoNode(InstructionNode): + def __init__(self, value, label): + self.value = value + self.label = label + +class StaticCallNode(InstructionNode): + def __init__(self, function, dest): + self.dest = dest + self.function = function + +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): + def __init__(self, dest, msg): + self.dest = dest + self.msg = msg + +class ConcatNode(InstructionNode): + def __init__(self, dest, msg1, msg2): + self.dest = dest + self.msg1 = msg1 + self.msg2 = msg2 + +class PrefixNode(InstructionNode): + def __init__(self, dest, msg1, msg2): + self.dest = dest + self.msg1 = msg1 + self.msg2 = msg2 + +class SubstringNode(InstructionNode): + def __init__(self, dest, msg1, start, length): + self.dest = dest + self.msg1 = msg1 + self.start = start + self.length = length + +class ToStrNode(InstructionNode): + def __init__(self, dest, ivalue): + self.dest = dest + self.ivalue = ivalue + +class ToIntNode(InstructionNode): + def __init__(self, dest, msg): + self.dest = dest + self.msg = msg + +class ReadNode(InstructionNode): + def __init__(self, dest): + self.dest = dest + +class PrintNode(InstructionNode): + def __init__(self, str_addr): + self.str_addr = str_addr + +################# nodes que me tengo que definir ############## + +# class ErrorNode(InstructionNode): +# def __init__(self, error=1): +# self.error = error + +# class CopyNode(InstructionNode): +# def __init__(self, dest, obj): +# self.dest = dest +# self.obj = obj + +# class TypeNameNode(InstructionNode): +# def __init__(self, dest, typex): +# self.dest = dest +# self.type = typex + + +# class ConformNode(InstructionNode): +# def __init__(self, dest, obj, typex): +# self.dest = dest +# self.obj = obj +# self.type = typex + +# class ComplementNode(InstructionNode): +# def __init__(self, dest, body): +# self.dest = dest +# self.body = body + +# class IsVoidNode(InstructionNode): +# def __init__(self, dest, body): +# self.dest = dest +# self.body = body + +# class LessNode(ArithmeticNode): +# pass + + +# class LessEqNode(ArithmeticNode): +# pass + +# class CleanArgsNode(InstructionNode): +# def __init__(self, nargs): +# self.nargs = nargs + +# class StringEqualNode(InstructionNode): +# def __init__(self, dest, msg1, msg2): +# self.dest = dest +# self.msg1 = msg1 +# self.msg2 = msg2 + diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py new file mode 100644 index 00000000..c1a82cec --- /dev/null +++ b/src/engine/codegen/cil_format.py @@ -0,0 +1,194 @@ +from .cil_ast import ProgramNode, TypeNode, FunctionNode, ParamNode, LocalNode, AssignNode, PlusNode \ + , MinusNode, StarNode, DivNode, AllocateNode, TypeOfNode, StaticCallNode, DynamicCallNode \ + , ArgNode, ReturnNode, ReadNode, PrintNode, LoadNode, LengthNode, ConcatNode, PrefixNode \ + , SubstringNode, ToStrNode, GetAttribNode, SetAttribNode, LabelNode, GotoNode, IfGotoNode \ + , DataNode, ToIntNode + +from ..cp.visitor import on, when + +class CIL_FORMATTER(object): + @on('node') + def visit(self, node): + pass + + @when(ProgramNode) + def visit(self, node: ProgramNode): + 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}' + + @when(DataNode) + def visit(self, node: DataNode): + return f'{node.name} = "{node.value}"' + + @when(TypeNode) + def visit(self, node: TypeNode): + 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}}' + + @when(FunctionNode) + def visit(self, node: FunctionNode): + 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}}' + + @when(ParamNode) + def visit(self, node: ParamNode): + return f'PARAM {node.name}' + + @when(LocalNode) + def visit(self, node: LocalNode): + return f'LOCAL {node.name}' + + @when(AssignNode) + def visit(self, node: AssignNode): + return f'{node.dest} = {node.source}' + + @when(EqualNode) + def visit(self, node: EqualNode): + return f'{node.dest} = {node.left} == {node.right}' + + @when(PlusNode) + def visit(self, node: PlusNode): + return f'{node.dest} = {node.left} + {node.right}' + + @when(MinusNode) + def visit(self, node: MinusNode): + return f'{node.dest} = {node.left} - {node.right}' + + @when(StarNode) + def visit(self, node: StarNode): + return f'{node.dest} = {node.left} * {node.right}' + + @when(DivNode) + def visit(self, node: DivNode): + return f'{node.dest} = {node.left} / {node.right}' + + @when(AllocateNode) + def visit(self, node: AllocateNode): + return f'{node.dest} = ALLOCATE {node.type}' + + @when(TypeOfNode) + def visit(self, node: TypeOfNode): + return f'{node.dest} = TYPEOF {node.obj}' + + @when(StaticCallNode) + def visit(self, node: StaticCallNode): + return f'{node.dest} = CALL {node.function}' + + @when(DynamicCallNode) + def visit(self, node: DynamicCallNode): + return f'{node.dest} = VCALL {node.type} {node.method}' + + @when(ArgNode) + def visit(self, node: ArgNode): + return f'ARG {node.name}' + + @when(ReturnNode) + def visit(self, node: ReturnNode): + return f'RETURN {node.value if node.value is not None else ""}' + + @when(ReadNode) + def visit(self, node: ReadNode): + return f'{node.dest} = READ' + + @when(PrintNode) + def visit(self, node: PrintNode): + return f'PRINT {node.str_addr}' + + @when(LoadNode) + def visit(self, node: LoadNode): + return f'{node.dest} = LOAD {node.msg}' + + @when(LengthNode) + def visit(self, node: LengthNode): + return f'{node.dest} = LENGTH {node.msg}' + + @when(ConcatNode) + def visit(self, node: ConcatNode): + return f'{node.dest} = CONCAT {node.msg1} {node.msg2}' + + @when(PrefixNode) + def visit(self, node: PrefixNode): + return f'{node.dest} = PREFIX {node.msg1} {node.msg2}' + + @when(SubstringNode) + def visit(self, node: SubstringNode): + return f'{node.dest} = SUBSTRING {node.msg1} {node.start} {node.length}' + + @when(ToStrNode) + def visit(self, node: ToStrNode): + return f'{node.dest} = STR {node.ivalue}' + + @when(ToIntNode) + def visit(self, node: ToIntNode): + return f'{node.dest} = INT {node.msg}' + + @when(GetAttribNode) + def visit(self, node: GetAttribNode): + return f'{node.dest} = GETATTR {node.obj} {node.attrib}' + + @when(SetAttribNode) + def visit(self, node: SetAttribNode): + return f'SETATTR {node.obj} {node.attrib} {node.value}' + + @when(LabelNode) + def visit(self, node: LabelNode): + return f'LABEL {node.label}' + + @when(GotoNode) + def visit(self, node: GotoNode): + return f'GOTO {node.label}' + + @when(IfGotoNode) + def visit(self, node: IfGotoNode): + return f'IF {node.value} GOTO {node.label}' + +###################### nodes to throw ####################### + + # @when(ErrorNode) + # def visit(self, node: ErrorNode): + # return f'ERROR {node.error}' + + # @when(ConformNode) + # def visit(self, node: ConformNode): + # return f'{node.dest} = COMFORM {node.obj} {node.type}' + + # @when(ComplementNode) + # def visit(self, node: ComplementNode): + # return f'{node.dest} = COMPLEMENT {node.body}' + + # @when(LessNode) + # def visit(self, node: LessNode): + # return f'{node.dest} = {node.left} < {node.right}' + + # @when(IsVoidNode) + # def visit(self, node: IsVoidNode): + # return f'{node.dest} = ISVOID {node.body}' + + # @when(LessEqNode) + # def visit(self, node: LessEqNode): + # return f'{node.dest} = {node.left} <= {node.right}' + + # @when(CleanArgsNode) + # def visit(self, node:CleanArgsNode): + # return f'CLEANARG {node.nargs}' + + # @when(StringEqualNode) + # def visit(self, node: StringEqualNode): + # return f'{node.dest} = STREQ {node.msg1} {node.msg2}' + + # @when(CopyNode) + # def visit(self, node: CopyNode): + # return f'{node.dest} = COPY {node.obj}' + + # @when(TypeNameNode) + # def visit(self, node: TypeNameNode): + # return f'{node.dest} = TYPENAME {node.type}' + diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py new file mode 100644 index 00000000..5d957bc2 --- /dev/null +++ b/src/engine/codegen/to_cil.py @@ -0,0 +1,371 @@ +import parser as cool +from .cil_ast import ProgramNode, TypeNode, FunctionNode, ParamNode, LocalNode, AssignNode, PlusNode \ + , MinusNode, StarNode, DivNode, AllocateNode, TypeOfNode, StaticCallNode, DynamicCallNode \ + , ArgNode, ReturnNode, ReadNode, PrintNode, LoadNode, LengthNode, ConcatNode, PrefixNode \ + , SubstringNode, ToStrNode, GetAttribNode, SetAttribNode, LabelNode, GotoNode, IfGotoNode \ + , DataNode, ToIntNode + +from .cil import BASE_COOL_CIL_TRANSFORM, VariableInfo +from .utils import Scope +from ..cp.visitor import when,on + + + +class COOL_TO_CIL_VISITOR(BASE_COOL_CIL_TRANSFORM): + @on('node') + def visit(self, node, scope:Scope): + pass + + def order_caseof(self, node:cool.CaseOfNode): + return list(node.cases) + + def find_type_name(self, typex, func_name): + if func_name in typex.methods: + return typex.name + return self.find_type_name(typex.parent, func_name) + + def init_class_attr(self, scope:Scope, class_id, self_inst): + attr_nodes = self.attr_init[class_id] + for attr in attr_nodes: + attr_scope = Scope(parent=scope) + attr_scope.define_var('self', self_inst) + self.visit(attr, attr_scope) + + def build_attr_init(self, node:cool.ProgramNode): + self.attr_init = dict() + for classx in node.classes: + self.attr_init[classx.id] = [] + if classx.parent and not classx.parent in ['IO', 'Object']: + self.attr_init[classx.id] += self.attr_init[classx.parent] + for feature in classx.features: + if type(feature) is cool.AttrDeclarationNode: + self.attr_init[classx.id].append(feature) + + @when(cool.ProgramNode) + def visit(self, node:cool.ProgramNode=None, scope:Scope=None): + scope = Scope() + self.build_attr_init(node) + self.current_function = self.register_function('main') + instance = self.define_internal_local() + result = self.define_internal_local() + self.register_instruction(AllocateNode(instance, 'Main')) + self.init_class_attr(scope, 'Main', instance) + self.register_instruction(ArgNode(instance)) + self.register_instruction(StaticCallNode(self.to_function_name('main', 'Main'), result)) + self.register_instruction(CleanArgsNode(1)) + self.register_instruction(ReturnNode(0)) + self.current_function = None + + for classx in node.classes: + self.visit(classx, scope) + + return ProgramNode(self.dottypes, self.dotdata, self.dotcode) + + @when(cool.ClassDeclarationNode) + def visit(self, node:cool.ClassDeclarationNode, scope:Scope): + self.current_type = self.context.get_type(node.id) + + type_node = self.register_type(node.id) + type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] + type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] + + for feature in node.features: + if isinstance(feature, cool.FuncDeclarationNode): + self.visit(feature, scope) + + self.current_type = None + + @when(cool.AttrDeclarationNode) + def visit(self, node:cool.AttrDeclarationNode, scope:Scope): + result = self.visit(node.expression, scope) if node.expression else 0 + self_inst = scope.get_var('self').local_name + self.register_instruction(SetAttribNode(self_inst, node.id, result)) + + @when(cool.FuncDeclarationNode) + def visit(self, node:cool.FuncDeclarationNode, scope:Scope): + func_scope = Scope(parent=scope) + self.current_method = self.current_type.get_method(node.id) + type_name = self.current_type.name + + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + func_scope.define_var('self', self_local) + for param_name in self.current_method.param_names: + param_local = self.register_param(VariableInfo(param_name, None)) + func_scope.define_var(param_name, param_local) + + body = self.visit(node.expression, func_scope) + self.register_instruction(ReturnNode(body)) + + self.current_method = self.current_function = None + + + @when(cool.IfThenElseNode) + def visit(self, node:cool.IfThenElseNode, scope:Scope): + if_scope = Scope(parent=scope) + cond_result = self.visit(node.condition, scope) + result = self.define_internal_local() + true_label = self.to_label_name('if_true') + end_label = self.to_label_name('end_if') + self.register_instruction(IfGotoNode(cond_result, true_label)) + false_result = self.visit(node.else_body, if_scope) + self.register_instruction(AssignNode(result, false_result)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(LabelNode(true_label)) + true_result = self.visit(node.if_body, if_scope) + self.register_instruction(AssignNode(result, true_result)) + self.register_instruction(LabelNode(end_label)) + + return result + + + @when(cool.WhileLoopNode) + def visit(self, node:cool.WhileLoopNode, scope:Scope): + while_scope = Scope(parent=scope) + loop_label = self.to_label_name('loop') + body_label = self.to_label_name('body') + end_label = self.to_label_name('pool') + self.register_instruction(LabelNode(loop_label)) + condition = self.visit(node.condition, scope) + self.register_instruction(IfGotoNode(condition, body_label)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(LabelNode(body_label)) + self.visit(node.body, while_scope) + self.register_instruction(LabelNode(end_label)) + + return 0 + + + @when(cool.BlockNode) + def visit(self, node:cool.BlockNode, scope:Scope): + result = None + for expr in node.expressions: + result = self.visit(expr, scope) + + return result + + + @when(cool.LetNode) + def visit(self, node:cool.LetNode, scope:Scope): + var_name = self.register_local(VariableInfo(node.id, None)) + scope.define_var(node.id, var_name) + result = self.visit(node.expression, scope) if node.expression else 0 + + self.register_instruction(AssignNode(var_name, result)) + + @when(cool.LetInNode) + def visit(self, node:cool.LetInNode, scope:Scope): + let_scope = Scope(parent=scope) + for let in node.let_body: + self.visit(let, let_scope) + + result = self.visit(node.in_body, let_scope) + return result + + @when(cool.CaseNode) + def visit(self, node:cool.CaseNode, scope:Scope, typex=None, result_inst=None, end_label=None): + cond = self.define_internal_local() + not_cond = self.define_internal_local() + case_label = self.to_label_name(f'case_{node.type}') + self.register_instruction(ConformNode(cond, typex, node.type)) + self.register_instruction(ComplementNode(not_cond, cond)) + self.register_instruction(IfGotoNode(not_cond, case_label)) + case_scope = Scope(parent=scope) + case_var = self.register_local(VariableInfo(node.id, None)) + case_scope.define_var(node.id, case_var) + case_result = self.visit(node.expression, case_scope) + self.register_instruction(AssignNode(result_inst, case_result)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(LabelNode(case_label)) + + @when(cool.CaseOfNode) + def visit(self, node:cool.CaseOfNode, scope:Scope): + order_cases = self.order_caseof(node) + end_label = self.to_label_name('end') + error_label = self.to_label_name('error') + result = self.define_internal_local() + type_inst = self.define_internal_local() + is_void = self.define_internal_local() + obj_inst = self.visit(node.expression, scope) + self.register_instruction(IsVoidNode(is_void, obj_inst)) + self.register_instruction(IfGotoNode(is_void, error_label)) + self.register_instruction(TypeOfNode(obj_inst, type_inst)) + for case in order_cases: + self.visit(case, scope, type_inst, result, end_label) + self.register_instruction(LabelNode(error_label)) + self.register_instruction(ErrorNode()) + self.register_instruction(LabelNode(end_label)) + + return result + + @when(cool.AssignNode) + def visit(self, node:cool.AssignNode, scope:Scope): + value = self.visit(node.expression, scope) + pvar = scope.get_var(node.id) + if not pvar: + selfx = scope.get_var('self').local_name + self.register_instruction(SetAttribNode(selfx, node.id, value)) + else: + pvar = pvar.local_name + self.register_instruction(AssignNode(pvar, value)) + return 0 + + @when(cool.MemberCallNode) + def visit(self, node:cool.MemberCallNode, scope:Scope): + type_name = self.current_type.name + result = self.define_internal_local() + rev_args = [] + for arg in node.args: + arg_value = self.visit(arg, scope) + rev_args = [ arg_value ] + rev_args + for arg_value in rev_args: + self.register_instruction(ArgNode(arg_value)) + self_inst = scope.get_var('self').local_name + self.register_instruction(ArgNode(self_inst)) + self.register_instruction(DynamicCallNode(type_name, node.id, result)) + self.register_instruction(CleanArgsNode(len(node.args)+1)) + + return result + + @when(cool.FunctionCallNode) + def visit(self, node:cool.FunctionCallNode, scope:Scope): + typex = None if not node.type else self.context.get_type(node.type) + type_name = self.find_type_name(typex, node.id) if typex else '' + func_name = self.to_function_name(node.id, type_name) if type_name else '' + result = self.define_internal_local() + rev_args = [] + for arg in node.args: + arg_value = self.visit(arg, scope) + rev_args = [ arg_value ] + rev_args + for arg_value in rev_args: + self.register_instruction(ArgNode(arg_value)) + obj_inst = self.visit(node.obj, scope) + self.register_instruction(ArgNode(obj_inst)) + self.register_instruction(StaticCallNode(func_name, result)) if func_name else self.register_instruction(DynamicCallNode(node.obj.static_type.name, node.id, result)) + self.register_instruction(CleanArgsNode(len(node.args)+1)) + + return result + + + @when(cool.NewNode) + def visit(self, node:cool.NewNode, scope:Scope): # Remember attributes initialization + result = self.define_internal_local() + self.register_instruction(AllocateNode(result, node.type)) + self.init_class_attr(scope, node.type, result) + + return result + + @when(cool.IsVoidNode) + def visit(self, node:cool.IsVoidNode, scope:Scope): + body = self.visit(node.expression, scope) + result = self.define_internal_local() + + self.register_instruction(IsVoidNode(result, body)) + return result + + @when(cool.NotNode) + def visit(self, node:cool.NotNode, scope:Scope): + value = self.visit(node.expression, scope) + result = self.define_internal_local() + + self.register_instruction(ComplementNode(result, value)) + return result + + @when(cool.ComplementNode) + def visit(self, node:cool.ComplementNode, scope:Scope): + value = self.visit(node.expression, scope) + result = self.define_internal_local() + + self.register_instruction(ComplementNode(result, value)) + return result + + @when(cool.PlusNode) + def visit(self, node:cool.PlusNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(PlusNode(result, left, right)) + return result + + @when(cool.MinusNode) + def visit(self, node:cool.MinusNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(MinusNode(result, left, right)) + return result + + @when(cool.StarNode) + def visit(self, node:cool.StarNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(StarNode(result, left, right)) + return result + + @when(cool.DivNode) + def visit(self, node:cool.DivNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(DivNode(result, left, right)) + return result + + @when(cool.EqualNode) + def visit(self, node:cool.EqualNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + if node.left.static_type == self.context.get_type('String'): + self.register_instruction(StringEqualNode(result, left, right)) + else: + self.register_instruction(EqualNode(result, left, right)) + return result + + @when(cool.LessNode) + def visit(self, node:cool.LessNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(LessNode(result, left, right)) + return result + + @when(cool.LessEqualNode) + def visit(self, node:cool.LessEqualNode, scope:Scope): + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + self.register_instruction(LessEqNode(result, left, right)) + return result + + @when(cool.IdNode) + def visit(self, node:cool.IdNode, scope:Scope): + pvar = scope.get_var(node.token) + if not pvar: + selfx = scope.get_var('self').local_name + pvar = self.define_internal_local() + + self.register_instruction(GetAttribNode(pvar, selfx, node.token)) # Perhaps GetAttribNode could need info about self type, this is know in self.current_type variable + else: + pvar = pvar.local_name + return pvar + + @when(cool.BoolNode) + def visit(self, node:cool.BoolNode, scope:Scope): + return 1 if node.token.lower() == 'true' else 0 + + @when(cool.IntegerNode) + def visit(self, node:cool.IntegerNode, scope:Scope): + return int(node.token) + + @when(cool.StringNode) + def visit(self, node:cool.StringNode, scope:Scope): + string = self.register_data(node.token[1:-1]) + return string.name diff --git a/src/engine/codegen/utils.py b/src/engine/codegen/utils.py new file mode 100644 index 00000000..8f26e864 --- /dev/null +++ b/src/engine/codegen/utils.py @@ -0,0 +1,36 @@ +class Var: + def __init__(self, idx, local_name): + self.id = idx + self.local_name = local_name + + def __str__(self): + return f'[var] {self.id}: {self.local_name}' + + def __repr__(self): + return str(self) + +class Scope: + def __init__(self, parent=None): + self.parent = parent + self.vars = {} + + def child(self): + return Scope(parent=self) + + def define_var(self, name, local_name): + var = self.vars[name] = Var(name, local_name) + return var + + def get_var(self, name): + try: + return self.vars[name] + except KeyError: + if not self.parent is None: + return self.parent.get_var(name) + return None + + def __str__(self): + return '{\n' + ('\t' if self.parent is None else 'Parent:\n' + f'{self.parent}\n\t') + '\n\t'.join(str(x) for x in self.vars.values()) + '\n}' + + def __repr__(self): + return str(self) \ No newline at end of file From b3899d3f90986aa42c8273f1d69f0e45430015a6 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 19 Nov 2020 12:24:50 -0500 Subject: [PATCH 028/191] Start the code generation... CIL transformation --- src/engine/__init__.py | 2 + src/engine/codegen/__init__.py | 2 +- src/engine/codegen/cil.py | 231 ++++++----------- src/engine/codegen/cil_format.py | 93 +++---- src/engine/codegen/to_cil.py | 408 +++++++++---------------------- src/engine/codegen/utils.py | 56 ++--- src/main.py | 25 +- src/makefile | 3 + src/test.cl | 32 +++ src/test.mips | 1 + 10 files changed, 325 insertions(+), 528 deletions(-) create mode 100755 src/test.cl create mode 100644 src/test.mips diff --git a/src/engine/__init__.py b/src/engine/__init__.py index 00d42166..fd691753 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -7,3 +7,5 @@ from .visitors import Format from .visitors import Inferer from .errors import * +from .codegen import COOL_TO_CIL_VISITOR +from .codegen.cil_format import CIL_FORMATTER diff --git a/src/engine/codegen/__init__.py b/src/engine/codegen/__init__.py index f34b2132..d5d01dd7 100644 --- a/src/engine/codegen/__init__.py +++ b/src/engine/codegen/__init__.py @@ -1,3 +1,3 @@ -from .ast import * +from .cil_ast import * from .cil import * from .to_cil import * diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index ece58407..5233f27d 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -1,13 +1,5 @@ -from .ast import ProgramNode,TypeNode,DataNode,FunctionNode,ArithmeticNode,ParamNode, \ -LocalNode, AssignNode,GetAttribNode,SetAttribNode,SetIndexNode,AllocateNode,TypeOfNode, \ -LabelNode,GotoNode,IfGotoNode,StaticCallNode,DynamicCallNode,ArgNode,ReturnNode,LoadNode, \ -LengthNode,ConcatNode,PrefixNode,SubstringNode,ToStrNode,ToIntNode,ReadNode,PrefixNode - - -class VariableInfo: - def __init__(self, name, vtype): - self.name = name - self.type = vtype +from .cil_ast import * +from ..cp.semantic import VariableInfo , Scope class BASE_COOL_CIL_TRANSFORM: def __init__(self, context): @@ -18,8 +10,6 @@ def __init__(self, context): self.current_method = None self.current_function = None self.context = context - self.label_count = 0 - self.build_basics() @property def params(self): @@ -35,14 +25,15 @@ def instructions(self): def register_param(self, vinfo): param_node = ParamNode(vinfo.name) + # vinfo.name = f'param_{self.current_function.name[9:]}_{vinfo.name}_{len(self.params)}' self.params.append(param_node) return vinfo.name def register_local(self, vinfo): - vinfo.name = f'local_{self.current_function.name[9:]}_{vinfo.name}_{len(self.localvars)}' - local_node = LocalNode(vinfo.name) + name = f'local_{self.current_function.name[9:]}_{vinfo.name}_{len(self.localvars)}' + local_node = LocalNode(name) self.localvars.append(local_node) - return vinfo.name + return name def define_internal_local(self): vinfo = VariableInfo('internal', None) @@ -51,14 +42,12 @@ def define_internal_local(self): def register_instruction(self, instruction): self.instructions.append(instruction) return instruction - ############################### def to_function_name(self, method_name, type_name): return f'function_{method_name}_at_{type_name}' - def to_label_name(self, label_name): - self.label_count += 1 - return f'label_{label_name}{self.label_count}_at_{self.current_function.name[9:]}' + def to_attr_name(self, attr_name, type_name): + return f'attribute_{attr_name}_at_{type_name}' def register_function(self, function_name): function_node = FunctionNode(function_name, [], [], []) @@ -71,163 +60,97 @@ def register_type(self, name): return type_node def register_data(self, value): - data_node = None - for data in self.dotdata: - if data.value == value: - data_node = data - break - else: - vname = f'data_{len(self.dotdata)}' - data_node = DataNode(vname, value) - self.dotdata.append(data_node) + vname = f'data_{len(self.dotdata)}' + data_node = DataNode(vname, value) + self.dotdata.append(data_node) return data_node ################################### - def build_basics(self): - self.build_basic_object() - self.build_basic_string() - self.build_basic_io() + def define_string_type(self): + self.current_type = self.context.get_type('String') + type_node = self.register_type(node.id) + type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + self.current_method = self.current_type.get_method('length') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_param = self.register_param(VariableInfo('self',None)) + dest = self.define_internal_local() + self.register_instruction(LengthNode(dest,self_param)) + self.register_instruction(ReturnNode(dest)) + self.current_method = self.current_function = None + self.current_type = None - def build_basic_object(self): - self.current_type = self.context.get_type('Object') - type_node = self.register_type('Object') - type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] - type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] - ### abort function - self.current_method = self.current_type.get_method('abort') + self.current_method = self.current_type.get_method('concat') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - self.register_instruction(ErrorNode(0)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_param = self.register_param(VariableInfo('self',None)) + str_param = self.register_param(VariableInfo('string',None)) + dest = self.define_internal_local() + self.register_instruction(ConcatNode(dest,self_param,str_param)) + self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None - ### copy function - self.current_method = self.current_type.get_method('copy') + + self.current_method = self.current_type.get_method('substr') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - copy_inst = self.define_internal_local() - self.register_instruction(CopyNode(copy_inst, self_local)) - self.register_instruction(ReturnNode(copy_inst)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_param = self.register_param(VariableInfo('self',None)) + start = self.register_param(VariableInfo('start',None)) + length = self.register_param(VariableInfo('length',None)) + dest = self.define_internal_local() + self.register_instruction(SubstringNode(dest,self_param,start,length)) + self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None - ### type_name - self.current_method = self.current_type.get_method('type_name') + + self.current_method = self.current_type.get_method('prefix') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - obj_type = self.define_internal_local() - type_name_inst = self.define_internal_local() - self.register_instruction(TypeOfNode(self_local, obj_type)) - self.register_instruction(TypeNameNode(type_name_inst, obj_type)) - self.register_instruction(ReturnNode(type_name_inst)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_param = self.register_param(VariableInfo('self',None)) + length = self.register_param(VariableInfo('length',None)) + dest = self.define_internal_local() + self.register_instruction(ConcatNode(dest,self_param,length)) + self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None self.current_type = None - def build_basic_io(self): + def define_io_type(self): self.current_type = self.context.get_type('IO') type_node = self.register_type('IO') - type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] - type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] - ### in_string - self.current_method = self.current_type.get_method('in_string') - type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - _ = self.register_param(VariableInfo('self', None)) - result_msg = self.define_internal_local() - self.register_instruction(ReadNode(result_msg)) - self.register_instruction(ReturnNode(result_msg)) - self.current_method = self.current_function = None - ### out_string - self.current_method = self.current_type.get_method('out_string') + type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + self.current_method = self.current_type.get_method('print') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - out_msg = self.register_param(VariableInfo('x', None)) - self.register_instruction(PrintNode(out_msg)) - self.register_instruction(ReturnNode(self_local)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + str_val = self.define_internal_local() self.current_method = self.current_function = None - ### in_int - self.current_method = self.current_type.get_method('in_string') + self.register_instruction(PrintNode(str_val)) + + self.current_method = self.current_type.get_method('read') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - _ = self.register_param(VariableInfo('self', None)) - result_msg = self.define_internal_local() - result_int = self.define_internal_local() - self.register_instruction(ReadNode(result_msg)) - self.register_instruction(ToIntNode(result_int, result_msg)) - self.register_instruction(ReturnNode(result_int)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + dest = self.define_internal_local() self.current_method = self.current_function = None - ### out_int - self.current_method = self.current_type.get_method('out_string') + self.register_instruction(ReadNode(dest)) + + self.current_method = self.current_type.get_method('str') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - out_int = self.register_param(VariableInfo('x', None)) - out_msg = self.define_internal_local() - self.register_instruction(ToStrNode(out_msg, out_int)) - self.register_instruction(PrintNode(out_msg)) - self.register_instruction(ReturnNode(self_local)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + dest = self.define_internal_local() + str_val = self.register_param(VariableInfo('value',None)) + self.register_instruction(ToStrNode(dest,str_val)) self.current_method = self.current_function = None self.current_type = None - def build_basic_string(self): - self.current_type = self.context.get_type('String') - type_node = self.register_type('String') - type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] - type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] - ### length - self.current_method = self.current_type.get_method('length') - type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - length_var = self.define_internal_local() - self.register_instruction(LengthNode(length_var, self_local)) - self.register_instruction(ReturnNode(length_var)) - self.current_method = self.current_function = None - ### concat - self.current_method = self.current_type.get_method('concat') - type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - param_local = self.register_param(VariableInfo('s', None)) - result_msg = self.define_internal_local() - self.register_instruction(ConcatNode(result_msg, self_local, param_local)) - self.register_instruction(ReturnNode(result_msg)) - self.current_method = self.current_function = None - ### substr - self.current_method = self.current_type.get_method('substr') + def define_object_type(self): + self.current_type = self.context.get_type('Object') + type_node = self.register_type('Object') + type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - start_parm = self.register_param(VariableInfo('i', None)) - length_param = self.register_param(VariableInfo('l', None)) - result_msg = self.define_internal_local() - length_var = self.define_internal_local() - sum_var = self.define_internal_local() - cmp_var1 = self.define_internal_local() - cmp_var2 = self.define_internal_local() - cmp_var3 = self.define_internal_local() - no_error_label1 = self.to_label_name('error1') - no_error_label2 = self.to_label_name('error2') - no_error_label3 = self.to_label_name('error3') - self.register_instruction(LengthNode(length_var, self_local)) - # start param negative - self.register_instruction(LessEqNode(cmp_var1, 0, start_parm)) - self.register_instruction(IfGotoNode(cmp_var1, no_error_label1)) - self.register_instruction(ErrorNode()) - self.register_instruction(LabelNode(no_error_label1)) - # length param negative - self.register_instruction(LessEqNode(cmp_var2, 0, length_param)) - self.register_instruction(IfGotoNode(cmp_var2, no_error_label2)) - self.register_instruction(ErrorNode()) - self.register_instruction(LabelNode(no_error_label2)) - # substr larger than max length - self.register_instruction(PlusNode(sum_var, start_parm, length_param)) - self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) - self.register_instruction(IfGotoNode(cmp_var3, no_error_label3)) - self.register_instruction(ErrorNode()) - self.register_instruction(LabelNode(no_error_label3)) - self.register_instruction(SubstringNode(result_msg, self_local, start_parm, length_param)) - self.register_instruction(ReturnNode(result_msg)) + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) self.current_method = self.current_function = None - self.current_type = None diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index c1a82cec..0667490d 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -4,14 +4,14 @@ , SubstringNode, ToStrNode, GetAttribNode, SetAttribNode, LabelNode, GotoNode, IfGotoNode \ , DataNode, ToIntNode -from ..cp.visitor import on, when +from ..cp import visitor class CIL_FORMATTER(object): - @on('node') + @visitor.on('node') def visit(self, node): pass - @when(ProgramNode) + @visitor.when(ProgramNode) def visit(self, node: ProgramNode): dottypes = '\n'.join(self.visit(t) for t in node.dottypes) dotdata = '\n'.join(self.visit(t) for t in node.dotdata) @@ -19,18 +19,18 @@ def visit(self, node: ProgramNode): return f'.TYPES\n{dottypes}\n\n.DATA\n{dotdata}\n\n.CODE\n{dotcode}' - @when(DataNode) + @visitor.when(DataNode) def visit(self, node: DataNode): return f'{node.name} = "{node.value}"' - @when(TypeNode) + @visitor.when(TypeNode) def visit(self, node: TypeNode): 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}}' - @when(FunctionNode) + @visitor.when(FunctionNode) def visit(self, node: FunctionNode): params = '\n\t'.join(self.visit(x) for x in node.params) localvars = '\n\t'.join(self.visit(x) for x in node.localvars) @@ -38,157 +38,158 @@ def visit(self, node: FunctionNode): return f'function {node.name} {{\n\t{params}\n\n\t{localvars}\n\n\t{instructions}\n}}' - @when(ParamNode) + @visitor.when(ParamNode) def visit(self, node: ParamNode): return f'PARAM {node.name}' - @when(LocalNode) + @visitor.when(LocalNode) def visit(self, node: LocalNode): return f'LOCAL {node.name}' - @when(AssignNode) + @visitor.when(AssignNode) def visit(self, node: AssignNode): return f'{node.dest} = {node.source}' - @when(EqualNode) - def visit(self, node: EqualNode): - return f'{node.dest} = {node.left} == {node.right}' - @when(PlusNode) + @visitor.when(PlusNode) def visit(self, node: PlusNode): return f'{node.dest} = {node.left} + {node.right}' - @when(MinusNode) + @visitor.when(MinusNode) def visit(self, node: MinusNode): return f'{node.dest} = {node.left} - {node.right}' - @when(StarNode) + @visitor.when(StarNode) def visit(self, node: StarNode): return f'{node.dest} = {node.left} * {node.right}' - @when(DivNode) + @visitor.when(DivNode) def visit(self, node: DivNode): return f'{node.dest} = {node.left} / {node.right}' - @when(AllocateNode) + @visitor.when(AllocateNode) def visit(self, node: AllocateNode): return f'{node.dest} = ALLOCATE {node.type}' - @when(TypeOfNode) + @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): return f'{node.dest} = TYPEOF {node.obj}' - @when(StaticCallNode) + @visitor.when(StaticCallNode) def visit(self, node: StaticCallNode): return f'{node.dest} = CALL {node.function}' - @when(DynamicCallNode) + @visitor.when(DynamicCallNode) def visit(self, node: DynamicCallNode): return f'{node.dest} = VCALL {node.type} {node.method}' - @when(ArgNode) + @visitor.when(ArgNode) def visit(self, node: ArgNode): return f'ARG {node.name}' - @when(ReturnNode) + @visitor.when(ReturnNode) def visit(self, node: ReturnNode): return f'RETURN {node.value if node.value is not None else ""}' - @when(ReadNode) + @visitor.when(ReadNode) def visit(self, node: ReadNode): return f'{node.dest} = READ' - @when(PrintNode) + @visitor.when(PrintNode) def visit(self, node: PrintNode): return f'PRINT {node.str_addr}' - @when(LoadNode) + @visitor.when(LoadNode) def visit(self, node: LoadNode): return f'{node.dest} = LOAD {node.msg}' - @when(LengthNode) + @visitor.when(LengthNode) def visit(self, node: LengthNode): return f'{node.dest} = LENGTH {node.msg}' - @when(ConcatNode) + @visitor.when(ConcatNode) def visit(self, node: ConcatNode): return f'{node.dest} = CONCAT {node.msg1} {node.msg2}' - @when(PrefixNode) + @visitor.when(PrefixNode) def visit(self, node: PrefixNode): return f'{node.dest} = PREFIX {node.msg1} {node.msg2}' - @when(SubstringNode) + @visitor.when(SubstringNode) def visit(self, node: SubstringNode): return f'{node.dest} = SUBSTRING {node.msg1} {node.start} {node.length}' - @when(ToStrNode) + @visitor.when(ToStrNode) def visit(self, node: ToStrNode): return f'{node.dest} = STR {node.ivalue}' - @when(ToIntNode) + @visitor.when(ToIntNode) def visit(self, node: ToIntNode): return f'{node.dest} = INT {node.msg}' - @when(GetAttribNode) + @visitor.when(GetAttribNode) def visit(self, node: GetAttribNode): return f'{node.dest} = GETATTR {node.obj} {node.attrib}' - @when(SetAttribNode) + @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): return f'SETATTR {node.obj} {node.attrib} {node.value}' - @when(LabelNode) + @visitor.when(LabelNode) def visit(self, node: LabelNode): return f'LABEL {node.label}' - @when(GotoNode) + @visitor.when(GotoNode) def visit(self, node: GotoNode): return f'GOTO {node.label}' - @when(IfGotoNode) + @visitor.when(IfGotoNode) def visit(self, node: IfGotoNode): return f'IF {node.value} GOTO {node.label}' ###################### nodes to throw ####################### - # @when(ErrorNode) + # @visitor.when(EqualNode) + # def visit(self, node: EqualNode): + # return f'{node.dest} = {node.left} == {node.right}' + + # @visitor.when(ErrorNode) # def visit(self, node: ErrorNode): # return f'ERROR {node.error}' - # @when(ConformNode) + # @visitor.when(ConformNode) # def visit(self, node: ConformNode): # return f'{node.dest} = COMFORM {node.obj} {node.type}' - # @when(ComplementNode) + # @visitor.when(ComplementNode) # def visit(self, node: ComplementNode): # return f'{node.dest} = COMPLEMENT {node.body}' - # @when(LessNode) + # @visitor.when(LessNode) # def visit(self, node: LessNode): # return f'{node.dest} = {node.left} < {node.right}' - # @when(IsVoidNode) + # @visitor.when(IsVoidNode) # def visit(self, node: IsVoidNode): # return f'{node.dest} = ISVOID {node.body}' - # @when(LessEqNode) + # @visitor.when(LessEqNode) # def visit(self, node: LessEqNode): # return f'{node.dest} = {node.left} <= {node.right}' - # @when(CleanArgsNode) + # @visitor.when(CleanArgsNode) # def visit(self, node:CleanArgsNode): # return f'CLEANARG {node.nargs}' - # @when(StringEqualNode) + # @visitor.when(StringEqualNode) # def visit(self, node: StringEqualNode): # return f'{node.dest} = STREQ {node.msg1} {node.msg2}' - # @when(CopyNode) + # @visitor.when(CopyNode) # def visit(self, node: CopyNode): # return f'{node.dest} = COPY {node.obj}' - # @when(TypeNameNode) + # @visitor.when(TypeNameNode) # def visit(self, node: TypeNameNode): # return f'{node.dest} = TYPENAME {node.type}' diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 5d957bc2..5e2d032f 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -1,285 +1,121 @@ -import parser as cool -from .cil_ast import ProgramNode, TypeNode, FunctionNode, ParamNode, LocalNode, AssignNode, PlusNode \ - , MinusNode, StarNode, DivNode, AllocateNode, TypeOfNode, StaticCallNode, DynamicCallNode \ - , ArgNode, ReturnNode, ReadNode, PrintNode, LoadNode, LengthNode, ConcatNode, PrefixNode \ - , SubstringNode, ToStrNode, GetAttribNode, SetAttribNode, LabelNode, GotoNode, IfGotoNode \ - , DataNode, ToIntNode +from ...engine import parser as cool +from .cil_ast import * +from ..cp import visitor +from ..cp.semantic import VariableInfo , Scope +from .cil import BASE_COOL_CIL_TRANSFORM -from .cil import BASE_COOL_CIL_TRANSFORM, VariableInfo -from .utils import Scope -from ..cp.visitor import when,on +class COOL_TO_CIL(BASE_COOL_CIL_TRANSFORM): - -class COOL_TO_CIL_VISITOR(BASE_COOL_CIL_TRANSFORM): - @on('node') - def visit(self, node, scope:Scope): + def __init__(self): pass - def order_caseof(self, node:cool.CaseOfNode): - return list(node.cases) - - def find_type_name(self, typex, func_name): - if func_name in typex.methods: - return typex.name - return self.find_type_name(typex.parent, func_name) - - def init_class_attr(self, scope:Scope, class_id, self_inst): - attr_nodes = self.attr_init[class_id] - for attr in attr_nodes: - attr_scope = Scope(parent=scope) - attr_scope.define_var('self', self_inst) - self.visit(attr, attr_scope) - - def build_attr_init(self, node:cool.ProgramNode): - self.attr_init = dict() - for classx in node.classes: - self.attr_init[classx.id] = [] - if classx.parent and not classx.parent in ['IO', 'Object']: - self.attr_init[classx.id] += self.attr_init[classx.parent] - for feature in classx.features: - if type(feature) is cool.AttrDeclarationNode: - self.attr_init[classx.id].append(feature) - - @when(cool.ProgramNode) - def visit(self, node:cool.ProgramNode=None, scope:Scope=None): - scope = Scope() - self.build_attr_init(node) - self.current_function = self.register_function('main') + @visitor.on('node') + def visit(self,node,scope): + pass + + @visitor.when(cool.ProgramNode) + def visit(self,node: cool.ProgramNode,scope: Scope): + self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() - self.register_instruction(AllocateNode(instance, 'Main')) - self.init_class_attr(scope, 'Main', instance) + self.register_instruction(AllocateNode('Main',instance)) self.register_instruction(ArgNode(instance)) - self.register_instruction(StaticCallNode(self.to_function_name('main', 'Main'), result)) - self.register_instruction(CleanArgsNode(1)) + name = self.to_function_name('main','Main') + self.register_instruction(StaticCallNode(name,result)) self.register_instruction(ReturnNode(0)) self.current_function = None - for classx in node.classes: - self.visit(classx, scope) - - return ProgramNode(self.dottypes, self.dotdata, self.dotcode) - - @when(cool.ClassDeclarationNode) - def visit(self, node:cool.ClassDeclarationNode, scope:Scope): - self.current_type = self.context.get_type(node.id) + for declaration, child_scope in zip(node.declarations,scope.children): + self.visit(declaration,child_scope) - type_node = self.register_type(node.id) - type_node.attributes = [ attr.name for attr in self.current_type.get_all_attributes() ] - type_node.methods = [ (method.name, self.to_function_name(method.name, typex.name)) for method, typex in self.current_type.get_all_methods() ] + return ProgramNode(self.dottypes,self.dotdata,self.dotcode) - for feature in node.features: - if isinstance(feature, cool.FuncDeclarationNode): - self.visit(feature, scope) + @visitor.when(cool.ClassDeclarationNode) + def visit(self,node: cool.ClassDeclarationNode,scope: Scope): + self.current_type = self.context.get_type(node.id) + type_node = self.register_type(node.id) + type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + fun_declarations = (f for f in node.features if isinstance(f,cool.FuncDeclarationNode)) + for feature, child_scope in zip(fun_declarations,scope.children): + self.visit(feature,child_scope) self.current_type = None - @when(cool.AttrDeclarationNode) - def visit(self, node:cool.AttrDeclarationNode, scope:Scope): - result = self.visit(node.expression, scope) if node.expression else 0 - self_inst = scope.get_var('self').local_name - self.register_instruction(SetAttribNode(self_inst, node.id, result)) - - @when(cool.FuncDeclarationNode) - def visit(self, node:cool.FuncDeclarationNode, scope:Scope): - func_scope = Scope(parent=scope) + @visitor.when(cool.FuncDeclarationNode) + def visit(self,node: cool.FuncDeclarationNode,scope: Scope): self.current_method = self.current_type.get_method(node.id) type_name = self.current_type.name - - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - func_scope.define_var('self', self_local) - for param_name in self.current_method.param_names: - param_local = self.register_param(VariableInfo(param_name, None)) - func_scope.define_var(param_name, param_local) - body = self.visit(node.expression, func_scope) - self.register_instruction(ReturnNode(body)) - - self.current_method = self.current_function = None - - - @when(cool.IfThenElseNode) - def visit(self, node:cool.IfThenElseNode, scope:Scope): - if_scope = Scope(parent=scope) - cond_result = self.visit(node.condition, scope) - result = self.define_internal_local() - true_label = self.to_label_name('if_true') - end_label = self.to_label_name('end_if') - self.register_instruction(IfGotoNode(cond_result, true_label)) - false_result = self.visit(node.else_body, if_scope) - self.register_instruction(AssignNode(result, false_result)) - self.register_instruction(GotoNode(end_label)) - self.register_instruction(LabelNode(true_label)) - true_result = self.visit(node.if_body, if_scope) - self.register_instruction(AssignNode(result, true_result)) - self.register_instruction(LabelNode(end_label)) - - return result + self.current_function = self.register_function(self.to_function_name(node.id, type_name)) + for param_name, param_type in node.params: + self.register_param(VariableInfo(param_name, param_type)) + body, _ = self.visit(node.body,scope) - @when(cool.WhileLoopNode) - def visit(self, node:cool.WhileLoopNode, scope:Scope): - while_scope = Scope(parent=scope) - loop_label = self.to_label_name('loop') - body_label = self.to_label_name('body') - end_label = self.to_label_name('pool') - self.register_instruction(LabelNode(loop_label)) - condition = self.visit(node.condition, scope) - self.register_instruction(IfGotoNode(condition, body_label)) - self.register_instruction(GotoNode(end_label)) - self.register_instruction(LabelNode(body_label)) - self.visit(node.body, while_scope) - self.register_instruction(LabelNode(end_label)) - - return 0 - - - @when(cool.BlockNode) - def visit(self, node:cool.BlockNode, scope:Scope): - result = None - for expr in node.expressions: - result = self.visit(expr, scope) - - return result - - - @when(cool.LetNode) - def visit(self, node:cool.LetNode, scope:Scope): - var_name = self.register_local(VariableInfo(node.id, None)) - scope.define_var(node.id, var_name) - result = self.visit(node.expression, scope) if node.expression else 0 - - self.register_instruction(AssignNode(var_name, result)) - - @when(cool.LetInNode) - def visit(self, node:cool.LetInNode, scope:Scope): - let_scope = Scope(parent=scope) - for let in node.let_body: - self.visit(let, let_scope) + self.register_instruction(ReturnNode(body)) + self.current_method = None - result = self.visit(node.in_body, let_scope) - return result + @visitor.when(cool.AttrDeclarationNode) + def visit(self,node: cool.AttrDeclarationNode,scope:Scope): + attr_info = scope.find_variable(node.id) + vtype = get_type(attr_info.type) + local_attr = self.register_local(VariableInfo(attr_info.name,vtype)) - @when(cool.CaseNode) - def visit(self, node:cool.CaseNode, scope:Scope, typex=None, result_inst=None, end_label=None): - cond = self.define_internal_local() - not_cond = self.define_internal_local() - case_label = self.to_label_name(f'case_{node.type}') - self.register_instruction(ConformNode(cond, typex, node.type)) - self.register_instruction(ComplementNode(not_cond, cond)) - self.register_instruction(IfGotoNode(not_cond, case_label)) - case_scope = Scope(parent=scope) - case_var = self.register_local(VariableInfo(node.id, None)) - case_scope.define_var(node.id, case_var) - case_result = self.visit(node.expression, case_scope) - self.register_instruction(AssignNode(result_inst, case_result)) - self.register_instruction(GotoNode(end_label)) - self.register_instruction(LabelNode(case_label)) + expr, _ = self.visit(node.expression,scope) + self.register_instruction(AssignNode(local_attr,expr)) + return local_attr,vtype - @when(cool.CaseOfNode) - def visit(self, node:cool.CaseOfNode, scope:Scope): - order_cases = self.order_caseof(node) - end_label = self.to_label_name('end') - error_label = self.to_label_name('error') - result = self.define_internal_local() - type_inst = self.define_internal_local() - is_void = self.define_internal_local() - obj_inst = self.visit(node.expression, scope) - self.register_instruction(IsVoidNode(is_void, obj_inst)) - self.register_instruction(IfGotoNode(is_void, error_label)) - self.register_instruction(TypeOfNode(obj_inst, type_inst)) - for case in order_cases: - self.visit(case, scope, type_inst, result, end_label) - self.register_instruction(LabelNode(error_label)) - self.register_instruction(ErrorNode()) - self.register_instruction(LabelNode(end_label)) + @visitor.when(cool.AssignNode) + def visit(self,node: cool.AssignNode,scope: Scope): + vinfo = scope.find_variable(node.id) + vname = self.register_local(VariableInfo(node.id,get_type(vinfo.type))) + expr = self.visit(node.expression,scope) + return self.register_instruction(AssignNode(vname,expr)) - return result + @visitor.when(cool.IfThenElseNode) + def visit(self,node:cool.IfThenElseNode,scope: Scope): + cond, _ = self.visit(node.condition, scope) + true_label = LabelNode('TRUE') + end_label = LabelNode('END') - @when(cool.AssignNode) - def visit(self, node:cool.AssignNode, scope:Scope): - value = self.visit(node.expression, scope) - pvar = scope.get_var(node.id) - if not pvar: - selfx = scope.get_var('self').local_name - self.register_instruction(SetAttribNode(selfx, node.id, value)) - else: - pvar = pvar.local_name - self.register_instruction(AssignNode(pvar, value)) - return 0 - - @when(cool.MemberCallNode) - def visit(self, node:cool.MemberCallNode, scope:Scope): - type_name = self.current_type.name result = self.define_internal_local() - rev_args = [] - for arg in node.args: - arg_value = self.visit(arg, scope) - rev_args = [ arg_value ] + rev_args - for arg_value in rev_args: - self.register_instruction(ArgNode(arg_value)) - self_inst = scope.get_var('self').local_name - self.register_instruction(ArgNode(self_inst)) - self.register_instruction(DynamicCallNode(type_name, node.id, result)) - self.register_instruction(CleanArgsNode(len(node.args)+1)) - - return result + self.register_instruction(IfGotoNode(cond,true_label)) - @when(cool.FunctionCallNode) - def visit(self, node:cool.FunctionCallNode, scope:Scope): - typex = None if not node.type else self.context.get_type(node.type) - type_name = self.find_type_name(typex, node.id) if typex else '' - func_name = self.to_function_name(node.id, type_name) if type_name else '' - result = self.define_internal_local() - rev_args = [] - for arg in node.args: - arg_value = self.visit(arg, scope) - rev_args = [ arg_value ] + rev_args - for arg_value in rev_args: - self.register_instruction(ArgNode(arg_value)) - obj_inst = self.visit(node.obj, scope) - self.register_instruction(ArgNode(obj_inst)) - self.register_instruction(StaticCallNode(func_name, result)) if func_name else self.register_instruction(DynamicCallNode(node.obj.static_type.name, node.id, result)) - self.register_instruction(CleanArgsNode(len(node.args)+1)) - - return result - - - @when(cool.NewNode) - def visit(self, node:cool.NewNode, scope:Scope): # Remember attributes initialization - result = self.define_internal_local() - self.register_instruction(AllocateNode(result, node.type)) - self.init_class_attr(scope, node.type, result) + false_expr , ftype = self.visit(node.else_body, scope) + self.register_instruction(AssignNode(result,false_expr)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(true_label) - return result + true_expr , ttype = self.visit(node.if_body, scope) + self.register_instruction(AssignNode(result,true_expr)) + self.register_instruction(end_label) - @when(cool.IsVoidNode) - def visit(self, node:cool.IsVoidNode, scope:Scope): - body = self.visit(node.expression, scope) - result = self.define_internal_local() + return result, get_common_basetype([ftype,ttype]) - self.register_instruction(IsVoidNode(result, body)) - return result + @visitor.when(cool.WhileLoopNode) + def visit(self,node:cool.WhileLoopNode,scope: Scope): + start_label = LabelNode('START') + continue_label = LabelNode('CONTINUE') + end_label = LabelNode('END') - @when(cool.NotNode) - def visit(self, node:cool.NotNode, scope:Scope): - value = self.visit(node.expression, scope) result = self.define_internal_local() + self.register_instruction(start_label) - self.register_instruction(ComplementNode(result, value)) - return result - - @when(cool.ComplementNode) - def visit(self, node:cool.ComplementNode, scope:Scope): - value = self.visit(node.expression, scope) - result = self.define_internal_local() + cond, _ = self.visit(node.condition,scope) + self.register_instruction(IfGotoNode(cond, continue_label)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(continue_label) + body, btype = self.visit(node.body, scope) + self.register_instruction(GotoNode(start_label)) + self.register_instruction(end_label) - self.register_instruction(ComplementNode(result, value)) - return result + self.register_instruction(AssignNode(result,body)) + return result, btype - @when(cool.PlusNode) + @visitor.when(cool.PlusNode) def visit(self, node:cool.PlusNode, scope:Scope): left = self.visit(node.left, scope) right = self.visit(node.right, scope) @@ -288,7 +124,7 @@ def visit(self, node:cool.PlusNode, scope:Scope): self.register_instruction(PlusNode(result, left, right)) return result - @when(cool.MinusNode) + @visitor.when(cool.MinusNode) def visit(self, node:cool.MinusNode, scope:Scope): left = self.visit(node.left, scope) right = self.visit(node.right, scope) @@ -297,7 +133,7 @@ def visit(self, node:cool.MinusNode, scope:Scope): self.register_instruction(MinusNode(result, left, right)) return result - @when(cool.StarNode) + @visitor.when(cool.StarNode) def visit(self, node:cool.StarNode, scope:Scope): left = self.visit(node.left, scope) right = self.visit(node.right, scope) @@ -306,7 +142,7 @@ def visit(self, node:cool.StarNode, scope:Scope): self.register_instruction(StarNode(result, left, right)) return result - @when(cool.DivNode) + @visitor.when(cool.DivNode) def visit(self, node:cool.DivNode, scope:Scope): left = self.visit(node.left, scope) right = self.visit(node.right, scope) @@ -314,58 +150,34 @@ def visit(self, node:cool.DivNode, scope:Scope): self.register_instruction(DivNode(result, left, right)) return result + + @visitor.when(cool.BlockNode) + def visit(self,node,scope): + pass - @when(cool.EqualNode) - def visit(self, node:cool.EqualNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) - result = self.define_internal_local() + @visitor.when(cool.LetInNode) + def visit(self,node,scope): + pass - if node.left.static_type == self.context.get_type('String'): - self.register_instruction(StringEqualNode(result, left, right)) - else: - self.register_instruction(EqualNode(result, left, right)) - return result + @visitor.when(cool.CaseOfNode) + def visit(self,node,scope): + pass - @when(cool.LessNode) - def visit(self, node:cool.LessNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) - result = self.define_internal_local() + @visitor.when(cool.FunctionCallNode) + def visit(self,node,scope): + pass - self.register_instruction(LessNode(result, left, right)) - return result + @visitor.when(cool.MemberCallNode) + def visit(self,node,scope): + pass - @when(cool.LessEqualNode) - def visit(self, node:cool.LessEqualNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) - result = self.define_internal_local() + @visitor.when(cool.NewNode) + def visit(self,node,scope): + pass - self.register_instruction(LessEqNode(result, left, right)) - return result - - @when(cool.IdNode) - def visit(self, node:cool.IdNode, scope:Scope): - pvar = scope.get_var(node.token) - if not pvar: - selfx = scope.get_var('self').local_name - pvar = self.define_internal_local() - - self.register_instruction(GetAttribNode(pvar, selfx, node.token)) # Perhaps GetAttribNode could need info about self type, this is know in self.current_type variable - else: - pvar = pvar.local_name - return pvar - - @when(cool.BoolNode) - def visit(self, node:cool.BoolNode, scope:Scope): - return 1 if node.token.lower() == 'true' else 0 - - @when(cool.IntegerNode) - def visit(self, node:cool.IntegerNode, scope:Scope): - return int(node.token) - - @when(cool.StringNode) - def visit(self, node:cool.StringNode, scope:Scope): - string = self.register_data(node.token[1:-1]) - return string.name + @visitor.when(cool.AtomicNode) + def visit(self,node,scope): + pass + + + \ No newline at end of file diff --git a/src/engine/codegen/utils.py b/src/engine/codegen/utils.py index 8f26e864..e922f295 100644 --- a/src/engine/codegen/utils.py +++ b/src/engine/codegen/utils.py @@ -1,36 +1,36 @@ -class Var: - def __init__(self, idx, local_name): - self.id = idx - self.local_name = local_name +# class Var: +# def __init__(self, idx, local_name): +# self.id = idx +# self.local_name = local_name - def __str__(self): - return f'[var] {self.id}: {self.local_name}' +# def __str__(self): +# return f'[var] {self.id}: {self.local_name}' - def __repr__(self): - return str(self) +# def __repr__(self): +# return str(self) -class Scope: - def __init__(self, parent=None): - self.parent = parent - self.vars = {} +# class Scope: +# def __init__(self, parent=None): +# self.parent = parent +# self.vars = {} - def child(self): - return Scope(parent=self) +# def child(self): +# return Scope(parent=self) - def define_var(self, name, local_name): - var = self.vars[name] = Var(name, local_name) - return var +# def define_var(self, name, local_name): +# var = self.vars[name] = Var(name, local_name) +# return var - def get_var(self, name): - try: - return self.vars[name] - except KeyError: - if not self.parent is None: - return self.parent.get_var(name) - return None +# def get_var(self, name): +# try: +# return self.vars[name] +# except KeyError: +# if not self.parent is None: +# return self.parent.get_var(name) +# return None - def __str__(self): - return '{\n' + ('\t' if self.parent is None else 'Parent:\n' + f'{self.parent}\n\t') + '\n\t'.join(str(x) for x in self.vars.values()) + '\n}' +# def __str__(self): +# return '{\n' + ('\t' if self.parent is None else 'Parent:\n' + f'{self.parent}\n\t') + '\n\t'.join(str(x) for x in self.vars.values()) + '\n}' - def __repr__(self): - return str(self) \ No newline at end of file +# def __repr__(self): +# return str(self) \ No newline at end of file diff --git a/src/main.py b/src/main.py index 5ad9726e..bb574966 100644 --- a/src/main.py +++ b/src/main.py @@ -9,10 +9,11 @@ exit(1) input_file = open(args[1], "r") +output_file = open(args[2], 'w') t = input_file.read() -output_file = args[2] +# output_file = args[2] tokens, errors = tokenizer(t) @@ -25,6 +26,28 @@ parse, operations = CoolParser(tokens) +ast = evaluate_reverse_parse(parse,operations,tokens) + +collect = Collector() +collect.visit(ast) + +context = collect.context +builder = Builder(context) +builder.visit(ast) +context = builder.context +checker = Checker(context) +checker.visit(ast) + +# cil = COOL_TO_CIL_VISITOR(checker.context) + +# cil_ast = cil.visit(ast) + +# f_ast = CIL_FORMATTER().visit(cil_ast) +# string_formatted = str(f_ast) +# output_file.write(string_formatted) +# output_file.close() + + if not operations: message = f'ERROR at or near "{parse.lex}"' print(SyntacticError(parse.line,parse.column, message)) diff --git a/src/makefile b/src/makefile index 021189d6..271f146c 100644 --- a/src/makefile +++ b/src/makefile @@ -9,3 +9,6 @@ clean: test: pytest ../tests -v --tb=short -m=${TAG} +quick_test: + bash coolc.sh test.cl + diff --git a/src/test.cl b/src/test.cl new file mode 100755 index 00000000..3d4300df --- /dev/null +++ b/src/test.cl @@ -0,0 +1,32 @@ +class Main inherits IO { + + main () : Object { + { + let x:E <- new E in x.f() = x@E.f() ; + let x:A <- new B in out_string( x.f().m() ); + let x:A <- new A in out_string( x.f().m() ); + } + + }; +}; + +class A { + m () : String { "A" }; + f () : A { new A }; +}; + +class B inherits A { + m () : String { "B" }; +}; + + +class C { + f () : String {"C"}; +}; + +class D inherits C { +}; + +class E inherits D { + f () : String {"E"}; +}; diff --git a/src/test.mips b/src/test.mips new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/src/test.mips @@ -0,0 +1 @@ +[] \ No newline at end of file From 3c4f3d7cb22c0e81b86af442c7f5226a5aea046b Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 20 Nov 2020 12:02:27 -0500 Subject: [PATCH 029/191] Implementando visitor de CIL... definir los nodos unarios y binarios --- src/engine/__init__.py | 4 +- src/engine/codegen/cil.py | 5 +- src/engine/codegen/cil_ast.py | 32 +++++----- src/engine/codegen/cil_format.py | 37 ++++++----- src/engine/codegen/to_cil.py | 102 ++++++++++++++++++++----------- src/main.py | 13 ++-- 6 files changed, 113 insertions(+), 80 deletions(-) diff --git a/src/engine/__init__.py b/src/engine/__init__.py index fd691753..cefec6cf 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -1,5 +1,5 @@ from .lexer import tokenizer -from .parser import CoolParser +from .parser import * from .cp import evaluate_reverse_parse from .visitors import Builder from .visitors import Checker @@ -7,5 +7,5 @@ from .visitors import Format from .visitors import Inferer from .errors import * -from .codegen import COOL_TO_CIL_VISITOR +from .codegen.to_cil import COOL_TO_CIL from .codegen.cil_format import CIL_FORMATTER diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 5233f27d..2f63cd0b 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -10,7 +10,10 @@ def __init__(self, context): self.current_method = None self.current_function = None self.context = context - + self.define_object_type() + self.define_string_type() + self.define_io_type() + @property def params(self): return self.current_function.params diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 757da0ad..2d1ef94c 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -49,6 +49,17 @@ def __init__(self, dest, left, right): self.left = left self.right = right +class UnaryNode(InstructionNode): + def __init__(self,dest, expression): + self.dest = dest + self.expression = expression + +class ComplementNode(UnaryNode): + pass + +class IsVoidNode(UnaryNode): + pass + class PlusNode(ArithmeticNode): pass @@ -64,6 +75,12 @@ class DivNode(ArithmeticNode): class EqualNode(ArithmeticNode): pass +class LessNode(ArithmeticNode): + pass + +class LessEqNode(ArithmeticNode): + pass + class GetAttribNode(InstructionNode): def __init__(self, dest, obj, attrib): self.dest = dest @@ -200,22 +217,7 @@ def __init__(self, str_addr): # self.obj = obj # self.type = typex -# class ComplementNode(InstructionNode): -# def __init__(self, dest, body): -# self.dest = dest -# self.body = body - -# class IsVoidNode(InstructionNode): -# def __init__(self, dest, body): -# self.dest = dest -# self.body = body - -# class LessNode(ArithmeticNode): -# pass - -# class LessEqNode(ArithmeticNode): -# pass # class CleanArgsNode(InstructionNode): # def __init__(self, nargs): diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 0667490d..7892dae2 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -1,8 +1,4 @@ -from .cil_ast import ProgramNode, TypeNode, FunctionNode, ParamNode, LocalNode, AssignNode, PlusNode \ - , MinusNode, StarNode, DivNode, AllocateNode, TypeOfNode, StaticCallNode, DynamicCallNode \ - , ArgNode, ReturnNode, ReadNode, PrintNode, LoadNode, LengthNode, ConcatNode, PrefixNode \ - , SubstringNode, ToStrNode, GetAttribNode, SetAttribNode, LabelNode, GotoNode, IfGotoNode \ - , DataNode, ToIntNode +from .cil_ast import * from ..cp import visitor @@ -147,6 +143,22 @@ def visit(self, node: GotoNode): def visit(self, node: IfGotoNode): return f'IF {node.value} GOTO {node.label}' + @visitor.when(ComplementNode) + def visit(self, node: ComplementNode): + return f'{node.dest} = COMPLEMENT {node.body}' + + @visitor.when(LessNode) + def visit(self, node: LessNode): + return f'{node.dest} = {node.left} < {node.right}' + + @visitor.when(IsVoidNode) + def visit(self, node: IsVoidNode): + return f'{node.dest} = ISVOID {node.body}' + + @visitor.when(LessEqNode) + def visit(self, node: LessEqNode): + return f'{node.dest} = {node.left} <= {node.right}' + ###################### nodes to throw ####################### # @visitor.when(EqualNode) @@ -161,21 +173,6 @@ def visit(self, node: IfGotoNode): # def visit(self, node: ConformNode): # return f'{node.dest} = COMFORM {node.obj} {node.type}' - # @visitor.when(ComplementNode) - # def visit(self, node: ComplementNode): - # return f'{node.dest} = COMPLEMENT {node.body}' - - # @visitor.when(LessNode) - # def visit(self, node: LessNode): - # return f'{node.dest} = {node.left} < {node.right}' - - # @visitor.when(IsVoidNode) - # def visit(self, node: IsVoidNode): - # return f'{node.dest} = ISVOID {node.body}' - - # @visitor.when(LessEqNode) - # def visit(self, node: LessEqNode): - # return f'{node.dest} = {node.left} <= {node.right}' # @visitor.when(CleanArgsNode) # def visit(self, node:CleanArgsNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 5e2d032f..0b397dae 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -1,4 +1,4 @@ -from ...engine import parser as cool +from engine import parser as cool from .cil_ast import * from ..cp import visitor from ..cp.semantic import VariableInfo , Scope @@ -7,9 +7,19 @@ class COOL_TO_CIL(BASE_COOL_CIL_TRANSFORM): - def __init__(self): - pass + def define_binary_node(self, node: cool.BinaryNode, scope: Scope, cil_node: Node): + result = self.define_internal_local() + left, typex = self.visit(node.left, scope) + right, typex = self.visit( node.right, scope) + self.register_instruction(cil_node(result, left, right)) + return result, typex + def define_unary_node(self, node: cool.UnaryNode, scope: Scope, cil_node: Node): + result = self.define_internal_local() + expr ,typex = self.visit(node.expression, scope) + self.register_instruction(cil_node(result, expr)) + return result, typex + @visitor.on('node') def visit(self,node,scope): pass @@ -115,53 +125,73 @@ def visit(self,node:cool.WhileLoopNode,scope: Scope): self.register_instruction(AssignNode(result,body)) return result, btype - @visitor.when(cool.PlusNode) - def visit(self, node:cool.PlusNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) + @visitor.when(cool.BlockNode) + def visit(self,node: cool.BlockNode,scope: Scope): result = self.define_internal_local() + for expr in node.expressions: + val, typex = self.visit(expr, scope) + self.register_instruction(AssignNode(result,val)) + return result, typex - self.register_instruction(PlusNode(result, left, right)) - return result + @visitor.when(cool.LetInNode) + def visit(self,node: cool.LetInNode,scope: Scope): + let_scope = scope.create_child() + for let in node.let_body: + self.visit(let,let_scope) - @visitor.when(cool.MinusNode) - def visit(self, node:cool.MinusNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) result = self.define_internal_local() + expr, typex = self.visit(node.in_body,let_scope) + self.register_instruction(AssignNode(result,expr)) + return result,typex + + @visitor.when(cool.CaseOfNode) + def visit(self,node: cool.CaseOfNode,scope: Scope): + expr, typex = self.visit(node.expression, scope) + result = self.define_internal_local() + exptype = self.define_internal_local() + end_label = LabelNode('END') + self.register_instruction(TypeOfNode(expr,exptype)) + + for i ,case, child_scope in enumerate(zip(node.branches, scope.children)): + expr_n, type_n = self.visit(case,child_scope) + self.register_instruction(AssignNode(result,expr_n)) + self.register_instruction(GotoNode(end_label)) + self.register_instruction(LabelNode(f'CASE_{i}')) + self.register_instruction(end_label) + + return result, typex + + @visitor.when(cool.PlusNode) + def visit(self, node:cool.PlusNode, scope:Scope): + self.define_binary_node(node,scope,PlusNode) - self.register_instruction(MinusNode(result, left, right)) - return result + @visitor.when(cool.MinusNode) + def visit(self, node:cool.MinusNode, scope:Scope): + self.define_binary_node(node,scope,MinusNode) @visitor.when(cool.StarNode) def visit(self, node:cool.StarNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) - result = self.define_internal_local() - - self.register_instruction(StarNode(result, left, right)) - return result + self.define_binary_node(node,scope,StarNode) @visitor.when(cool.DivNode) def visit(self, node:cool.DivNode, scope:Scope): - left = self.visit(node.left, scope) - right = self.visit(node.right, scope) - result = self.define_internal_local() + self.define_binary_node(node,scope,DivNode) - self.register_instruction(DivNode(result, left, right)) - return result - - @visitor.when(cool.BlockNode) - def visit(self,node,scope): - pass + @visitor.when(cool.LessNode) + def visit(self, node:cool.LessNode, scope: Scope): + self.define_binary_node(node,scope,MinusNode) - @visitor.when(cool.LetInNode) - def visit(self,node,scope): - pass + @visitor.when(cool.EqualNode) + def visit(self, node: cool.EqualNode, scope: Scope): + self.define_binary_node(node,scope,MinusNode) - @visitor.when(cool.CaseOfNode) - def visit(self,node,scope): - pass + @visitor.when(cool.IsVoidNode) + def visit(self, node: cool.IsVoidNode, scope: Scope): + self.define_unary_node(node, scope, IsVoidNode) + + @visitor.when(cool.ComplementNode) + def visit(self, node: cool.ComplementNode, scope: Scope): + self.define_unary_node(node, scope, ComplementNode) @visitor.when(cool.FunctionCallNode) def visit(self,node,scope): diff --git a/src/main.py b/src/main.py index bb574966..2b1c67d2 100644 --- a/src/main.py +++ b/src/main.py @@ -38,14 +38,15 @@ checker = Checker(context) checker.visit(ast) +cil = COOL_TO_CIL(checker.context) # cil = COOL_TO_CIL_VISITOR(checker.context) -# cil_ast = cil.visit(ast) - -# f_ast = CIL_FORMATTER().visit(cil_ast) -# string_formatted = str(f_ast) -# output_file.write(string_formatted) -# output_file.close() +cil_ast = cil.visit(ast) +# f_ast = Format().visit(ast) +f_ast = CIL_FORMATTER().visit(cil_ast) +string_formatted = str(f_ast) +output_file.write(string_formatted) +output_file.close() if not operations: From f450ea0969af341ed708900c270b28cce25f5659 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sun, 22 Nov 2020 23:05:53 -0500 Subject: [PATCH 030/191] CIL done (while and case nodes still to test) --- src/engine/__init__.py | 1 + src/engine/codegen/cil.py | 77 +++++--- src/engine/codegen/cil_ast.py | 79 +++++---- src/engine/codegen/cil_format.py | 48 ++--- src/engine/codegen/to_cil.py | 208 ++++++++++++++-------- src/engine/cp/semantic.py | 21 +++ src/main.py | 8 +- src/test.mips | 291 ++++++++++++++++++++++++++++++- 8 files changed, 566 insertions(+), 167 deletions(-) diff --git a/src/engine/__init__.py b/src/engine/__init__.py index cefec6cf..132a599e 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -1,6 +1,7 @@ from .lexer import tokenizer from .parser import * from .cp import evaluate_reverse_parse +from .cp.semantic import Scope from .visitors import Builder from .visitors import Checker from .visitors import Collector diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 2f63cd0b..15fb6e10 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -49,8 +49,8 @@ def register_instruction(self, instruction): def to_function_name(self, method_name, type_name): return f'function_{method_name}_at_{type_name}' - def to_attr_name(self, attr_name, type_name): - return f'attribute_{attr_name}_at_{type_name}' + def to_label_name(self, label_name): + return f'{label_name}' def register_function(self, function_name): function_node = FunctionNode(function_name, [], [], []) @@ -72,8 +72,8 @@ def register_data(self, value): def define_string_type(self): self.current_type = self.context.get_type('String') - type_node = self.register_type(node.id) - type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node = self.register_type('String') + type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] self.current_method = self.current_type.get_method('length') @@ -84,7 +84,6 @@ def define_string_type(self): self.register_instruction(LengthNode(dest,self_param)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None - self.current_type = None self.current_method = self.current_type.get_method('concat') type_name = self.current_type.name @@ -106,54 +105,84 @@ def define_string_type(self): self.register_instruction(SubstringNode(dest,self_param,start,length)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None - - self.current_method = self.current_type.get_method('prefix') - type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_param = self.register_param(VariableInfo('self',None)) - length = self.register_param(VariableInfo('length',None)) - dest = self.define_internal_local() - self.register_instruction(ConcatNode(dest,self_param,length)) - self.register_instruction(ReturnNode(dest)) - self.current_method = self.current_function = None + self.current_type = None def define_io_type(self): self.current_type = self.context.get_type('IO') type_node = self.register_type('IO') - type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - self.current_method = self.current_type.get_method('print') + self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_local = self.register_param(VariableInfo('self', None)) str_val = self.define_internal_local() - self.current_method = self.current_function = None self.register_instruction(PrintNode(str_val)) + self.register_instruction(ReturnNode(self_local)) + self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('read') + self.current_method = self.current_type.get_method('in_string') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_local = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() - self.current_method = self.current_function = None self.register_instruction(ReadNode(dest)) + self.register_instruction(ReturnNode(self_local)) + self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('str') + self.current_method = self.current_type.get_method('out_int') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_local = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() - str_val = self.register_param(VariableInfo('value',None)) - self.register_instruction(ToStrNode(dest,str_val)) + int_val = self.register_param(VariableInfo('int_val',None)) + self.register_instruction(ToStrNode(dest,int_val)) + self.register_instruction(PrintNode(dest)) + self.register_instruction(ReturnNode(self_local)) + self.current_method = self.current_function = None + + self.current_method = self.current_type.get_method('in_int') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_local = self.register_param(VariableInfo('self', None)) + dest = self.define_internal_local() + int_val = self.define_internal_local() + self.register_instruction(ReadNode(dest)) + self.register_instruction(ToIntNode(int_val,dest)) + self.register_instruction(ReturnNode(self_local)) self.current_method = self.current_function = None self.current_type = None def define_object_type(self): self.current_type = self.context.get_type('Object') type_node = self.register_type('Object') - type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self_local = self.register_param(VariableInfo('self', None)) + self.register_instruction(ErrorNode()) + self.current_method = self.current_function = None + + self.current_method = self.current_type.get_method('copy') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + copy_inst = self.define_internal_local() + self.register_instruction(CopyNode(copy_inst, self_local)) + self.current_method = self.current_function = None + + self.current_method = self.current_type.get_method('type_name') + type_name = self.current_type.name + self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + type_name_inst = self.define_internal_local() + obj_type = self.define_internal_local() + self.register_instruction(TypeOfNode(self_local, obj_type)) + self.register_instruction(TypeNameNode(type_name_inst, obj_type)) self.current_method = self.current_function = None + self.current_type = None \ No newline at end of file diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 2d1ef94c..d82a78bc 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -60,6 +60,9 @@ class ComplementNode(UnaryNode): class IsVoidNode(UnaryNode): pass +class NotNode(UnaryNode): + pass + class PlusNode(ArithmeticNode): pass @@ -81,29 +84,6 @@ class LessNode(ArithmeticNode): class LessEqNode(ArithmeticNode): pass -class GetAttribNode(InstructionNode): - def __init__(self, dest, obj, attrib): - self.dest = dest - self.obj = obj - self.attrib = attrib - -class SetAttribNode(InstructionNode): - def __init__(self, obj, attrib, value): - self.obj = obj - self.attrib = attrib - self.value = value - -class GetIndexNode(InstructionNode): - def __init__(self, dest, array, index): - self.dest = dest - self.array = array - self.index = index - -class SetIndexNode(InstructionNode): - def __init__(self, array, index, value): - self.array = array - self.index = index - self.value = value class AllocateNode(InstructionNode): def __init__(self, dest, itype): @@ -143,6 +123,20 @@ class ArgNode(InstructionNode): def __init__(self, name): self.name = name +class ErrorNode(InstructionNode): + def __init__(self, error=0): + self.error = error + +class CopyNode(InstructionNode): + def __init__(self, dest, obj): + self.dest = dest + self.obj = obj + +class TypeNameNode(InstructionNode): + def __init__(self, dest, typex): + self.dest = dest + self.type = typex + class ReturnNode(InstructionNode): def __init__(self, value=None): self.value = value @@ -163,11 +157,6 @@ def __init__(self, dest, msg1, msg2): self.msg1 = msg1 self.msg2 = msg2 -class PrefixNode(InstructionNode): - def __init__(self, dest, msg1, msg2): - self.dest = dest - self.msg1 = msg1 - self.msg2 = msg2 class SubstringNode(InstructionNode): def __init__(self, dest, msg1, start, length): @@ -196,19 +185,35 @@ def __init__(self, str_addr): ################# nodes que me tengo que definir ############## -# class ErrorNode(InstructionNode): -# def __init__(self, error=1): -# self.error = error +# class GetAttribNode(InstructionNode): +# def __init__(self, dest, obj, attrib): +# self.dest = dest +# self.obj = obj +# self.attrib = attrib + +# class SetAttribNode(InstructionNode): +# def __init__(self, obj, attrib, value): +# self.obj = obj +# self.attrib = attrib +# self.value = value -# class CopyNode(InstructionNode): -# def __init__(self, dest, obj): +# class GetIndexNode(InstructionNode): +# def __init__(self, dest, array, index): # self.dest = dest -# self.obj = obj +# self.array = array +# self.index = index -# class TypeNameNode(InstructionNode): -# def __init__(self, dest, typex): +# class SetIndexNode(InstructionNode): +# def __init__(self, array, index, value): +# self.array = array +# self.index = index +# self.value = value + +# class PrefixNode(InstructionNode): +# def __init__(self, dest, msg1, msg2): # self.dest = dest -# self.type = typex +# self.msg1 = msg1 +# self.msg2 = msg2 # class ConformNode(InstructionNode): diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 7892dae2..eec71361 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -107,9 +107,9 @@ def visit(self, node: LengthNode): def visit(self, node: ConcatNode): return f'{node.dest} = CONCAT {node.msg1} {node.msg2}' - @visitor.when(PrefixNode) - def visit(self, node: PrefixNode): - return f'{node.dest} = PREFIX {node.msg1} {node.msg2}' + # @visitor.when(PrefixNode) + # def visit(self, node: PrefixNode): + # return f'{node.dest} = PREFIX {node.msg1} {node.msg2}' @visitor.when(SubstringNode) def visit(self, node: SubstringNode): @@ -123,13 +123,13 @@ def visit(self, node: ToStrNode): def visit(self, node: ToIntNode): return f'{node.dest} = INT {node.msg}' - @visitor.when(GetAttribNode) - def visit(self, node: GetAttribNode): - return f'{node.dest} = GETATTR {node.obj} {node.attrib}' + # @visitor.when(GetAttribNode) + # def visit(self, node: GetAttribNode): + # return f'{node.dest} = GETATTR {node.obj} {node.attrib}' - @visitor.when(SetAttribNode) - def visit(self, node: SetAttribNode): - return f'SETATTR {node.obj} {node.attrib} {node.value}' + # @visitor.when(SetAttribNode) + # def visit(self, node: SetAttribNode): + # return f'SETATTR {node.obj} {node.attrib} {node.value}' @visitor.when(LabelNode) def visit(self, node: LabelNode): @@ -161,32 +161,32 @@ def visit(self, node: LessEqNode): ###################### nodes to throw ####################### - # @visitor.when(EqualNode) - # def visit(self, node: EqualNode): - # return f'{node.dest} = {node.left} == {node.right}' + @visitor.when(EqualNode) + def visit(self, node: EqualNode): + return f'{node.dest} = {node.left} == {node.right}' - # @visitor.when(ErrorNode) - # def visit(self, node: ErrorNode): - # return f'ERROR {node.error}' + @visitor.when(ErrorNode) + def visit(self, node: ErrorNode): + return f'ERROR {node.error}' # @visitor.when(ConformNode) # def visit(self, node: ConformNode): # return f'{node.dest} = COMFORM {node.obj} {node.type}' - # @visitor.when(CleanArgsNode) - # def visit(self, node:CleanArgsNode): - # return f'CLEANARG {node.nargs}' + @visitor.when(NotNode) + def visit(self, node:NotNode): + return f'{node.dest} = NOT {node.body}' # @visitor.when(StringEqualNode) # def visit(self, node: StringEqualNode): # return f'{node.dest} = STREQ {node.msg1} {node.msg2}' - # @visitor.when(CopyNode) - # def visit(self, node: CopyNode): - # return f'{node.dest} = COPY {node.obj}' + @visitor.when(CopyNode) + def visit(self, node: CopyNode): + return f'{node.dest} = COPY {node.obj}' - # @visitor.when(TypeNameNode) - # def visit(self, node: TypeNameNode): - # return f'{node.dest} = TYPENAME {node.type}' + @visitor.when(TypeNameNode) + def visit(self, node: TypeNameNode): + return f'{node.dest} = TYPENAME {node.type}' diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 0b397dae..e5e01a25 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -7,14 +7,14 @@ class COOL_TO_CIL(BASE_COOL_CIL_TRANSFORM): - def define_binary_node(self, node: cool.BinaryNode, scope: Scope, cil_node: Node): + def define_binary_node(self, node: cool.BinaryNode, scope, cil_node: Node): result = self.define_internal_local() - left, typex = self.visit(node.left, scope) - right, typex = self.visit( node.right, scope) - self.register_instruction(cil_node(result, left, right)) - return result, typex + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + self.register_instruction(cil_node(result, left, right)) + return result - def define_unary_node(self, node: cool.UnaryNode, scope: Scope, cil_node: Node): + def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): result = self.define_internal_local() expr ,typex = self.visit(node.expression, scope) self.register_instruction(cil_node(result, expr)) @@ -25,7 +25,7 @@ def visit(self,node,scope): pass @visitor.when(cool.ProgramNode) - def visit(self,node: cool.ProgramNode,scope: Scope): + def visit(self,node: cool.ProgramNode, scope): self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() @@ -42,10 +42,10 @@ def visit(self,node: cool.ProgramNode,scope: Scope): return ProgramNode(self.dottypes,self.dotdata,self.dotcode) @visitor.when(cool.ClassDeclarationNode) - def visit(self,node: cool.ClassDeclarationNode,scope: Scope): - self.current_type = self.context.get_type(node.id) - type_node = self.register_type(node.id) - type_node.attributes = [(attr.name, self.to_attr_name(attr.name,atype)) for attr, atype in self.current_type.all_attributes()] + def visit(self,node: cool.ClassDeclarationNode,scope): + self.current_type = self.context.get_type(node.id.lex) + type_node = self.register_type(node.id.lex) + type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] fun_declarations = (f for f in node.features if isinstance(f,cool.FuncDeclarationNode)) @@ -55,22 +55,22 @@ def visit(self,node: cool.ClassDeclarationNode,scope: Scope): self.current_type = None @visitor.when(cool.FuncDeclarationNode) - def visit(self,node: cool.FuncDeclarationNode,scope: Scope): - self.current_method = self.current_type.get_method(node.id) + def visit(self,node: cool.FuncDeclarationNode,scope): + self.current_method = self.current_type.get_method(node.id.lex) type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(node.id, type_name)) + self.current_function = self.register_function(self.to_function_name(node.id.lex, type_name)) for param_name, param_type in node.params: self.register_param(VariableInfo(param_name, param_type)) - - body, _ = self.visit(node.body,scope) + + body = self.visit(node.body,scope) self.register_instruction(ReturnNode(body)) self.current_method = None @visitor.when(cool.AttrDeclarationNode) - def visit(self,node: cool.AttrDeclarationNode,scope:Scope): - attr_info = scope.find_variable(node.id) + def visit(self,node: cool.AttrDeclarationNode,scope): + attr_info = scope.find_variable(node.id.lex) vtype = get_type(attr_info.type) local_attr = self.register_local(VariableInfo(attr_info.name,vtype)) @@ -79,34 +79,33 @@ def visit(self,node: cool.AttrDeclarationNode,scope:Scope): return local_attr,vtype @visitor.when(cool.AssignNode) - def visit(self,node: cool.AssignNode,scope: Scope): - vinfo = scope.find_variable(node.id) - vname = self.register_local(VariableInfo(node.id,get_type(vinfo.type))) + def visit(self,node: cool.AssignNode,scope): + vinfo = scope.find_variable(node.id.lex) + vname = self.register_local(VariableInfo(node.id.lex,get_type(vinfo.type))) expr = self.visit(node.expression,scope) return self.register_instruction(AssignNode(vname,expr)) @visitor.when(cool.IfThenElseNode) - def visit(self,node:cool.IfThenElseNode,scope: Scope): + def visit(self,node:cool.IfThenElseNode,scope): cond, _ = self.visit(node.condition, scope) true_label = LabelNode('TRUE') end_label = LabelNode('END') - result = self.define_internal_local() - self.register_instruction(IfGotoNode(cond,true_label)) - - false_expr , ftype = self.visit(node.else_body, scope) + self.register_instruction(IfGotoNode(cond,self.to_label_name(true_label.label))) + + false_expr = self.visit(node.else_body, scope) self.register_instruction(AssignNode(result,false_expr)) - self.register_instruction(GotoNode(end_label)) + self.register_instruction(GotoNode(self.to_label_name(end_label.label))) self.register_instruction(true_label) - true_expr , ttype = self.visit(node.if_body, scope) + true_expr = self.visit(node.if_body, scope) self.register_instruction(AssignNode(result,true_expr)) self.register_instruction(end_label) - return result, get_common_basetype([ftype,ttype]) + return result @visitor.when(cool.WhileLoopNode) - def visit(self,node:cool.WhileLoopNode,scope: Scope): + def visit(self,node:cool.WhileLoopNode,scope): start_label = LabelNode('START') continue_label = LabelNode('CONTINUE') end_label = LabelNode('END') @@ -125,27 +124,8 @@ def visit(self,node:cool.WhileLoopNode,scope: Scope): self.register_instruction(AssignNode(result,body)) return result, btype - @visitor.when(cool.BlockNode) - def visit(self,node: cool.BlockNode,scope: Scope): - result = self.define_internal_local() - for expr in node.expressions: - val, typex = self.visit(expr, scope) - self.register_instruction(AssignNode(result,val)) - return result, typex - - @visitor.when(cool.LetInNode) - def visit(self,node: cool.LetInNode,scope: Scope): - let_scope = scope.create_child() - for let in node.let_body: - self.visit(let,let_scope) - - result = self.define_internal_local() - expr, typex = self.visit(node.in_body,let_scope) - self.register_instruction(AssignNode(result,expr)) - return result,typex - @visitor.when(cool.CaseOfNode) - def visit(self,node: cool.CaseOfNode,scope: Scope): + def visit(self,node: cool.CaseOfNode,scope): expr, typex = self.visit(node.expression, scope) result = self.define_internal_local() exptype = self.define_internal_local() @@ -161,53 +141,127 @@ def visit(self,node: cool.CaseOfNode,scope: Scope): return result, typex + @visitor.when(cool.LetInNode) + def visit(self,node: cool.LetInNode,scope: Scope): + let_scope = scope.children[0] + for let_id, let_type, let_expr in node.let_body: + let_scope.define_variable(let_id.lex, let_type.lex) + self.visit(let_expr,let_scope) + + result = self.define_internal_local() + expr = self.visit(node.in_body,let_scope) + self.register_instruction(AssignNode(result,expr)) + return result + + @visitor.when(cool.BlockNode) + def visit(self,node: cool.BlockNode,scope): + result = self.define_internal_local() + for expr in node.expressions: + val = self.visit(expr, scope) + self.register_instruction(AssignNode(result,val)) + return result + + @visitor.when(cool.FunctionCallNode) + def visit(self,node: cool.FunctionCallNode, scope): + if not (node.type): + typex = self.context.get_type(node.obj.static_type.name).name + else: + typex = node.type.lex + name = self.to_function_name(node.id.lex, typex) + result = self.define_internal_local() + rev_args = [] + for arg in node.args: + arg_value = self.visit(arg, scope) + rev_args = [ arg_value ] + rev_args + for arg_value in rev_args: + self.register_instruction(ArgNode(arg_value)) + obj = self.visit(node.obj, scope) + self.register_instruction(ArgNode(obj)) + self.register_instruction(StaticCallNode(name, result)) if name else \ + self.register_instruction(DynamicCallNode(typex, node.id.lex, result)) + + return result + + @visitor.when(cool.MemberCallNode) + def visit(self,node: cool.MemberCallNode, scope: Scope): + type_name = self.current_type.name + result = self.define_internal_local() + rev_args = [] + for arg in node.args: + arg_value = self.visit(arg, scope) + rev_args = [ arg_value ] + rev_args + for arg_value in rev_args: + self.register_instruction(ArgNode(arg_value)) + self_inst = scope.find_variable('self').name + self.register_instruction(ArgNode(self_inst)) + self.register_instruction(DynamicCallNode(type_name, node.id.lex, result)) + + return result + + @visitor.when(cool.PlusNode) - def visit(self, node:cool.PlusNode, scope:Scope): - self.define_binary_node(node,scope,PlusNode) + def visit(self, node:cool.PlusNode, scope): + return self.define_binary_node(node,scope,PlusNode) @visitor.when(cool.MinusNode) - def visit(self, node:cool.MinusNode, scope:Scope): - self.define_binary_node(node,scope,MinusNode) + def visit(self, node:cool.MinusNode, scope): + return self.define_binary_node(node,scope,MinusNode) @visitor.when(cool.StarNode) - def visit(self, node:cool.StarNode, scope:Scope): - self.define_binary_node(node,scope,StarNode) + def visit(self, node:cool.StarNode, scope): + return self.define_binary_node(node,scope,StarNode) @visitor.when(cool.DivNode) - def visit(self, node:cool.DivNode, scope:Scope): - self.define_binary_node(node,scope,DivNode) + def visit(self, node:cool.DivNode, scope): + return self.define_binary_node(node,scope,DivNode) @visitor.when(cool.LessNode) - def visit(self, node:cool.LessNode, scope: Scope): - self.define_binary_node(node,scope,MinusNode) + def visit(self, node:cool.LessNode, scope): + return self.define_binary_node(node,scope,LessNode) @visitor.when(cool.EqualNode) - def visit(self, node: cool.EqualNode, scope: Scope): - self.define_binary_node(node,scope,MinusNode) + def visit(self, node: cool.EqualNode, scope): + return self.define_binary_node(node,scope,EqualNode) @visitor.when(cool.IsVoidNode) - def visit(self, node: cool.IsVoidNode, scope: Scope): - self.define_unary_node(node, scope, IsVoidNode) + def visit(self, node: cool.IsVoidNode, scope): + return self.define_unary_node(node, scope, IsVoidNode) + @visitor.when(cool.NotNode) + def visit(self, node: cool.NotNode, scope): + return self.define_unary_node(node,scope, NotNode) + @visitor.when(cool.ComplementNode) - def visit(self, node: cool.ComplementNode, scope: Scope): - self.define_unary_node(node, scope, ComplementNode) + def visit(self, node: cool.ComplementNode, scope): + return self.define_unary_node(node, scope, ComplementNode) - @visitor.when(cool.FunctionCallNode) - def visit(self,node,scope): - pass + @visitor.when(cool.IdNode) + def visit(self, node: cool.IdNode, scope: Scope): + typex = scope.find_variable(node.token.lex).type + return node.token.lex, typex - @visitor.when(cool.MemberCallNode) - def visit(self,node,scope): - pass + @visitor.when(cool.BoolNode) + def visit(self, node:cool.BoolNode, scope): + typex = self.context.get_type('Bool').name + return (1, typex) if node.token.lex else (0, typex) + + @visitor.when(cool.IntegerNode) + def visit(self, node:cool.IntegerNode, scope): + return int(node.token.lex), self.context.get_type('Int').name + + @visitor.when(cool.StringNode) + def visit(self, node:cool.StringNode, scope): + string = self.register_data(node.token.lex) + return string.value, string.name @visitor.when(cool.NewNode) - def visit(self,node,scope): - pass + def visit(self,node: cool.NewNode,scope): + new_local = self.define_internal_local() + typex = self.context.get_type(node.type.lex) + self.register_instruction(AllocateNode(new_local, typex)) + return new_local, typex + - @visitor.when(cool.AtomicNode) - def visit(self,node,scope): - pass \ No newline at end of file diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index fd5cbd24..efdbb383 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -108,6 +108,27 @@ def define_method(self, name:str, param_names:list, param_types:list, return_typ method = self.methods[name] = Method(name, param_names, param_types, return_type) return method + def all_attributes(self): + if self.parent: + for attr in self.parent.all_attributes(): + yield attr + for attr in self.attributes: + yield attr + + def all_methods(self): + done = set() + if self.parent: + for method, typex in self.parent.all_methods(): + if method.name in self.methods: + done.add(method.name) + yield (self.methods[method.name], self) + else: + yield (method, typex) + for method in self.methods.values(): + if method.name in done: continue + yield (method, self) + + def conforms_to(self, other): return other.bypass() or self == other or self.parent is not None and self.parent.conforms_to(other) diff --git a/src/main.py b/src/main.py index 2b1c67d2..0cafdf8d 100644 --- a/src/main.py +++ b/src/main.py @@ -30,18 +30,18 @@ collect = Collector() collect.visit(ast) - context = collect.context builder = Builder(context) builder.visit(ast) context = builder.context checker = Checker(context) -checker.visit(ast) +scope = checker.visit(ast) + cil = COOL_TO_CIL(checker.context) # cil = COOL_TO_CIL_VISITOR(checker.context) - -cil_ast = cil.visit(ast) +# sc = Scope() +cil_ast = cil.visit(ast,scope) # f_ast = Format().visit(ast) f_ast = CIL_FORMATTER().visit(cil_ast) string_formatted = str(f_ast) diff --git a/src/test.mips b/src/test.mips index 0637a088..1c3b40e4 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1 +1,290 @@ -[] \ No newline at end of file +.TYPES +type Object { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type String { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method length: function_length_at_String + method concat: function_concat_at_String + method substr: function_substr_at_String +} +type IO { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO +} +type Main { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method main: function_main_at_Main +} +type A { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method m: function_m_at_A + method f: function_f_at_A +} +type B { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method m: function_m_at_B + method f: function_f_at_A +} +type C { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method f: function_f_at_C +} +type D { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method f: function_f_at_C +} +type E { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method f: function_f_at_E +} + +.DATA +data_0 = "A" +data_1 = "B" +data_2 = "C" +data_3 = "E" + +.CODE +function function_abort_at_Object { + PARAM self + + + + ERROR 0 +} +function function_copy_at_Object { + PARAM self + + LOCAL local_copy_at_Object_internal_0 + + local_copy_at_Object_internal_0 = COPY self +} +function function_type_name_at_Object { + PARAM self + + LOCAL local_type_name_at_Object_internal_0 + LOCAL local_type_name_at_Object_internal_1 + + local_type_name_at_Object_internal_1 = TYPEOF self + local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 +} +function function_length_at_String { + PARAM self + + LOCAL local_length_at_String_internal_0 + + local_length_at_String_internal_0 = LENGTH self + RETURN local_length_at_String_internal_0 +} +function function_concat_at_String { + PARAM self + PARAM string + + LOCAL local_concat_at_String_internal_0 + + local_concat_at_String_internal_0 = CONCAT self string + RETURN local_concat_at_String_internal_0 +} +function function_substr_at_String { + PARAM self + PARAM start + PARAM length + + LOCAL local_substr_at_String_internal_0 + + local_substr_at_String_internal_0 = SUBSTRING self start length + RETURN local_substr_at_String_internal_0 +} +function function_out_string_at_IO { + PARAM self + + LOCAL local_out_string_at_IO_internal_0 + + PRINT local_out_string_at_IO_internal_0 + RETURN self +} +function function_in_string_at_IO { + PARAM self + + LOCAL local_in_string_at_IO_internal_0 + + local_in_string_at_IO_internal_0 = READ + RETURN self +} +function function_out_int_at_IO { + PARAM self + PARAM int_val + + LOCAL local_out_int_at_IO_internal_0 + + local_out_int_at_IO_internal_0 = STR int_val + PRINT local_out_int_at_IO_internal_0 + RETURN self +} +function function_in_int_at_IO { + PARAM self + + LOCAL local_in_int_at_IO_internal_0 + LOCAL local_in_int_at_IO_internal_1 + + local_in_int_at_IO_internal_0 = READ + local_in_int_at_IO_internal_1 = INT local_in_int_at_IO_internal_0 + RETURN self +} +function entry { + + + LOCAL local__internal_0 + LOCAL local__internal_1 + + Main = ALLOCATE local__internal_0 + ARG local__internal_0 + local__internal_1 = CALL function_main_at_Main + RETURN 0 +} +function function_main_at_Main { + + + LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_internal_1 + LOCAL local_main_at_Main_internal_2 + LOCAL local_main_at_Main_internal_3 + LOCAL local_main_at_Main_internal_4 + LOCAL local_main_at_Main_internal_5 + LOCAL local_main_at_Main_internal_6 + LOCAL local_main_at_Main_internal_7 + LOCAL local_main_at_Main_internal_8 + LOCAL local_main_at_Main_internal_9 + LOCAL local_main_at_Main_internal_10 + LOCAL local_main_at_Main_internal_11 + LOCAL local_main_at_Main_internal_12 + LOCAL local_main_at_Main_internal_13 + LOCAL local_main_at_Main_internal_14 + LOCAL local_main_at_Main_internal_15 + + local_main_at_Main_internal_1 = ALLOCATE type E : D { + [method] f(): String; +} + + ARG ('x', 'E') + local_main_at_Main_internal_4 = CALL function_f_at_E + ARG ('x', 'E') + local_main_at_Main_internal_5 = CALL function_f_at_E + local_main_at_Main_internal_3 = local_main_at_Main_internal_4 == local_main_at_Main_internal_5 + local_main_at_Main_internal_2 = local_main_at_Main_internal_3 + local_main_at_Main_internal_6 = ALLOCATE type B : A { + [method] m(): String; +} + + ARG ('x', 'E') + local_main_at_Main_internal_10 = CALL function_f_at_A + ARG local_main_at_Main_internal_10 + local_main_at_Main_internal_9 = CALL function_m_at_A + ARG local_main_at_Main_internal_9 + ARG self + local_main_at_Main_internal_8 = VCALL Main out_string + local_main_at_Main_internal_7 = local_main_at_Main_internal_8 + local_main_at_Main_internal_11 = ALLOCATE type A : Object { + [method] m(): String; + [method] f(): A; +} + + ARG ('x', 'E') + local_main_at_Main_internal_15 = CALL function_f_at_A + ARG local_main_at_Main_internal_15 + local_main_at_Main_internal_14 = CALL function_m_at_A + ARG local_main_at_Main_internal_14 + ARG self + local_main_at_Main_internal_13 = VCALL Main out_string + local_main_at_Main_internal_12 = local_main_at_Main_internal_13 + local_main_at_Main_internal_0 = local_main_at_Main_internal_12 + RETURN local_main_at_Main_internal_0 +} +function function_m_at_A { + + + + + RETURN ('A', 'data_0') +} +function function_f_at_A { + + + LOCAL local_f_at_A_internal_0 + + local_f_at_A_internal_0 = ALLOCATE type A : Object { + [method] m(): String; + [method] f(): A; +} + + RETURN ('local_f_at_A_internal_0', type A : Object { + [method] m(): String; + [method] f(): A; +} +) +} +function function_m_at_B { + + + + + RETURN ('B', 'data_1') +} +function function_f_at_C { + + + + + RETURN ('C', 'data_2') +} +function function_f_at_E { + + + + + RETURN ('E', 'data_3') +} \ No newline at end of file From e48dc6ca75b9a103c6bcdc2bcf93b2cf3d6f83bb Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Wed, 25 Nov 2020 10:05:20 -0500 Subject: [PATCH 031/191] Remove Auto Type --- src/engine/visitors/collector.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 3f5473b7..52270354 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -9,7 +9,6 @@ def __init__(self, errors = []): #Tipos especiales self.context.add_type(SelfType()) - self.context.add_type(AutoType()) #Tipos Buit-In self.context.create_type('Object',builtin = True) From 4d330f59e2acbb792f3e0b5159a7410ee45d5c01 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Wed, 25 Nov 2020 10:05:35 -0500 Subject: [PATCH 032/191] Fix Error_On_LN_Col format --- src/engine/semantic_errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/semantic_errors.py b/src/engine/semantic_errors.py index a57f776d..f1ca2e0d 100644 --- a/src/engine/semantic_errors.py +++ b/src/engine/semantic_errors.py @@ -1,4 +1,4 @@ -ERROR_ON_LN_COL = 'Line %d, Column %d: ' +ERROR_ON_LN_COL = '(%d, %d) - ' WRONG_SIGNATURE = 'Method "%s" of "%s" already defined in "%s" with a different signature.' SELF_IS_READONLY = 'Variable "self" is read-only.' LOCAL_ALREADY_DEFINED = 'Variable "%s" is already defined in method "%s".' From 781f55f425aa839dbd89530bb807d62adfab48a3 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Wed, 25 Nov 2020 10:11:16 -0500 Subject: [PATCH 033/191] Remove more Auto Type code --- src/engine/cp/semantic.py | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index efdbb383..9bc05901 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -165,23 +165,6 @@ def bypass(self): def __eq__(self, other): return isinstance(other, SelfType) -class AutoType(Type): - def __init__(self): - Type.__init__(self, 'AUTO_TYPE') - self.sealed = True - - def union_type(self, other): - return self - - def conforms_to(self, other): - return True - - def bypass(self): - return True - - def __eq__(self, other): - return isinstance(other, Type) - class ErrorType(Type): def __init__(self, message = ""): Type.__init__(self, '') @@ -232,13 +215,11 @@ class VariableInfo: def __init__(self, name, vtype): self.name = name self.type = vtype - self.infered = not isinstance(vtype, AutoType) self.calls = [] self.assigns = [] def set_calls(self, typex): - if not self.infered and not isinstance(typex, AutoType): - self.calls.append(typex) + self.calls.append(typex) def set_assigns(self, typex): if not self.infered: @@ -269,10 +250,6 @@ def infer_type(self): else: self.type = call - if not self.type or isinstance(self.type, ErrorType): - self.type = AutoType() - - self.infered = not isinstance(self.type, AutoType) self.calls = [] self.assigns = [] From ffae644c0f48d7f6e6e92c1c80adb0d19d537b35 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Wed, 25 Nov 2020 10:42:49 -0500 Subject: [PATCH 034/191] Add redefinition of basic class error --- src/engine/cp/semantic.py | 5 +++++ src/engine/visitors/checker.py | 2 +- src/engine/visitors/collector.py | 2 +- src/engine/visitors/inferer.py | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index 9bc05901..860e704a 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -186,14 +186,19 @@ def __eq__(self, other): class Context: def __init__(self): self.types = {} + self.basic_types = ['Object', 'IO', 'Int', 'String', 'Bool'] def create_type(self, name:str, builtin = False): + if name in self.basic_types and name in self.types: + raise SemanticError(f'SemanticError: Redefinition of basic class {name}.') if name in self.types: raise SemanticError(f'Type with the same name ({name}) already in context.') typex = self.types[name] = Type(name,built_in=builtin) return typex def add_type(self, typex): + if typex.name in self.basic_types: + raise SemanticError(f'SemanticError: Redefinition of basic class {typex.name}.') if typex.name in self.types: raise SemanticError(f'Type with the same name ({typex.name}) already in context.') self.types[typex.name] = typex diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 2f319657..b84e0e75 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -1,4 +1,4 @@ -from engine.cp import visitor, ErrorType, SelfType, AutoType, SemanticError, Scope +from engine.cp import visitor, ErrorType, SelfType, SemanticError, Scope from engine.parser import ProgramNode, ClassDeclarationNode, AttrDeclarationNode, FuncDeclarationNode from engine.parser import IfThenElseNode, WhileLoopNode, BlockNode, LetInNode, CaseOfNode from engine.parser import AssignNode, UnaryNode, BinaryNode, LessEqualNode, LessNode, EqualNode, ArithmeticNode diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 52270354..96d7337b 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -1,4 +1,4 @@ -from engine.cp import SemanticError, visitor, Context, SelfType, AutoType +from engine.cp import SemanticError, visitor, Context, SelfType from engine.parser import ProgramNode, ClassDeclarationNode from engine.semantic_errors import ERROR_ON_LN_COL diff --git a/src/engine/visitors/inferer.py b/src/engine/visitors/inferer.py index 0a64a232..ed509dad 100644 --- a/src/engine/visitors/inferer.py +++ b/src/engine/visitors/inferer.py @@ -1,4 +1,4 @@ -from engine.cp import visitor, ErrorType, SelfType, AutoType, SemanticError +from engine.cp import visitor, ErrorType, SelfType, SemanticError from engine.parser import ProgramNode, ClassDeclarationNode, AttrDeclarationNode, FuncDeclarationNode from engine.parser import IfThenElseNode, WhileLoopNode, BlockNode, LetInNode, CaseOfNode from engine.parser import AssignNode, UnaryNode, BinaryNode, LessEqualNode, LessNode, EqualNode, ArithmeticNode From 2c9417c9edd587e1f8a5872fc51e634933dd5a20 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Wed, 25 Nov 2020 22:06:25 -0500 Subject: [PATCH 035/191] temporal changes --- src/main.py | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/main.py b/src/main.py index 0cafdf8d..a1dc5738 100644 --- a/src/main.py +++ b/src/main.py @@ -28,24 +28,32 @@ ast = evaluate_reverse_parse(parse,operations,tokens) -collect = Collector() +collect_errors = [] +collect = Collector(collect_errors) collect.visit(ast) context = collect.context -builder = Builder(context) -builder.visit(ast) -context = builder.context -checker = Checker(context) -scope = checker.visit(ast) - - -cil = COOL_TO_CIL(checker.context) -# cil = COOL_TO_CIL_VISITOR(checker.context) -# sc = Scope() -cil_ast = cil.visit(ast,scope) -# f_ast = Format().visit(ast) -f_ast = CIL_FORMATTER().visit(cil_ast) -string_formatted = str(f_ast) -output_file.write(string_formatted) +builder_errors = [] +#builder = Builder(context, builder_errors) +#builder.visit(ast) +#context = builder.context +#checker_errors = [] +#checker = Checker(context, checker_errors) +#scope = checker.visit(ast) + + +# cil = COOL_TO_CIL(checker.context) +# # cil = COOL_TO_CIL_VISITOR(checker.context) +# # sc = Scope() +# cil_ast = cil.visit(ast,scope) +# # f_ast = Format().visit(ast) +# f_ast = CIL_FORMATTER().visit(cil_ast) +# string_formatted = str(f_ast) +#output_file.write(string_formatted) +output_file.write(str(collect_errors)) +#print(str(collect_errors)) +#output_file.write(str(builder_errors)) +#output_file.write(str(checker_errors)) +#output_file.write(collect_errors) output_file.close() @@ -54,4 +62,12 @@ print(SyntacticError(parse.line,parse.column, message)) exit(1) #print(parse) -exit(0) + + +if len(collect_errors): + for e in collect_errors: + print(e) + print('/n') + exit(1) + +exit(0) \ No newline at end of file From 56d7ed0cb7dd8f4d3d74bdc6295644df11111c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 08:23:24 -0500 Subject: [PATCH 036/191] Improve semantic errors --- src/engine/semantic_errors.py | 3 ++- src/engine/visitors/checker.py | 4 ++-- src/main.py | 39 ++++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/engine/semantic_errors.py b/src/engine/semantic_errors.py index f1ca2e0d..e3e2e157 100644 --- a/src/engine/semantic_errors.py +++ b/src/engine/semantic_errors.py @@ -10,4 +10,5 @@ INF_ATTR = 'On class "%s", attribute "%s": type "%s"' INF_PARAM = 'On method "%s" of class "%s", param "%s": type "%s"' INF_RETRN = 'Return of method "%s" in class "%s", type "%s"' -INF_VAR = 'Varible "%s", type "%s"' \ No newline at end of file +INF_VAR = 'Varible "%s", type "%s"' +NON_TYPE_ARGUMENTS = 'Non-%s arguments: %s %s %s' \ No newline at end of file diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index b84e0e75..4d7fd8b1 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -4,7 +4,7 @@ from engine.parser import AssignNode, UnaryNode, BinaryNode, LessEqualNode, LessNode, EqualNode, ArithmeticNode from engine.parser import NotNode, IsVoidNode, ComplementNode, FunctionCallNode, MemberCallNode, NewNode, AtomicNode from engine.parser import IntegerNode, IdNode, StringNode, BoolNode -from engine.semantic_errors import ERROR_ON_LN_COL, WRONG_SIGNATURE, SELF_IS_READONLY, LOCAL_ALREADY_DEFINED, INCOMPATIBLE_TYPES, VARIABLE_NOT_DEFINED, INVALID_OPERATION, CYCLIC_HERITAGE +from engine.semantic_errors import NON_TYPE_ARGUMENTS, ERROR_ON_LN_COL, WRONG_SIGNATURE, SELF_IS_READONLY, LOCAL_ALREADY_DEFINED, INCOMPATIBLE_TYPES, VARIABLE_NOT_DEFINED, INVALID_OPERATION, CYCLIC_HERITAGE class Checker: def __init__(self, context, errors=[]): @@ -293,7 +293,7 @@ def visit(self, node, scope): right_type = node.right.static_type if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) node.static_type = self.int_type diff --git a/src/main.py b/src/main.py index a1dc5738..4f8970f2 100644 --- a/src/main.py +++ b/src/main.py @@ -31,14 +31,35 @@ collect_errors = [] collect = Collector(collect_errors) collect.visit(ast) + +if len(collect_errors): + #print("coolector") + for e in collect_errors: + print(e) + exit(1) + context = collect.context builder_errors = [] -#builder = Builder(context, builder_errors) -#builder.visit(ast) -#context = builder.context -#checker_errors = [] -#checker = Checker(context, checker_errors) -#scope = checker.visit(ast) +builder = Builder(context, builder_errors) +builder.visit(ast) + +if len(builder_errors): + #print("builder") + for e in builder_errors: + print(e) + exit(1) + +context = builder.context +checker_errors = [] +checker = Checker(context, checker_errors) +scope = checker.visit(ast) + +if len(checker_errors): + #print("checker") + for e in checker_errors: + print(e) + exit(1) + # cil = COOL_TO_CIL(checker.context) @@ -64,10 +85,6 @@ #print(parse) -if len(collect_errors): - for e in collect_errors: - print(e) - print('/n') - exit(1) + exit(0) \ No newline at end of file From ee2dc831eddc044c5f2d76cae92a604cdf32f583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 08:47:23 -0500 Subject: [PATCH 037/191] Fix Main class and main method error --- src/engine/visitors/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/visitors/builder.py b/src/engine/visitors/builder.py index 9217175e..8eb1a56d 100644 --- a/src/engine/visitors/builder.py +++ b/src/engine/visitors/builder.py @@ -51,7 +51,7 @@ def visit(self, node): try: self.context.get_type('Main').get_method('main') except SemanticError: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "Class Main and feature main needed") + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: Class Main and feature main needed") @visitor.when(ClassDeclarationNode) def visit(self, node): From 13b9df5b2dc2a61bb870c3ec17b072d2c09e77d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 08:56:33 -0500 Subject: [PATCH 038/191] Type builder visitor error fixing --- src/engine/visitors/builder.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/visitors/builder.py b/src/engine/visitors/builder.py index 8eb1a56d..3e7f56f5 100644 --- a/src/engine/visitors/builder.py +++ b/src/engine/visitors/builder.py @@ -76,13 +76,13 @@ def visit(self, node): try: attr_type = self.context.get_type(node.type.lex) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + se.text) attr_type = ErrorType() try: self.current_type.define_attribute(node.id.lex, attr_type) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) @visitor.when(FuncDeclarationNode) def visit(self, node): @@ -91,11 +91,11 @@ def visit(self, node): try: arg_type = self.context.get_type(types.lex) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + se.text) arg_type = ErrorType() else: if isinstance(arg_type, SelfType): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Type "{arg_type.name}" can not be used as a parameter type') + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Type "{arg_type.name}" can not be used as a parameter type') arg_type = ErrorType() arg_names.append(ids.lex) @@ -104,10 +104,10 @@ def visit(self, node): try: ret_type = self.context.get_type(node.type.lex) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + se.text) ret_type = ErrorType() try: self.current_type.define_method(node.id.lex, arg_names, arg_types, ret_type) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) \ No newline at end of file + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) \ No newline at end of file From 8e799a81c7cfece24090a6979fb9ef7d4755e9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 09:31:16 -0500 Subject: [PATCH 039/191] Type Checker error fixing --- src/engine/visitors/checker.py | 70 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 4d7fd8b1..b77fdc73 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -40,7 +40,7 @@ def visit(self, node, scope): while parent: if parent == self.current_type: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + CYCLIC_HERITAGE % (parent.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + CYCLIC_HERITAGE % (parent.name)) self.current_type.parent = self.object_type break @@ -65,7 +65,7 @@ def visit(self, node, scope): pass else: if p_method.return_type != self.current_method.return_type or p_method.param_types != self.current_method.param_types: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " +WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) scope.define_variable('self', self.current_type) @@ -79,7 +79,7 @@ def visit(self, node, scope): return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type if not body_type.conforms_to(return_type): - self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) + self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + "TypeError: " + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) @visitor.when(AttrDeclarationNode) def visit(self, node, scope): @@ -92,7 +92,7 @@ def visit(self, node, scope): node_type = attr.type node_type = self.current_type if isinstance(node_type, SelfType) else node_type if not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) @visitor.when(FuncDeclarationNode) def visit(self, node, scope): @@ -130,7 +130,7 @@ def visit(self, node, scope): condition_type = condition.static_type if not condition_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) self.visit(node.if_body, scope.create_child()) self.visit(node.else_body, scope.create_child()) @@ -146,7 +146,7 @@ def visit(self, node, scope): condition_type = condition.static_type if not condition_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) self.visit(node.body, scope.create_child()) @@ -165,7 +165,7 @@ def visit(self, node, scope): try: node_type = self.context.get_type(typex.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "TypeError: " + ex.text) node_type = ErrorType() id_type = self.current_type if isinstance(node_type, SelfType) else node_type @@ -175,7 +175,7 @@ def visit(self, node, scope): self.visit(expr, child) expr_type = expr.static_type if not expr_type.conforms_to(id_type): - self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) scope.define_variable(idx.lex, id_type) @@ -193,11 +193,11 @@ def visit(self, node, scope): try: node_type = self.context.get_type(typex.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "TypeError: " + ex.text) node_type = ErrorType() else: - if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + f'Type "{node_type.name}" can not be used as case type') + if isinstance(node_type, SelfType): + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "SemanticError: " + f'Type "{node_type.name}" can not be used as case type') node_type = ErrorType() id_type = node_type @@ -220,11 +220,11 @@ def visit(self, node, scope): node_type = var.type if var.name == 'self': - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + SELF_IS_READONLY) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + SELF_IS_READONLY) elif not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) node.static_type = expr_type @@ -235,7 +235,7 @@ def visit(self, node, scope): expr_type = expression.static_type if not expr_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.bool_type.name)) node.static_type = self.bool_type @@ -248,7 +248,7 @@ def visit(self, node, scope): right_type = node.right.static_type if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (right_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) node.static_type = self.bool_type @@ -261,7 +261,7 @@ def visit(self, node, scope): right_type = node.right.static_type if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (right_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) node.static_type = self.bool_type @@ -273,14 +273,12 @@ def visit(self, node, scope): self.visit(node.right, scope.create_child()) right_type = node.right.static_type - if isinstance(left_type, AutoType) or isinstance(right_type, AutoType): - pass - elif left_type.conforms_to(self.int_type) ^ right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + if left_type.conforms_to(self.int_type) ^ right_type.conforms_to(self.int_type): + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) elif left_type.conforms_to(self.string_type) ^ right_type.conforms_to(self.string_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) elif left_type.conforms_to(self.bool_type) ^ right_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) node.static_type = self.bool_type @@ -310,7 +308,7 @@ def visit(self, node, scope): expr_type = expression.static_type if not expr_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + INCOMPATIBLE_TYPES % (expr_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.int_type.name)) node.static_type = self.int_type @@ -324,15 +322,15 @@ def visit(self, node, scope): try: node_type = self.context.get_type(node.type.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "TypeError: " + ex.text) node_type = ErrorType() else: - if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): - self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + f'Type "{node_type}" cannot be used as type dispatch') + if isinstance(node_type, SelfType): + self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "SemanticError: " + f'Type "{node_type}" cannot be used as type dispatch') node_type = ErrorType() if not obj_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (node.obj.line, node.obj.column) + INCOMPATIBLE_TYPES % (obj_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.obj.line, node.obj.column) + "TypeError: "+ INCOMPATIBLE_TYPES % (obj_type.name, node_type.name)) obj_type = node_type @@ -340,7 +338,7 @@ def visit(self, node, scope): node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "AttributeError: " + ex.text) node_type = ErrorType() obj_method = None @@ -352,9 +350,9 @@ def visit(self, node, scope): arg_type = arg.static_type if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" can not be dispatched') + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') node.static_type = node_type @@ -367,7 +365,7 @@ def visit(self, node, scope): node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "AttributeError: " + ex.text) node_type = ErrorType() obj_method = None @@ -379,9 +377,9 @@ def visit(self, node, scope): arg_type = arg.static_type if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" canot be dispatched') + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" canot be dispatched') node.static_type = node_type @@ -390,7 +388,7 @@ def visit(self, node, scope): try: node_type = self.context.get_type(node.type.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + ex.text) node_type = ErrorType() node.static_type = node_type @@ -409,7 +407,7 @@ def visit(self, node, scope): var = scope.find_variable(node.token.lex) node_type = var.type else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name)) node_type = ErrorType() node.static_type = node_type From 0bc060c5c68b75cc1919ac28e7345a657e282147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 10:33:04 -0500 Subject: [PATCH 040/191] Type builder error fixing --- src/engine/visitors/builder.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/visitors/builder.py b/src/engine/visitors/builder.py index 3e7f56f5..cc81dbde 100644 --- a/src/engine/visitors/builder.py +++ b/src/engine/visitors/builder.py @@ -63,7 +63,10 @@ def visit(self, node): parent_type = self.context.get_type(parent.lex) self.current_type.set_parent(parent_type) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) + if self.current_type and parent_type.sealed: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + se.text) self.current_type.set_parent(self.object_type) else: self.current_type.set_parent(self.object_type) From 744698bd4ad0172bd9aeb388951f99272cea61c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 10:44:44 -0500 Subject: [PATCH 041/191] Fix type builder double exception --- src/engine/visitors/builder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/visitors/builder.py b/src/engine/visitors/builder.py index cc81dbde..29bf594f 100644 --- a/src/engine/visitors/builder.py +++ b/src/engine/visitors/builder.py @@ -59,11 +59,12 @@ def visit(self, node): parent = node.parent if parent: + parent_type = None try: parent_type = self.context.get_type(parent.lex) self.current_type.set_parent(parent_type) except SemanticError as se: - if self.current_type and parent_type.sealed: + if self.current_type and parent_type != None and parent_type.sealed: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) else: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + se.text) From a64fbf0f0f2cc4accdbdbc2b0a361063e351a5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 10:56:02 -0500 Subject: [PATCH 042/191] Improve type checker funcdeclarationnode errors --- src/engine/visitors/checker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index b77fdc73..d83d404a 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -107,7 +107,7 @@ def visit(self, node, scope): pass else: if parent_method.param_types != self.current_method.param_types or parent_method.return_type != self.current_method.return_type: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) scope.define_variable('self', self.current_type) @@ -121,7 +121,7 @@ def visit(self, node, scope): return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type if not body_type.conforms_to(return_type): - self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) + self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + "TypeError: " + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) @visitor.when(IfThenElseNode) def visit(self, node, scope): From e1effd609446bd902b781d25009545175cee28a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 11:50:34 -0500 Subject: [PATCH 043/191] Add self attribute declaration error --- src/engine/visitors/checker.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index d83d404a..72c6a77e 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -47,6 +47,10 @@ def visit(self, node, scope): parent = parent.parent for a in self.current_type.attributes: + if a.name == 'self': + line, column = [ (attrib.line, attrib.column) for attrib in node.features if type(attrib) is AttrDeclarationNode and attrib.id.lex == 'self'][0] + self.errors.append(ERROR_ON_LN_COL % (line, column) + "SemanticError: " + "Incorrect use of self in attribute declaration") + scope.define_variable(a.name, a.type) for f in node.features: From 9f61b838b38001afbd9f64f8ee913b207bb75c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 12:14:14 -0500 Subject: [PATCH 044/191] add self as function parameter error --- src/engine/visitors/checker.py | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 72c6a77e..50a524f6 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -56,35 +56,6 @@ def visit(self, node, scope): for f in node.features: self.visit(f, scope.create_child()) - @visitor.when(FuncDeclarationNode) - def visit(self, node, scope): - self.current_method = self.current_type.get_method(node.id.lex) - - #Verificar funciones redefinidas - parent = self.current_type.parent - if parent: - try: - p_method = parent.get_method(node.id.lex) - except SemanticError: - pass - else: - if p_method.return_type != self.current_method.return_type or p_method.param_types != self.current_method.param_types: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " +WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) - - scope.define_variable('self', self.current_type) - - for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): - scope.define_variable(pname, ptype) - - body = node.body - self.visit(body, scope.create_child()) - - body_type = body.static_type - return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type - - if not body_type.conforms_to(return_type): - self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + "TypeError: " + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) - @visitor.when(AttrDeclarationNode) def visit(self, node, scope): expr = node.expression @@ -111,11 +82,13 @@ def visit(self, node, scope): pass else: if parent_method.param_types != self.current_method.param_types or parent_method.return_type != self.current_method.return_type: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) scope.define_variable('self', self.current_type) for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): + if pname == 'self': + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") scope.define_variable(pname, ptype) body = node.body From edff5e02fafa914f3f6d1d7aecad34105307c783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 12:25:05 -0500 Subject: [PATCH 045/191] Add self as let expression error --- src/engine/cp/semantic.py | 1 + src/engine/visitors/checker.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index 860e704a..462cfbba 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -222,6 +222,7 @@ def __init__(self, name, vtype): self.type = vtype self.calls = [] self.assigns = [] + self.infered = False def set_calls(self, typex): self.calls.append(typex) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 50a524f6..af78aa81 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -146,6 +146,10 @@ def visit(self, node, scope): node_type = ErrorType() id_type = self.current_type if isinstance(node_type, SelfType) else node_type + + if idx.lex == 'self': + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "SemanticError: " + "'self' cannot be bound in a 'let' expression.") + child = scope.create_child() if expr: From f16a4b05151d9eefbd2955fc9248554980ba0351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 13:08:09 -0500 Subject: [PATCH 046/191] type collector error fixing --- src/engine/visitors/collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 96d7337b..24c9b5c2 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -31,4 +31,4 @@ def visit(self, node): try: self.context.create_type(node.id.lex) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) \ No newline at end of file + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) \ No newline at end of file From 08b80a54773b2760e6f51ae602e53fc57d57f29b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 13:16:10 -0500 Subject: [PATCH 047/191] Fix error selection order --- src/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.py b/src/main.py index 4f8970f2..618d63fe 100644 --- a/src/main.py +++ b/src/main.py @@ -34,7 +34,7 @@ if len(collect_errors): #print("coolector") - for e in collect_errors: + for e in collect_errors[::-1]: print(e) exit(1) @@ -45,7 +45,7 @@ if len(builder_errors): #print("builder") - for e in builder_errors: + for e in builder_errors[::-1]: print(e) exit(1) @@ -56,7 +56,7 @@ if len(checker_errors): #print("checker") - for e in checker_errors: + for e in checker_errors[::-1]: print(e) exit(1) From 0e0b7dce56b7eecdd62b23cf005f3460cfeef927 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 26 Nov 2020 14:36:50 -0500 Subject: [PATCH 048/191] cil work --- src/engine/codegen/cil.py | 15 ++--- src/engine/codegen/cil_ast.py | 34 +++++----- src/engine/codegen/to_cil.py | 119 ++++++++++++++++++++++------------ 3 files changed, 102 insertions(+), 66 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 15fb6e10..2d78a409 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -117,41 +117,37 @@ def define_io_type(self): self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_local = self.register_param(VariableInfo('self', None)) str_val = self.define_internal_local() self.register_instruction(PrintNode(str_val)) - self.register_instruction(ReturnNode(self_local)) + self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_string') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_local = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() self.register_instruction(ReadNode(dest)) - self.register_instruction(ReturnNode(self_local)) + self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('out_int') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_local = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() int_val = self.register_param(VariableInfo('int_val',None)) self.register_instruction(ToStrNode(dest,int_val)) self.register_instruction(PrintNode(dest)) - self.register_instruction(ReturnNode(self_local)) + self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_int') type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_local = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() int_val = self.define_internal_local() self.register_instruction(ReadNode(dest)) self.register_instruction(ToIntNode(int_val,dest)) - self.register_instruction(ReturnNode(self_local)) + self.register_instruction(ReturnNode(int_val)) self.current_method = self.current_function = None self.current_type = None @@ -166,6 +162,7 @@ def define_object_type(self): self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) self_local = self.register_param(VariableInfo('self', None)) self.register_instruction(ErrorNode()) + self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('copy') @@ -174,6 +171,7 @@ def define_object_type(self): self_local = self.register_param(VariableInfo('self', None)) copy_inst = self.define_internal_local() self.register_instruction(CopyNode(copy_inst, self_local)) + self.register_instruction(ReturnNode(copy_inst)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('type_name') @@ -184,5 +182,6 @@ def define_object_type(self): obj_type = self.define_internal_local() self.register_instruction(TypeOfNode(self_local, obj_type)) self.register_instruction(TypeNameNode(type_name_inst, obj_type)) + self.register_instruction(ReturnNode(type_name_inst)) self.current_method = self.current_function = None self.current_type = None \ No newline at end of file diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index d82a78bc..ddd75915 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -38,6 +38,18 @@ def __init__(self, name): class InstructionNode(Node): pass +class GetAttribNode(InstructionNode): + def __init__(self, dest, obj, attrib): + self.dest = dest + self.obj = obj + self.attrib = attrib + +class SetAttribNode(InstructionNode): + def __init__(self, obj, attrib, value): + self.obj = obj + self.attrib = attrib + self.value = value + class AssignNode(InstructionNode): def __init__(self, dest, source): self.dest = dest @@ -157,6 +169,11 @@ def __init__(self, dest, msg1, msg2): self.msg1 = msg1 self.msg2 = msg2 +class StringEqualNode(InstructionNode): + def __init__(self, dest, msg1, msg2): + self.dest = dest + self.msg1 = msg1 + self.msg2 = msg2 class SubstringNode(InstructionNode): def __init__(self, dest, msg1, start, length): @@ -185,17 +202,6 @@ def __init__(self, str_addr): ################# nodes que me tengo que definir ############## -# class GetAttribNode(InstructionNode): -# def __init__(self, dest, obj, attrib): -# self.dest = dest -# self.obj = obj -# self.attrib = attrib - -# class SetAttribNode(InstructionNode): -# def __init__(self, obj, attrib, value): -# self.obj = obj -# self.attrib = attrib -# self.value = value # class GetIndexNode(InstructionNode): # def __init__(self, dest, array, index): @@ -228,9 +234,3 @@ def __init__(self, str_addr): # def __init__(self, nargs): # self.nargs = nargs -# class StringEqualNode(InstructionNode): -# def __init__(self, dest, msg1, msg2): -# self.dest = dest -# self.msg1 = msg1 -# self.msg2 = msg2 - diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index e5e01a25..3f323b83 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -18,14 +18,25 @@ def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): result = self.define_internal_local() expr ,typex = self.visit(node.expression, scope) self.register_instruction(cil_node(result, expr)) - return result, typex + return result + + def save_attr_init(self, node:cool.ProgramNode): + self.attr_init = dict() + for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode): + self.attr_init[declaration.id.lex] = [] + if dec.parent and not classx.parent in ['IO', 'Object']: + self.attr_init[classx.id] += self.attr_init[classx.parent] + for feature in classx.features: + if type(feature) is cool.AttrDeclarationNode: + self.attr_init[classx.id].append(feature) @visitor.on('node') def visit(self,node,scope): pass @visitor.when(cool.ProgramNode) - def visit(self,node: cool.ProgramNode, scope): + def visit(self,node: cool.ProgramNode, scope = None): + scope = Scope() self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() @@ -36,12 +47,12 @@ def visit(self,node: cool.ProgramNode, scope): self.register_instruction(ReturnNode(0)) self.current_function = None - for declaration, child_scope in zip(node.declarations,scope.children): - self.visit(declaration,child_scope) + classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)]: + self.visit(declaration,scope) return ProgramNode(self.dottypes,self.dotdata,self.dotcode) - @visitor.when(cool.ClassDeclarationNode) + @visitor.when(cool.ClassDeclarationNode) def visit(self,node: cool.ClassDeclarationNode,scope): self.current_type = self.context.get_type(node.id.lex) type_node = self.register_type(node.id.lex) @@ -49,56 +60,69 @@ def visit(self,node: cool.ClassDeclarationNode,scope): type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] fun_declarations = (f for f in node.features if isinstance(f,cool.FuncDeclarationNode)) - for feature, child_scope in zip(fun_declarations,scope.children): - self.visit(feature,child_scope) + for feature in fun_declarations: + self.visit(feature,scope) self.current_type = None @visitor.when(cool.FuncDeclarationNode) - def visit(self,node: cool.FuncDeclarationNode,scope): + def visit(self,node: cool.FuncDeclarationNode,scope: Scope): + fun_scope = Scope(parent=scope) self.current_method = self.current_type.get_method(node.id.lex) type_name = self.current_type.name self.current_function = self.register_function(self.to_function_name(node.id.lex, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + func_scope.define_variable('self', self_local) for param_name, param_type in node.params: self.register_param(VariableInfo(param_name, param_type)) - body = self.visit(node.body,scope) + body = self.visit(node.body,func_scope) self.register_instruction(ReturnNode(body)) self.current_method = None @visitor.when(cool.AttrDeclarationNode) def visit(self,node: cool.AttrDeclarationNode,scope): - attr_info = scope.find_variable(node.id.lex) - vtype = get_type(attr_info.type) - local_attr = self.register_local(VariableInfo(attr_info.name,vtype)) - - expr, _ = self.visit(node.expression,scope) - self.register_instruction(AssignNode(local_attr,expr)) - return local_attr,vtype + result = self.visit(node.expression, scope) if node.expression else 0 + self_inst = scope.find_variable('self').name + self.register_instruction(SetAttribNode(self_inst, node.id.lex, result)) @visitor.when(cool.AssignNode) def visit(self,node: cool.AssignNode,scope): - vinfo = scope.find_variable(node.id.lex) - vname = self.register_local(VariableInfo(node.id.lex,get_type(vinfo.type))) expr = self.visit(node.expression,scope) - return self.register_instruction(AssignNode(vname,expr)) + attr_info = scope.find_variable(node.id.lex) + if not attr_info: + selfx = scope.find_variable('self').name + self.register_instruction(SetAttribNode(selfx, node.id.lex, expr)) + else: + attr_info = attr_info.name + self.register_instruction(AssignNode(attr_info, value)) + return 0 + + @visitor.when(cool.NewNode) + def visit(self,node: cool.NewNode,scope): + new_local = self.define_internal_local() + typex = self.context.get_type(node.type.lex) + self.register_instruction(AllocateNode(new_local, typex)) + + return new_local @visitor.when(cool.IfThenElseNode) def visit(self,node:cool.IfThenElseNode,scope): - cond, _ = self.visit(node.condition, scope) + cond = self.visit(node.condition, scope) + child_scope = Scope(parent=scope) true_label = LabelNode('TRUE') end_label = LabelNode('END') result = self.define_internal_local() self.register_instruction(IfGotoNode(cond,self.to_label_name(true_label.label))) - false_expr = self.visit(node.else_body, scope) + false_expr = self.visit(node.else_body, child_scope) self.register_instruction(AssignNode(result,false_expr)) self.register_instruction(GotoNode(self.to_label_name(end_label.label))) self.register_instruction(true_label) - true_expr = self.visit(node.if_body, scope) + true_expr = self.visit(node.if_body, child_scope) self.register_instruction(AssignNode(result,true_expr)) self.register_instruction(end_label) @@ -106,23 +130,24 @@ def visit(self,node:cool.IfThenElseNode,scope): @visitor.when(cool.WhileLoopNode) def visit(self,node:cool.WhileLoopNode,scope): + while_scope = Scope(parent=None) start_label = LabelNode('START') continue_label = LabelNode('CONTINUE') end_label = LabelNode('END') - result = self.define_internal_local() + # result = self.define_internal_local() self.register_instruction(start_label) - cond, _ = self.visit(node.condition,scope) + cond = self.visit(node.condition,scope) self.register_instruction(IfGotoNode(cond, continue_label)) self.register_instruction(GotoNode(end_label)) self.register_instruction(continue_label) - body, btype = self.visit(node.body, scope) + self.visit(node.body, while_scope) self.register_instruction(GotoNode(start_label)) self.register_instruction(end_label) - self.register_instruction(AssignNode(result,body)) - return result, btype + # self.register_instruction(AssignNode(result,body)) + return 0 @visitor.when(cool.CaseOfNode) def visit(self,node: cool.CaseOfNode,scope): @@ -198,7 +223,6 @@ def visit(self,node: cool.MemberCallNode, scope: Scope): return result - @visitor.when(cool.PlusNode) def visit(self, node:cool.PlusNode, scope): return self.define_binary_node(node,scope,PlusNode) @@ -219,9 +243,21 @@ def visit(self, node:cool.DivNode, scope): def visit(self, node:cool.LessNode, scope): return self.define_binary_node(node,scope,LessNode) + @visitor.when(cool.LessEqualNode) + def visit(self, node: cool.LessEqualNode, scope): + return self.define_binary_node(node, scope, LessEqNode) + @visitor.when(cool.EqualNode) def visit(self, node: cool.EqualNode, scope): - return self.define_binary_node(node,scope,EqualNode) + left = self.visit(node.left, scope) + right = self.visit(node.right, scope) + result = self.define_internal_local() + + if node.left.static_type == self.context.get_type('String'): + self.register_instruction(StringEqualNode(result, left, right)) + else: + self.register_instruction(EqualNode(result, left, right)) + return result @visitor.when(cool.IsVoidNode) def visit(self, node: cool.IsVoidNode, scope): @@ -237,29 +273,30 @@ def visit(self, node: cool.ComplementNode, scope): @visitor.when(cool.IdNode) def visit(self, node: cool.IdNode, scope: Scope): - typex = scope.find_variable(node.token.lex).type - return node.token.lex, typex + nvar = scope.find_variable(node.token.lex) + if not nvar: + selfx = scope.find_variable('self').name + nvar = self.define_internal_local() + self.register_instruction(GetAttribNode(nvar, selfx, node.token.lex)) + else: + nvar = nvar.name + return nvar @visitor.when(cool.BoolNode) def visit(self, node:cool.BoolNode, scope): - typex = self.context.get_type('Bool').name - return (1, typex) if node.token.lex else (0, typex) + return 1 if node.token.lex else 0 @visitor.when(cool.IntegerNode) def visit(self, node:cool.IntegerNode, scope): - return int(node.token.lex), self.context.get_type('Int').name + return int(node.token.lex) @visitor.when(cool.StringNode) def visit(self, node:cool.StringNode, scope): string = self.register_data(node.token.lex) - return string.value, string.name + dest = self.define_internal_local() + self.register_instruction(LoadNode(dest,string.name)) + return dest - @visitor.when(cool.NewNode) - def visit(self,node: cool.NewNode,scope): - new_local = self.define_internal_local() - typex = self.context.get_type(node.type.lex) - self.register_instruction(AllocateNode(new_local, typex)) - return new_local, typex From 13783f707a6fc937265f3be22d9122c03f760ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 14:39:05 -0500 Subject: [PATCH 049/191] Improve checker visit function order --- src/engine/visitors/checker.py | 57 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index af78aa81..1c24ea17 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -193,8 +193,6 @@ def visit(self, node, scope): @visitor.when(AssignNode) def visit(self, node, scope): expression = node.expression - self.visit(expression, scope.create_child()) - expr_type = expression.static_type if scope.is_defined(node.id.lex): var = scope.find_variable(node.id.lex) @@ -202,11 +200,15 @@ def visit(self, node, scope): if var.name == 'self': self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + SELF_IS_READONLY) - elif not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) else: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) - + + self.visit(expression, scope.create_child()) + expr_type = expression.static_type + + if not expr_type.conforms_to(node_type): + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + node.static_type = expr_type @visitor.when(NotNode) @@ -305,6 +307,7 @@ def visit(self, node, scope): except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "TypeError: " + ex.text) node_type = ErrorType() + return else: if isinstance(node_type, SelfType): self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "SemanticError: " + f'Type "{node_type}" cannot be used as type dispatch') @@ -321,20 +324,19 @@ def visit(self, node, scope): except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "AttributeError: " + ex.text) node_type = ErrorType() - obj_method = None + obj_method = None - for arg in node.args: - self.visit(arg, scope.create_child()) - - if obj_method and len(node.args) == len(obj_method.param_types): - for arg, param_type in zip(node.args, obj_method.param_types): - arg_type = arg.static_type - - if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') - + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, param_type in zip(node.args, obj_method.param_types): + self.visit(arg, scope.create_child()) + arg_type = arg.static_type + + if not arg_type.conforms_to(param_type): + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') + node.static_type = node_type @visitor.when(MemberCallNode) @@ -350,18 +352,17 @@ def visit(self, node, scope): node_type = ErrorType() obj_method = None - for arg in node.args: - self.visit(arg, scope.create_child()) - - if obj_method and len(node.args) == len(obj_method.param_types): - for arg, param_type in zip(node.args, obj_method.param_types): - arg_type = arg.static_type - - if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" canot be dispatched') - + if obj_method and len(node.args) == len(obj_method.param_types): + for arg, param_type in zip(node.args, obj_method.param_types): + self.visit(arg, scope.create_child()) + arg_type = arg.static_type + + if not arg_type.conforms_to(param_type): + self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + else: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') + node.static_type = node_type @visitor.when(NewNode) From e751e5d67855284664196bc6bdc4e4d4f3188560 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 26 Nov 2020 15:11:33 -0500 Subject: [PATCH 050/191] syntax error fixed --- src/engine/codegen/to_cil.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 3f323b83..89f731e5 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -20,15 +20,15 @@ def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): self.register_instruction(cil_node(result, expr)) return result - def save_attr_init(self, node:cool.ProgramNode): - self.attr_init = dict() - for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode): - self.attr_init[declaration.id.lex] = [] - if dec.parent and not classx.parent in ['IO', 'Object']: - self.attr_init[classx.id] += self.attr_init[classx.parent] - for feature in classx.features: - if type(feature) is cool.AttrDeclarationNode: - self.attr_init[classx.id].append(feature) + # def save_attr_init(self, node:cool.ProgramNode): + # self.attr_init = dict() + # for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode): + # self.attr_init[declaration.id.lex] = [] + # if dec.parent and not classx.parent in ['IO', 'Object']: + # self.attr_init[classx.id] += self.attr_init[classx.parent] + # for feature in classx.features: + # if type(feature) is cool.AttrDeclarationNode: + # self.attr_init[classx.id].append(feature) @visitor.on('node') def visit(self,node,scope): @@ -47,7 +47,8 @@ def visit(self,node: cool.ProgramNode, scope = None): self.register_instruction(ReturnNode(0)) self.current_function = None - classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)]: + classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)] + for declaration in classes: self.visit(declaration,scope) return ProgramNode(self.dottypes,self.dotdata,self.dotcode) @@ -73,11 +74,11 @@ def visit(self,node: cool.FuncDeclarationNode,scope: Scope): self.current_function = self.register_function(self.to_function_name(node.id.lex, type_name)) self_local = self.register_param(VariableInfo('self', None)) - func_scope.define_variable('self', self_local) + fun_scope.define_variable('self', self_local) for param_name, param_type in node.params: self.register_param(VariableInfo(param_name, param_type)) - body = self.visit(node.body,func_scope) + body = self.visit(node.body,fun_scope) self.register_instruction(ReturnNode(body)) self.current_method = None @@ -104,7 +105,7 @@ def visit(self,node: cool.AssignNode,scope): def visit(self,node: cool.NewNode,scope): new_local = self.define_internal_local() typex = self.context.get_type(node.type.lex) - self.register_instruction(AllocateNode(new_local, typex)) + self.register_instruction(AllocateNode(new_local, typex.name)) return new_local From 396330c67943c214067172a50d75afd90e6e5901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 15:22:57 -0500 Subject: [PATCH 051/191] Fix function multiple times parameter --- src/engine/cp/semantic.py | 3 +++ src/engine/visitors/checker.py | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index 462cfbba..b90472ba 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -311,6 +311,9 @@ def create_child(self): def define_variable(self, vname, vtype): info = VariableInfo(vname, vtype) + for i in self.locals: + if i.name == vname: + raise SemanticError(f'Variable {vname} already exists in the current context') self.locals.append(info) return info diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 1c24ea17..b7212634 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -89,7 +89,11 @@ def visit(self, node, scope): for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): if pname == 'self': self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") - scope.define_variable(pname, ptype) + + try: + scope.define_variable(pname, ptype) + except SemanticError: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") body = node.body self.visit(body, scope.create_child()) From 73eb5d70c8f16e8f615bc1df331350b5d9a3aad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 15:33:44 -0500 Subject: [PATCH 052/191] Amend last commit ;) --- src/engine/cp/semantic.py | 3 --- src/engine/visitors/checker.py | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index b90472ba..462cfbba 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -311,9 +311,6 @@ def create_child(self): def define_variable(self, vname, vtype): info = VariableInfo(vname, vtype) - for i in self.locals: - if i.name == vname: - raise SemanticError(f'Variable {vname} already exists in the current context') self.locals.append(info) return info diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index b7212634..a0a31041 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -90,10 +90,11 @@ def visit(self, node, scope): if pname == 'self': self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") - try: - scope.define_variable(pname, ptype) - except SemanticError: + if scope.is_defined(pname): self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") + else: + scope.define_variable(pname, ptype) + body = node.body self.visit(body, scope.create_child()) From 85c474fd69267d98867fa499dce8f5d271f682d9 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 26 Nov 2020 16:40:28 -0500 Subject: [PATCH 053/191] attribute setter and getter --- src/engine/codegen/cil_format.py | 18 +++++++++--------- src/engine/codegen/to_cil.py | 32 +++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index eec71361..6abfe85f 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -123,13 +123,13 @@ def visit(self, node: ToStrNode): def visit(self, node: ToIntNode): return f'{node.dest} = INT {node.msg}' - # @visitor.when(GetAttribNode) - # def visit(self, node: GetAttribNode): - # return f'{node.dest} = GETATTR {node.obj} {node.attrib}' + @visitor.when(GetAttribNode) + def visit(self, node: GetAttribNode): + return f'{node.dest} = GETATTR {node.obj} {node.attrib}' - # @visitor.when(SetAttribNode) - # def visit(self, node: SetAttribNode): - # return f'SETATTR {node.obj} {node.attrib} {node.value}' + @visitor.when(SetAttribNode) + def visit(self, node: SetAttribNode): + return f'SETATTR {node.obj} {node.attrib} {node.value}' @visitor.when(LabelNode) def visit(self, node: LabelNode): @@ -178,9 +178,9 @@ def visit(self, node: ErrorNode): def visit(self, node:NotNode): return f'{node.dest} = NOT {node.body}' - # @visitor.when(StringEqualNode) - # def visit(self, node: StringEqualNode): - # return f'{node.dest} = STREQ {node.msg1} {node.msg2}' + @visitor.when(StringEqualNode) + def visit(self, node: StringEqualNode): + return f'{node.dest} = STREQ {node.msg1} {node.msg2}' @visitor.when(CopyNode) def visit(self, node: CopyNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 89f731e5..6bb03885 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -20,15 +20,23 @@ def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): self.register_instruction(cil_node(result, expr)) return result - # def save_attr_init(self, node:cool.ProgramNode): - # self.attr_init = dict() - # for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode): - # self.attr_init[declaration.id.lex] = [] - # if dec.parent and not classx.parent in ['IO', 'Object']: - # self.attr_init[classx.id] += self.attr_init[classx.parent] - # for feature in classx.features: - # if type(feature) is cool.AttrDeclarationNode: - # self.attr_init[classx.id].append(feature) + def init_class_attr(self, scope:Scope, class_id, self_inst): + attr_nodes = self.attr_init[class_id] + for attr in attr_nodes: + attr_scope = Scope(parent=scope) + attr_scope.define_variable('self', self_inst) + self.visit(attr, attr_scope) + + def save_attr_init(self, node:cool.ProgramNode): + self.attr_init = dict() + classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)] + for declaration in classes: + self.attr_init[declaration.id.lex] = [] + if declaration.parent and not declaration.parent.lex in ['IO', 'Object']: + self.attr_init[declaration.id.lex] += self.attr_init[declaration.parent.lex] + for feature in declaration.features: + if isinstance(feature,cool.AttrDeclarationNode): + self.attr_init[declaration.id.lex].append(feature) @visitor.on('node') def visit(self,node,scope): @@ -37,10 +45,12 @@ def visit(self,node,scope): @visitor.when(cool.ProgramNode) def visit(self,node: cool.ProgramNode, scope = None): scope = Scope() + self.save_attr_init(node) self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() self.register_instruction(AllocateNode('Main',instance)) + self.init_class_attr(scope, 'Main', instance) self.register_instruction(ArgNode(instance)) name = self.to_function_name('main','Main') self.register_instruction(StaticCallNode(name,result)) @@ -106,7 +116,7 @@ def visit(self,node: cool.NewNode,scope): new_local = self.define_internal_local() typex = self.context.get_type(node.type.lex) self.register_instruction(AllocateNode(new_local, typex.name)) - + self.init_class_attr(scope, node.type.lex, new_local) return new_local @visitor.when(cool.IfThenElseNode) @@ -169,7 +179,7 @@ def visit(self,node: cool.CaseOfNode,scope): @visitor.when(cool.LetInNode) def visit(self,node: cool.LetInNode,scope: Scope): - let_scope = scope.children[0] + let_scope = Scope(parent=scope) for let_id, let_type, let_expr in node.let_body: let_scope.define_variable(let_id.lex, let_type.lex) self.visit(let_expr,let_scope) From 8154065aff0db63e017f6944e943e2ddb6c89668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 21:07:14 -0500 Subject: [PATCH 054/191] Cyclic heritage error fix --- src/engine/visitors/collector.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 24c9b5c2..7f158be8 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -1,11 +1,12 @@ from engine.cp import SemanticError, visitor, Context, SelfType from engine.parser import ProgramNode, ClassDeclarationNode -from engine.semantic_errors import ERROR_ON_LN_COL +from engine.semantic_errors import ERROR_ON_LN_COL, CYCLIC_HERITAGE class Collector: def __init__(self, errors = []): self.context = Context() self.errors = errors + self.parents = {} #Tipos especiales self.context.add_type(SelfType()) @@ -16,6 +17,19 @@ def __init__(self, errors = []): self.context.create_type('Int',builtin = True) self.context.create_type('String',builtin = True) self.context.create_type('Bool',builtin = True) + + self.parents['Object'] = None + self.parents['IO'] = 'Object' + self.parents['Int'] = 'Object' + self.parents['String'] = 'Object' + self.parents['Bool'] = 'Object' + + def ciclic_heritage(self, name, parent): + if parent is None: + return False + if name == parent: + return True + return self.ciclic_heritage(name, self.parents[parent]) @visitor.on('node') def visit(self, node): @@ -25,6 +39,14 @@ def visit(self, node): def visit(self, node): for class_def in node.declarations: self.visit(class_def) + + if not len(self.errors): + for declaration in node.declarations: + if declaration.id.lex not in self.parents.keys(): + self.parents[declaration.id.lex] = 'Object' if declaration.parent == None else declaration.parent.lex + if declaration.parent != None and declaration.parent.lex in self.parents.keys() and self.ciclic_heritage(declaration.id.lex, declaration.parent.lex): + self.errors.append(ERROR_ON_LN_COL % (declaration.line, declaration.column) + "SemanticError: " + CYCLIC_HERITAGE % (declaration.id.lex)) + break @visitor.when(ClassDeclarationNode) def visit(self, node): From eb0427b30c472341eaf39b3f16e579813b03f58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 22:01:59 -0500 Subject: [PATCH 055/191] Fix multiple times same variable declaration error --- src/engine/cp/semantic.py | 3 +++ src/engine/visitors/checker.py | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index 462cfbba..b90472ba 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -311,6 +311,9 @@ def create_child(self): def define_variable(self, vname, vtype): info = VariableInfo(vname, vtype) + for i in self.locals: + if i.name == vname: + raise SemanticError(f'Variable {vname} already exists in the current context') self.locals.append(info) return info diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index a0a31041..f7607f42 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -90,10 +90,10 @@ def visit(self, node, scope): if pname == 'self': self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") - if scope.is_defined(pname): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") - else: + try: scope.define_variable(pname, ptype) + except SemanticError: + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") body = node.body @@ -163,7 +163,10 @@ def visit(self, node, scope): if not expr_type.conforms_to(id_type): self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) - scope.define_variable(idx.lex, id_type) + try: + scope.define_variable(idx.lex, id_type) + except SemanticError as e: + self.errors.append(ERROR_ON_LN_COL % (idx.line, idx.column) + "SemanticError: " + e.text) self.visit(node.in_body, scope.create_child()) From a3f2d3a50d853700c5b94f1086af008b529dbf5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 22:24:20 -0500 Subject: [PATCH 056/191] Fix attribute declaration node line and column error --- src/engine/visitors/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index f7607f42..12cc3b61 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -67,7 +67,7 @@ def visit(self, node, scope): node_type = attr.type node_type = self.current_type if isinstance(node_type, SelfType) else node_type if not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) @visitor.when(FuncDeclarationNode) def visit(self, node, scope): From 311e7d71d90865b922ecdbb276835beaeae9fd32 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 26 Nov 2020 22:33:15 -0500 Subject: [PATCH 057/191] CIL code generation completed --- src/engine/codegen/cil.py | 1 - src/engine/codegen/cil_ast.py | 25 --------- src/engine/codegen/cil_format.py | 4 +- src/engine/codegen/to_cil.py | 27 +++++----- src/engine/codegen/utils.py | 36 ------------- src/main.py | 14 ++--- src/test.mips | 92 ++++++++++++++------------------ 7 files changed, 62 insertions(+), 137 deletions(-) delete mode 100644 src/engine/codegen/utils.py diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 2d78a409..a29768c0 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -28,7 +28,6 @@ def instructions(self): def register_param(self, vinfo): param_node = ParamNode(vinfo.name) - # vinfo.name = f'param_{self.current_function.name[9:]}_{vinfo.name}_{len(self.params)}' self.params.append(param_node) return vinfo.name diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index ddd75915..e86fe6d8 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -202,26 +202,6 @@ def __init__(self, str_addr): ################# nodes que me tengo que definir ############## - -# class GetIndexNode(InstructionNode): -# def __init__(self, dest, array, index): -# self.dest = dest -# self.array = array -# self.index = index - -# class SetIndexNode(InstructionNode): -# def __init__(self, array, index, value): -# self.array = array -# self.index = index -# self.value = value - -# class PrefixNode(InstructionNode): -# def __init__(self, dest, msg1, msg2): -# self.dest = dest -# self.msg1 = msg1 -# self.msg2 = msg2 - - # class ConformNode(InstructionNode): # def __init__(self, dest, obj, typex): # self.dest = dest @@ -229,8 +209,3 @@ def __init__(self, str_addr): # self.type = typex - -# class CleanArgsNode(InstructionNode): -# def __init__(self, nargs): -# self.nargs = nargs - diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 6abfe85f..3568a185 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -145,7 +145,7 @@ def visit(self, node: IfGotoNode): @visitor.when(ComplementNode) def visit(self, node: ComplementNode): - return f'{node.dest} = COMPLEMENT {node.body}' + return f'{node.dest} = COMPLEMENT {node.expression}' @visitor.when(LessNode) def visit(self, node: LessNode): @@ -176,7 +176,7 @@ def visit(self, node: ErrorNode): @visitor.when(NotNode) def visit(self, node:NotNode): - return f'{node.dest} = NOT {node.body}' + return f'{node.dest} = NOT {node.expression}' @visitor.when(StringEqualNode) def visit(self, node: StringEqualNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 6bb03885..a538df73 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -16,7 +16,7 @@ def define_binary_node(self, node: cool.BinaryNode, scope, cil_node: Node): def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): result = self.define_internal_local() - expr ,typex = self.visit(node.expression, scope) + expr = self.visit(node.expression, scope) self.register_instruction(cil_node(result, expr)) return result @@ -86,7 +86,7 @@ def visit(self,node: cool.FuncDeclarationNode,scope: Scope): self_local = self.register_param(VariableInfo('self', None)) fun_scope.define_variable('self', self_local) for param_name, param_type in node.params: - self.register_param(VariableInfo(param_name, param_type)) + self.register_param(VariableInfo(param_name.lex, param_type.lex)) body = self.visit(node.body,fun_scope) @@ -108,7 +108,7 @@ def visit(self,node: cool.AssignNode,scope): self.register_instruction(SetAttribNode(selfx, node.id.lex, expr)) else: attr_info = attr_info.name - self.register_instruction(AssignNode(attr_info, value)) + self.register_instruction(AssignNode(attr_info, expr)) return 0 @visitor.when(cool.NewNode) @@ -141,41 +141,40 @@ def visit(self,node:cool.IfThenElseNode,scope): @visitor.when(cool.WhileLoopNode) def visit(self,node:cool.WhileLoopNode,scope): - while_scope = Scope(parent=None) + while_scope = Scope(parent=scope) start_label = LabelNode('START') continue_label = LabelNode('CONTINUE') end_label = LabelNode('END') - # result = self.define_internal_local() self.register_instruction(start_label) cond = self.visit(node.condition,scope) - self.register_instruction(IfGotoNode(cond, continue_label)) - self.register_instruction(GotoNode(end_label)) + self.register_instruction(IfGotoNode(cond, continue_label.label)) + self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) self.visit(node.body, while_scope) - self.register_instruction(GotoNode(start_label)) + self.register_instruction(GotoNode(start_label.label)) self.register_instruction(end_label) - # self.register_instruction(AssignNode(result,body)) return 0 @visitor.when(cool.CaseOfNode) def visit(self,node: cool.CaseOfNode,scope): - expr, typex = self.visit(node.expression, scope) + expr = self.visit(node.expression, scope) result = self.define_internal_local() exptype = self.define_internal_local() end_label = LabelNode('END') self.register_instruction(TypeOfNode(expr,exptype)) - for i ,case, child_scope in enumerate(zip(node.branches, scope.children)): - expr_n, type_n = self.visit(case,child_scope) + for i ,case in enumerate(node.branches): + child_scope = Scope(parent=scope) + expr_n = self.visit(case,child_scope) self.register_instruction(AssignNode(result,expr_n)) - self.register_instruction(GotoNode(end_label)) + self.register_instruction(GotoNode(end_label.label)) self.register_instruction(LabelNode(f'CASE_{i}')) self.register_instruction(end_label) - return result, typex + return result @visitor.when(cool.LetInNode) def visit(self,node: cool.LetInNode,scope: Scope): diff --git a/src/engine/codegen/utils.py b/src/engine/codegen/utils.py deleted file mode 100644 index e922f295..00000000 --- a/src/engine/codegen/utils.py +++ /dev/null @@ -1,36 +0,0 @@ -# class Var: -# def __init__(self, idx, local_name): -# self.id = idx -# self.local_name = local_name - -# def __str__(self): -# return f'[var] {self.id}: {self.local_name}' - -# def __repr__(self): -# return str(self) - -# class Scope: -# def __init__(self, parent=None): -# self.parent = parent -# self.vars = {} - -# def child(self): -# return Scope(parent=self) - -# def define_var(self, name, local_name): -# var = self.vars[name] = Var(name, local_name) -# return var - -# def get_var(self, name): -# try: -# return self.vars[name] -# except KeyError: -# if not self.parent is None: -# return self.parent.get_var(name) -# return None - -# def __str__(self): -# return '{\n' + ('\t' if self.parent is None else 'Parent:\n' + f'{self.parent}\n\t') + '\n\t'.join(str(x) for x in self.vars.values()) + '\n}' - -# def __repr__(self): -# return str(self) \ No newline at end of file diff --git a/src/main.py b/src/main.py index 618d63fe..451d0e70 100644 --- a/src/main.py +++ b/src/main.py @@ -62,15 +62,15 @@ -# cil = COOL_TO_CIL(checker.context) +cil = COOL_TO_CIL(checker.context) # # cil = COOL_TO_CIL_VISITOR(checker.context) # # sc = Scope() -# cil_ast = cil.visit(ast,scope) -# # f_ast = Format().visit(ast) -# f_ast = CIL_FORMATTER().visit(cil_ast) -# string_formatted = str(f_ast) -#output_file.write(string_formatted) -output_file.write(str(collect_errors)) +cil_ast = cil.visit(ast) +# f_ast = Format().visit(ast) +f_ast = CIL_FORMATTER().visit(cil_ast) +string_formatted = str(f_ast) +output_file.write(string_formatted) +# output_file.write(str(collect_errors)) #print(str(collect_errors)) #output_file.write(str(builder_errors)) #output_file.write(str(checker_errors)) diff --git a/src/test.mips b/src/test.mips index 1c3b40e4..f59612e3 100644 --- a/src/test.mips +++ b/src/test.mips @@ -95,6 +95,7 @@ function function_abort_at_Object { ERROR 0 + RETURN 0 } function function_copy_at_Object { PARAM self @@ -102,6 +103,7 @@ function function_copy_at_Object { LOCAL local_copy_at_Object_internal_0 local_copy_at_Object_internal_0 = COPY self + RETURN local_copy_at_Object_internal_0 } function function_type_name_at_Object { PARAM self @@ -111,6 +113,7 @@ function function_type_name_at_Object { local_type_name_at_Object_internal_1 = TYPEOF self local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 + RETURN local_type_name_at_Object_internal_0 } function function_length_at_String { PARAM self @@ -140,40 +143,39 @@ function function_substr_at_String { RETURN local_substr_at_String_internal_0 } function function_out_string_at_IO { - PARAM self + LOCAL local_out_string_at_IO_internal_0 PRINT local_out_string_at_IO_internal_0 - RETURN self + RETURN 0 } function function_in_string_at_IO { - PARAM self + LOCAL local_in_string_at_IO_internal_0 local_in_string_at_IO_internal_0 = READ - RETURN self + RETURN local_in_string_at_IO_internal_0 } function function_out_int_at_IO { - PARAM self PARAM int_val LOCAL local_out_int_at_IO_internal_0 local_out_int_at_IO_internal_0 = STR int_val PRINT local_out_int_at_IO_internal_0 - RETURN self + RETURN 0 } function function_in_int_at_IO { - PARAM self + LOCAL local_in_int_at_IO_internal_0 LOCAL local_in_int_at_IO_internal_1 local_in_int_at_IO_internal_0 = READ local_in_int_at_IO_internal_1 = INT local_in_int_at_IO_internal_0 - RETURN self + RETURN local_in_int_at_IO_internal_1 } function entry { @@ -187,7 +189,7 @@ function entry { RETURN 0 } function function_main_at_Main { - + PARAM self LOCAL local_main_at_Main_internal_0 LOCAL local_main_at_Main_internal_1 @@ -206,21 +208,15 @@ function function_main_at_Main { LOCAL local_main_at_Main_internal_14 LOCAL local_main_at_Main_internal_15 - local_main_at_Main_internal_1 = ALLOCATE type E : D { - [method] f(): String; -} - - ARG ('x', 'E') + local_main_at_Main_internal_1 = ALLOCATE E + ARG x + local_main_at_Main_internal_3 = CALL function_f_at_E + ARG x local_main_at_Main_internal_4 = CALL function_f_at_E - ARG ('x', 'E') - local_main_at_Main_internal_5 = CALL function_f_at_E - local_main_at_Main_internal_3 = local_main_at_Main_internal_4 == local_main_at_Main_internal_5 - local_main_at_Main_internal_2 = local_main_at_Main_internal_3 - local_main_at_Main_internal_6 = ALLOCATE type B : A { - [method] m(): String; -} - - ARG ('x', 'E') + local_main_at_Main_internal_5 = STREQ local_main_at_Main_internal_3 local_main_at_Main_internal_4 + local_main_at_Main_internal_2 = local_main_at_Main_internal_5 + local_main_at_Main_internal_6 = ALLOCATE B + ARG x local_main_at_Main_internal_10 = CALL function_f_at_A ARG local_main_at_Main_internal_10 local_main_at_Main_internal_9 = CALL function_m_at_A @@ -228,12 +224,8 @@ function function_main_at_Main { ARG self local_main_at_Main_internal_8 = VCALL Main out_string local_main_at_Main_internal_7 = local_main_at_Main_internal_8 - local_main_at_Main_internal_11 = ALLOCATE type A : Object { - [method] m(): String; - [method] f(): A; -} - - ARG ('x', 'E') + local_main_at_Main_internal_11 = ALLOCATE A + ARG x local_main_at_Main_internal_15 = CALL function_f_at_A ARG local_main_at_Main_internal_15 local_main_at_Main_internal_14 = CALL function_m_at_A @@ -245,46 +237,42 @@ function function_main_at_Main { RETURN local_main_at_Main_internal_0 } function function_m_at_A { - + PARAM self - + LOCAL local_m_at_A_internal_0 - RETURN ('A', 'data_0') + local_m_at_A_internal_0 = LOAD data_0 + RETURN local_m_at_A_internal_0 } function function_f_at_A { - + PARAM self LOCAL local_f_at_A_internal_0 - local_f_at_A_internal_0 = ALLOCATE type A : Object { - [method] m(): String; - [method] f(): A; -} - - RETURN ('local_f_at_A_internal_0', type A : Object { - [method] m(): String; - [method] f(): A; -} -) + local_f_at_A_internal_0 = ALLOCATE A + RETURN local_f_at_A_internal_0 } function function_m_at_B { - + PARAM self - + LOCAL local_m_at_B_internal_0 - RETURN ('B', 'data_1') + local_m_at_B_internal_0 = LOAD data_1 + RETURN local_m_at_B_internal_0 } function function_f_at_C { - + PARAM self - + LOCAL local_f_at_C_internal_0 - RETURN ('C', 'data_2') + local_f_at_C_internal_0 = LOAD data_2 + RETURN local_f_at_C_internal_0 } function function_f_at_E { - + PARAM self - + LOCAL local_f_at_E_internal_0 - RETURN ('E', 'data_3') + local_f_at_E_internal_0 = LOAD data_3 + RETURN local_f_at_E_internal_0 } \ No newline at end of file From 0d71c311a1e9ee67d0d7f3ad03cad9e6ac604599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 23:01:41 -0500 Subject: [PATCH 058/191] Fix type union index out of range case --- src/engine/cp/semantic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index b90472ba..aa95cc53 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -65,6 +65,8 @@ def type_union(self, other): while t1[-2] == t2[-2]: t1.pop() t2.pop() + if len(t1) < 2 or len(t2) < 2: + break return t1[-1] From 3d7e4a946645ddd0c1e14b19428d48456153516c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 26 Nov 2020 23:13:23 -0500 Subject: [PATCH 059/191] Fix repeated branch type of case errors --- src/engine/visitors/checker.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 12cc3b61..665c71ca 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -177,10 +177,16 @@ def visit(self, node, scope): self.visit(node.expression, scope.create_child()) node.static_type = None + + case_types = [] for idx, typex, expr in node.branches: try: node_type = self.context.get_type(typex.lex) + if node_type in case_types: + self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "SemanticError: " + f"Duplicate Branch {node_type} in case declaration") + else: + case_types.append(node_type) except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "TypeError: " + ex.text) node_type = ErrorType() From 3c360df3f1551cac44083b3cecff383f52a6694a Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sat, 28 Nov 2020 10:23:16 -0500 Subject: [PATCH 060/191] begin the mips visitor --- src/engine/codegen/to_mips.py | 169 ++++++++++++++++++++++++++++++++++ src/main.py | 16 ++-- 2 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 src/engine/codegen/to_mips.py diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py new file mode 100644 index 00000000..8f851f2b --- /dev/null +++ b/src/engine/codegen/to_mips.py @@ -0,0 +1,169 @@ +from .cil_ast import * +from ..cp import visitor + +class CIL_TO_MIPS: + + @visitor.on('node') + def visit(self,node): + pass + + @visitor.when(ProgramNode) + def visit(self,node): + pass + + @visitor.when(FunctionNode) + def visit(self,node): + pass + + @visitor.when(TypeNode) + def visit(self,node): + pass + + @visitor.when(DataNode) + def visit(self,node): + pass + + @visitor.when(ParamNode) + def visit(self,node): + pass + + @visitor.when(LocalNode) + def visit(self,node): + pass + + @visitor.when(GetAttribNode) + def visit(self,node): + pass + + @visitor.when(SetAttribNode) + def visit(self,node): + pass + + @visitor.when(AssignNode) + def visit(self,node): + pass + + @visitor.when(ComplementNode) + def visit(self,node): + pass + + @visitor.when(NotNode) + def visit(self,node): + pass + + @visitor.when(PlusNode) + def visit(self,node): + pass + + @visitor.when(MinusNode) + def visit(self,node): + pass + + @visitor.when(StarNode) + def visit(self,node): + pass + + @visitor.when(DivNode) + def visit(self,node): + pass + + @visitor.when(EqualNode) + def visit(self,node): + pass + + @visitor.when(LessEqNode) + def visit(self,node): + pass + + @visitor.when(LessNode) + def visit(self,node): + pass + + @visitor.when(AllocateNode) + def visit(self,node): + pass + + @visitor.when(TypeOfNode) + def visit(self,node): + pass + + @visitor.when(LabelNode) + def visit(self,node): + pass + + @visitor.when(GotoNode) + def visit(self,node): + pass + + @visitor.when(IfGotoNode) + def visit(self,node): + pass + + @visitor.when(StaticCallNode) + def visit(self,node): + pass + + @visitor.when(DynamicCallNode) + def visit(self,node): + pass + + @visitor.when(ArgNode) + def visit(self,node): + pass + + @visitor.when(ErrorNode) + def visit(self,node): + pass + + @visitor.when(CopyNode) + def visit(self,node): + pass + + @visitor.when(TypeNameNode) + def visit(self,node): + pass + + @visitor.when(LengthNode) + def visit(self,node): + pass + + @visitor.when(ConcatNode) + def visit(self,node): + pass + + @visitor.when(StringEqualNode) + def visit(self,node): + pass + + @visitor.when(ConcatNode) + def visit(self,node): + pass + + @visitor.when(LoadNode) + def visit(self,node): + pass + + @visitor.when(SubstringNode) + def visit(self,node): + pass + + @visitor.when(ToStrNode) + def visit(self,node): + pass + + @visitor.when(ToIntNode) + def visit(self,node): + pass + + @visitor.when(ReadNode) + def visit(self,node): + pass + + @visitor.when(PrintNode) + def visit(self,node): + pass + + @visitor.when(ReturnNode) + def visit(self,node): + pass + \ No newline at end of file diff --git a/src/main.py b/src/main.py index 451d0e70..cda6d828 100644 --- a/src/main.py +++ b/src/main.py @@ -62,15 +62,15 @@ -cil = COOL_TO_CIL(checker.context) -# # cil = COOL_TO_CIL_VISITOR(checker.context) -# # sc = Scope() -cil_ast = cil.visit(ast) +# cil = COOL_TO_CIL(checker.context) +# cil = COOL_TO_CIL_VISITOR(checker.context) +# sc = Scope() +# cil_ast = cil.visit(ast) # f_ast = Format().visit(ast) -f_ast = CIL_FORMATTER().visit(cil_ast) -string_formatted = str(f_ast) -output_file.write(string_formatted) -# output_file.write(str(collect_errors)) +# f_ast = CIL_FORMATTER().visit(cil_ast) +# string_formatted = str(f_ast) +# output_file.write(string_formatted) +output_file.write(str(collect_errors)) #print(str(collect_errors)) #output_file.write(str(builder_errors)) #output_file.write(str(checker_errors)) From b64837d1ab245629111ee13f9790d25729fee956 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sat, 28 Nov 2020 13:25:26 -0500 Subject: [PATCH 061/191] mips utils --- src/engine/codegen/mips.py | 91 +++++++++++++++++++++++++++++++++ src/engine/codegen/to_mips.py | 96 ++++++++++++++++++++++++++++++----- 2 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 src/engine/codegen/mips.py diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py new file mode 100644 index 00000000..0e0b0394 --- /dev/null +++ b/src/engine/codegen/mips.py @@ -0,0 +1,91 @@ +from enum import Enum + +class Registers: + zero = '$zero' # Constant 0 + at = '$at' # Reserved for assembler + v0 = '$v0' # Expression evaluation and + v1 = '$v1' # results of a function + a0 = '$a0' # Argument 1 + a1 = '$a1' # Argument 2 + a2 = '$a2' # Argument 3 + a3 = '$a3' # Argument 4 + t0 = '$t0' # Temporary(not preserved across call) + t1 = '$t1' # Temporary(not preserved across call) + t2 = '$t2' # Temporary(not preserved across call) + t3 = '$t3' # Temporary(not preserved across call) + t4 = '$t4' # Temporary(not preserved across call) + t5 = '$t5' # Temporary(not preserved across call) + t6 = '$t6' # Temporary(not preserved across call) + t7 = '$t7' # Temporary(not preserved across call) + s0 = '$s0' # Saved temporary(preserved across call) + s1 = '$s1' # Saved temporary(preserved across call) + s2 = '$s2' # Saved temporary(preserved across call) + s3 = '$s3' # Saved temporary(preserved across call) + s4 = '$s4' # Saved temporary(preserved across call) + s5 = '$s5' # Saved temporary(preserved across call) + s6 = '$s6' # Saved temporary(preserved across call) + s7 = '$s7' # Saved temporary(preserved across call) + t8 = '$t8' # Temporary(not preserved across call) + t9 = '$t9' # Temporary(not preserved across call) + k0 = '$k0' # Reserved for OS kernel + k1 = '$k1' # Reserved for OS kernel + gp = '$gp' # Pointer to global area + sp = '$sp' # Stack pointer + fp = '$fp' # Frame pointer + ra = '$ra' # Return address(used by function call) + + +class ArithmOperations(Enum): + Add = 1 + Sub = 2 + Mul = 3 + Div = 4 + + +class MipsCode: + def __init__(self): + pass + + def print_str(self, _str): + ''' + $v0 + $a0 + ''' + code = [ + 'li $v0, 4 # system call code for print_str', + f'la $a0, {_str} # address of string to print' , + 'syscall # print the string', + ] + return code + + def print_int(self, _int): + ''' + $v0 + $a0 + ''' + code = [ + 'li $v0, 1 # system call code for print_int', + f'la $a0, {_int} # address of string to print' , + 'syscall # print the string', + ] + return code + + def abs(self, rdest, rsrc): + ''' + Absolute Value + ''' + return f'abs {rdest}, {rsrc}' + + def lw(self, reg, memory, offset): + return f'lw {reg},{offset}({reg})' + + def addiu(self, rdest, rsrc, constant): + ''' + Addition Immediate (without overflow) + ''' + return f'addiu {rdest}, {offset}, {constant}' + + def add(self, rdest, rsrc, src): + ''' + + ''' diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 8f851f2b..9b83a03f 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,21 +1,90 @@ from .cil_ast import * from ..cp import visitor +from .mips import * class CIL_TO_MIPS: + def __init__(self): + self.data_code = [] + self.mips_code = [] + self.reg = Registers + self.code = MipsCode + + def visit_ArithNode(self, node: ArithmeticNode ): + # Setting + self.visit(node.left) + self.visit(node.right) + + self.mips_code.append("lw $t0, 8($sp)") + self.mips_code.append("lw $t1, 4($sp)") + + self.mips_code.append("lw $a0, 8($t0)") + self.mips_code.append("lw $a1, 8($t1)") + + self.mips_code.append("addiu $sp, $sp, 8") + # Operation + if isinstance(node, PlusNode): + self.mips_code.append("add $a1, $a0, $a1") + elif isinstance(node, MinusNode): + self.mips_code.append("sub $a1, $a0, $a1") + elif isinstance(node, StarNode): + self.mips_code.append("mult $a0, $a1") + self.mips_code.append("mflo $a1") + elif isinstance(node, DivNode): + self.mips_code.append("la $t0, zero_error") + self.mips_code.append("sw $t0, ($sp)") + self.mips_code.append("subu $sp, $sp, 4") + self.mips_code.append("beqz $a1, .raise") + self.mips_code.append("addu $sp, $sp, 4") + self.mips_code.append("div $a0, $a1") + self.mips_code.append("mflo $a1") + elif isinstance(node, LessNode): + self.mips_code.append("slt $a1, $a0, $a1") + elif isinstance(node, LessEqNode): + self.mips_code.append("sle $a1, $a0, $a1") + + # Return + self.mips_code.append("li $v0, 9") + self.mips_code.append("li $a0, 12") + self.mips_code.append("syscall") + if isinstance(node, EqualNode) or isinstance(node, LessNode): + self.mips_code.append("la $t0, Bool") + else: + self.mips_code.append("la $t0, Int") + + self.mips_code.append("sw $t0, ($v0)") + + self.mips_code.append("li $t0, 1") + self.mips_code.append("sw $t0, 4($v0)") + + self.mips_code.append("sw $a1, 8($v0)") + self.mips_code.append("sw $v0, ($sp)") + + self.mips_code.append("subu $sp, $sp, 4") + @visitor.on('node') def visit(self,node): pass @visitor.when(ProgramNode) - def visit(self,node): - pass + def visit(self,node: ProgramNode): + + for typex in node.dottypes: + self.visit(typex) + + for data in node.dotdata: + self.visit(data) + + for code in node.dotcode: + self.visit(code) + + return self.data_code, self.code - @visitor.when(FunctionNode) + @visitor.when(TypeNode) def visit(self,node): - pass - @visitor.when(TypeNode) + + @visitor.when(FunctionNode) def visit(self,node): pass @@ -52,32 +121,32 @@ def visit(self,node): pass @visitor.when(PlusNode) - def visit(self,node): - pass + def visit(self,node : PlusNode): + self.visit_ArithNode(node) @visitor.when(MinusNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(StarNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(DivNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(EqualNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(LessEqNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(LessNode) def visit(self,node): - pass + self.visit_ArithNode(node) @visitor.when(AllocateNode) def visit(self,node): @@ -166,4 +235,3 @@ def visit(self,node): @visitor.when(ReturnNode) def visit(self,node): pass - \ No newline at end of file From efed3ccbd3a86f0e42080809e5b037e787eda24c Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sat, 28 Nov 2020 14:14:49 -0500 Subject: [PATCH 062/191] formatter done --- src/engine/codegen/cil.py | 100 ++++++++++------- src/engine/codegen/cil_ast.py | 50 ++++++++- src/engine/codegen/cil_format.py | 16 ++- src/engine/codegen/mips.py | 7 +- src/engine/codegen/to_cil.py | 178 ++++++++++++++++--------------- src/engine/codegen/to_mips.py | 168 +++++++++++++++-------------- 6 files changed, 292 insertions(+), 227 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index a29768c0..93d88840 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -1,5 +1,6 @@ from .cil_ast import * -from ..cp.semantic import VariableInfo , Scope +from ..cp.semantic import VariableInfo, Scope + class BASE_COOL_CIL_TRANSFORM: def __init__(self, context): @@ -13,24 +14,24 @@ def __init__(self, context): self.define_object_type() self.define_string_type() self.define_io_type() - + @property def params(self): return self.current_function.params - + @property def localvars(self): return self.current_function.localvars - + @property def instructions(self): return self.current_function.instructions - + def register_param(self, vinfo): param_node = ParamNode(vinfo.name) self.params.append(param_node) return vinfo.name - + def register_local(self, vinfo): name = f'local_{self.current_function.name[9:]}_{vinfo.name}_{len(self.localvars)}' local_node = LocalNode(name) @@ -44,18 +45,18 @@ def define_internal_local(self): def register_instruction(self, instruction): self.instructions.append(instruction) return instruction - + def to_function_name(self, method_name, type_name): return f'function_{method_name}_at_{type_name}' def to_label_name(self, label_name): return f'{label_name}' - + def register_function(self, function_name): function_node = FunctionNode(function_name, [], [], []) self.dotcode.append(function_node) return function_node - + def register_type(self, name): type_node = TypeNode(name) self.dottypes.append(type_node) @@ -72,36 +73,42 @@ def register_data(self, value): def define_string_type(self): self.current_type = self.context.get_type('String') type_node = self.register_type('String') - type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] - type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + self.current_method = self.current_type.get_method('length') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_param = self.register_param(VariableInfo('self',None)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) + self_param = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() - self.register_instruction(LengthNode(dest,self_param)) + self.register_instruction(LengthNode(dest, self_param)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('concat') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_param = self.register_param(VariableInfo('self',None)) - str_param = self.register_param(VariableInfo('string',None)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) + self_param = self.register_param(VariableInfo('self', None)) + str_param = self.register_param(VariableInfo('string', None)) dest = self.define_internal_local() - self.register_instruction(ConcatNode(dest,self_param,str_param)) + self.register_instruction(ConcatNode(dest, self_param, str_param)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('substr') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) - self_param = self.register_param(VariableInfo('self',None)) - start = self.register_param(VariableInfo('start',None)) - length = self.register_param(VariableInfo('length',None)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) + self_param = self.register_param(VariableInfo('self', None)) + start = self.register_param(VariableInfo('start', None)) + length = self.register_param(VariableInfo('length', None)) dest = self.define_internal_local() - self.register_instruction(SubstringNode(dest,self_param,start,length)) + self.register_instruction(SubstringNode( + dest, self_param, start, length)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None @@ -110,12 +117,15 @@ def define_string_type(self): def define_io_type(self): self.current_type = self.context.get_type('IO') type_node = self.register_type('IO') - type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] - type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) str_val = self.define_internal_local() self.register_instruction(PrintNode(str_val)) self.register_instruction(ReturnNode(0)) @@ -123,7 +133,8 @@ def define_io_type(self): self.current_method = self.current_type.get_method('in_string') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) dest = self.define_internal_local() self.register_instruction(ReadNode(dest)) self.register_instruction(ReturnNode(dest)) @@ -131,21 +142,23 @@ def define_io_type(self): self.current_method = self.current_type.get_method('out_int') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) dest = self.define_internal_local() - int_val = self.register_param(VariableInfo('int_val',None)) - self.register_instruction(ToStrNode(dest,int_val)) + int_val = self.register_param(VariableInfo('int_val', None)) + self.register_instruction(ToStrNode(dest, int_val)) self.register_instruction(PrintNode(dest)) self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_int') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) dest = self.define_internal_local() int_val = self.define_internal_local() self.register_instruction(ReadNode(dest)) - self.register_instruction(ToIntNode(int_val,dest)) + self.register_instruction(ToIntNode(int_val, dest)) self.register_instruction(ReturnNode(int_val)) self.current_method = self.current_function = None self.current_type = None @@ -153,12 +166,15 @@ def define_io_type(self): def define_object_type(self): self.current_type = self.context.get_type('Object') type_node = self.register_type('Object') - type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] - type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name,type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) self.register_instruction(ErrorNode()) self.register_instruction(ReturnNode(0)) @@ -166,7 +182,8 @@ def define_object_type(self): self.current_method = self.current_type.get_method('copy') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) copy_inst = self.define_internal_local() self.register_instruction(CopyNode(copy_inst, self_local)) @@ -175,7 +192,8 @@ def define_object_type(self): self.current_method = self.current_type.get_method('type_name') type_name = self.current_type.name - self.current_function = self.register_function(self.to_function_name(self.current_method.name, type_name)) + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) type_name_inst = self.define_internal_local() obj_type = self.define_internal_local() @@ -183,4 +201,4 @@ def define_object_type(self): self.register_instruction(TypeNameNode(type_name_inst, obj_type)) self.register_instruction(ReturnNode(type_name_inst)) self.current_method = self.current_function = None - self.current_type = None \ No newline at end of file + self.current_type = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index e86fe6d8..8a529c5f 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -3,23 +3,27 @@ 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 @@ -27,72 +31,90 @@ def __init__(self, fname, params, localvars, instructions): 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 GetAttribNode(InstructionNode): def __init__(self, dest, obj, attrib): self.dest = dest self.obj = obj self.attrib = attrib + class SetAttribNode(InstructionNode): def __init__(self, obj, attrib, value): self.obj = obj self.attrib = attrib self.value = value - + + 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 UnaryNode(InstructionNode): - def __init__(self,dest, expression): + def __init__(self, dest, expression): self.dest = dest self.expression = expression + class ComplementNode(UnaryNode): pass + class IsVoidNode(UnaryNode): pass + class NotNode(UnaryNode): pass + class PlusNode(ArithmeticNode): pass + class MinusNode(ArithmeticNode): pass + class StarNode(ArithmeticNode): pass + class DivNode(ArithmeticNode): pass + class EqualNode(ArithmeticNode): pass + class LessNode(ArithmeticNode): pass + class LessEqNode(ArithmeticNode): pass @@ -102,79 +124,95 @@ def __init__(self, dest, itype): self.dest = dest self.type = itype + class TypeOfNode(InstructionNode): def __init__(self, obj, dest): self.obj = obj self.dest = dest + class LabelNode(InstructionNode): def __init__(self, label): self.label = label + class GotoNode(InstructionNode): def __init__(self, label): self.label = label + class IfGotoNode(InstructionNode): def __init__(self, value, label): self.value = value self.label = label + class StaticCallNode(InstructionNode): def __init__(self, function, dest): self.dest = dest self.function = function + 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 ErrorNode(InstructionNode): def __init__(self, error=0): self.error = error + class CopyNode(InstructionNode): def __init__(self, dest, obj): self.dest = dest - self.obj = obj + self.obj = obj + class TypeNameNode(InstructionNode): def __init__(self, dest, typex): self.dest = dest self.type = typex + 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): def __init__(self, dest, msg): self.dest = dest self.msg = msg + class ConcatNode(InstructionNode): def __init__(self, dest, msg1, msg2): self.dest = dest self.msg1 = msg1 self.msg2 = msg2 + class StringEqualNode(InstructionNode): def __init__(self, dest, msg1, msg2): self.dest = dest self.msg1 = msg1 self.msg2 = msg2 + class SubstringNode(InstructionNode): def __init__(self, dest, msg1, start, length): self.dest = dest @@ -182,20 +220,24 @@ def __init__(self, dest, msg1, start, length): self.start = start self.length = length + class ToStrNode(InstructionNode): def __init__(self, dest, ivalue): self.dest = dest self.ivalue = ivalue + class ToIntNode(InstructionNode): def __init__(self, dest, msg): self.dest = dest self.msg = msg + class ReadNode(InstructionNode): def __init__(self, dest): self.dest = dest + class PrintNode(InstructionNode): def __init__(self, str_addr): self.str_addr = str_addr @@ -207,5 +249,3 @@ def __init__(self, str_addr): # self.dest = dest # self.obj = obj # self.type = typex - - diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 3568a185..14cca39a 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -2,6 +2,7 @@ from ..cp import visitor + class CIL_FORMATTER(object): @visitor.on('node') def visit(self, node): @@ -22,7 +23,7 @@ def visit(self, node: DataNode): @visitor.when(TypeNode) def visit(self, node: TypeNode): 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) + 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}}' @@ -46,7 +47,6 @@ def visit(self, node: LocalNode): def visit(self, node: AssignNode): return f'{node.dest} = {node.source}' - @visitor.when(PlusNode) def visit(self, node: PlusNode): return f'{node.dest} = {node.left} + {node.right}' @@ -98,11 +98,11 @@ def visit(self, node: PrintNode): @visitor.when(LoadNode) def visit(self, node: LoadNode): return f'{node.dest} = LOAD {node.msg}' - + @visitor.when(LengthNode) def visit(self, node: LengthNode): return f'{node.dest} = LENGTH {node.msg}' - + @visitor.when(ConcatNode) def visit(self, node: ConcatNode): return f'{node.dest} = CONCAT {node.msg1} {node.msg2}' @@ -150,7 +150,7 @@ def visit(self, node: ComplementNode): @visitor.when(LessNode) def visit(self, node: LessNode): return f'{node.dest} = {node.left} < {node.right}' - + @visitor.when(IsVoidNode) def visit(self, node: IsVoidNode): return f'{node.dest} = ISVOID {node.body}' @@ -158,7 +158,7 @@ def visit(self, node: IsVoidNode): @visitor.when(LessEqNode) def visit(self, node: LessEqNode): return f'{node.dest} = {node.left} <= {node.right}' - + ###################### nodes to throw ####################### @visitor.when(EqualNode) @@ -173,9 +173,8 @@ def visit(self, node: ErrorNode): # def visit(self, node: ConformNode): # return f'{node.dest} = COMFORM {node.obj} {node.type}' - @visitor.when(NotNode) - def visit(self, node:NotNode): + def visit(self, node: NotNode): return f'{node.dest} = NOT {node.expression}' @visitor.when(StringEqualNode) @@ -189,4 +188,3 @@ def visit(self, node: CopyNode): @visitor.when(TypeNameNode) def visit(self, node: TypeNameNode): return f'{node.dest} = TYPENAME {node.type}' - diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 0e0b0394..bea243d8 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -1,5 +1,6 @@ from enum import Enum + class Registers: zero = '$zero' # Constant 0 at = '$at' # Reserved for assembler @@ -53,7 +54,7 @@ def print_str(self, _str): ''' code = [ 'li $v0, 4 # system call code for print_str', - f'la $a0, {_str} # address of string to print' , + f'la $a0, {_str} # address of string to print', 'syscall # print the string', ] return code @@ -65,7 +66,7 @@ def print_int(self, _int): ''' code = [ 'li $v0, 1 # system call code for print_int', - f'la $a0, {_int} # address of string to print' , + f'la $a0, {_int} # address of string to print', 'syscall # print the string', ] return code @@ -87,5 +88,5 @@ def addiu(self, rdest, rsrc, constant): def add(self, rdest, rsrc, src): ''' - + ''' diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index a538df73..18a6147a 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -1,7 +1,7 @@ from engine import parser as cool from .cil_ast import * from ..cp import visitor -from ..cp.semantic import VariableInfo , Scope +from ..cp.semantic import VariableInfo, Scope from .cil import BASE_COOL_CIL_TRANSFORM @@ -13,95 +13,102 @@ def define_binary_node(self, node: cool.BinaryNode, scope, cil_node: Node): right = self.visit(node.right, scope) self.register_instruction(cil_node(result, left, right)) return result - + def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): result = self.define_internal_local() expr = self.visit(node.expression, scope) - self.register_instruction(cil_node(result, expr)) + self.register_instruction(cil_node(result, expr)) return result - def init_class_attr(self, scope:Scope, class_id, self_inst): + def init_class_attr(self, scope: Scope, class_id, self_inst): attr_nodes = self.attr_init[class_id] for attr in attr_nodes: attr_scope = Scope(parent=scope) attr_scope.define_variable('self', self_inst) self.visit(attr, attr_scope) - def save_attr_init(self, node:cool.ProgramNode): + def save_attr_init(self, node: cool.ProgramNode): self.attr_init = dict() - classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)] - for declaration in classes: + classes = [declaration for declaration in node.declarations if isinstance( + declaration, cool.ClassDeclarationNode)] + for declaration in classes: self.attr_init[declaration.id.lex] = [] if declaration.parent and not declaration.parent.lex in ['IO', 'Object']: self.attr_init[declaration.id.lex] += self.attr_init[declaration.parent.lex] for feature in declaration.features: - if isinstance(feature,cool.AttrDeclarationNode): + if isinstance(feature, cool.AttrDeclarationNode): self.attr_init[declaration.id.lex].append(feature) @visitor.on('node') - def visit(self,node,scope): + def visit(self, node, scope): pass @visitor.when(cool.ProgramNode) - def visit(self,node: cool.ProgramNode, scope = None): + def visit(self, node: cool.ProgramNode, scope=None): scope = Scope() self.save_attr_init(node) self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() - self.register_instruction(AllocateNode('Main',instance)) + self.register_instruction(AllocateNode('Main', instance)) self.init_class_attr(scope, 'Main', instance) self.register_instruction(ArgNode(instance)) - name = self.to_function_name('main','Main') - self.register_instruction(StaticCallNode(name,result)) + name = self.to_function_name('main', 'Main') + self.register_instruction(StaticCallNode(name, result)) self.register_instruction(ReturnNode(0)) self.current_function = None - classes = [declaration for declaration in node.declarations if isinstance(declaration, cool.ClassDeclarationNode)] + classes = [declaration for declaration in node.declarations if isinstance( + declaration, cool.ClassDeclarationNode)] for declaration in classes: - self.visit(declaration,scope) + self.visit(declaration, scope) - return ProgramNode(self.dottypes,self.dotdata,self.dotcode) + return ProgramNode(self.dottypes, self.dotdata, self.dotcode) - @visitor.when(cool.ClassDeclarationNode) - def visit(self,node: cool.ClassDeclarationNode,scope): + @visitor.when(cool.ClassDeclarationNode) + def visit(self, node: cool.ClassDeclarationNode, scope): self.current_type = self.context.get_type(node.id.lex) type_node = self.register_type(node.id.lex) - type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] - type_node.methods = [(method.name, self.to_function_name(method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - - fun_declarations = (f for f in node.features if isinstance(f,cool.FuncDeclarationNode)) + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + fun_declarations = (f for f in node.features if isinstance( + f, cool.FuncDeclarationNode)) for feature in fun_declarations: - self.visit(feature,scope) + self.visit(feature, scope) self.current_type = None @visitor.when(cool.FuncDeclarationNode) - def visit(self,node: cool.FuncDeclarationNode,scope: Scope): + def visit(self, node: cool.FuncDeclarationNode, scope: Scope): fun_scope = Scope(parent=scope) self.current_method = self.current_type.get_method(node.id.lex) type_name = self.current_type.name - - self.current_function = self.register_function(self.to_function_name(node.id.lex, type_name)) + + self.current_function = self.register_function( + self.to_function_name(node.id.lex, type_name)) self_local = self.register_param(VariableInfo('self', None)) fun_scope.define_variable('self', self_local) for param_name, param_type in node.params: self.register_param(VariableInfo(param_name.lex, param_type.lex)) - body = self.visit(node.body,fun_scope) + body = self.visit(node.body, fun_scope) self.register_instruction(ReturnNode(body)) self.current_method = None @visitor.when(cool.AttrDeclarationNode) - def visit(self,node: cool.AttrDeclarationNode,scope): + def visit(self, node: cool.AttrDeclarationNode, scope): result = self.visit(node.expression, scope) if node.expression else 0 self_inst = scope.find_variable('self').name - self.register_instruction(SetAttribNode(self_inst, node.id.lex, result)) + self.register_instruction( + SetAttribNode(self_inst, node.id.lex, result)) @visitor.when(cool.AssignNode) - def visit(self,node: cool.AssignNode,scope): - expr = self.visit(node.expression,scope) + def visit(self, node: cool.AssignNode, scope): + expr = self.visit(node.expression, scope) attr_info = scope.find_variable(node.id.lex) if not attr_info: selfx = scope.find_variable('self').name @@ -112,7 +119,7 @@ def visit(self,node: cool.AssignNode,scope): return 0 @visitor.when(cool.NewNode) - def visit(self,node: cool.NewNode,scope): + def visit(self, node: cool.NewNode, scope): new_local = self.define_internal_local() typex = self.context.get_type(node.type.lex) self.register_instruction(AllocateNode(new_local, typex.name)) @@ -120,27 +127,29 @@ def visit(self,node: cool.NewNode,scope): return new_local @visitor.when(cool.IfThenElseNode) - def visit(self,node:cool.IfThenElseNode,scope): + def visit(self, node: cool.IfThenElseNode, scope): cond = self.visit(node.condition, scope) child_scope = Scope(parent=scope) true_label = LabelNode('TRUE') end_label = LabelNode('END') result = self.define_internal_local() - self.register_instruction(IfGotoNode(cond,self.to_label_name(true_label.label))) - + self.register_instruction(IfGotoNode( + cond, self.to_label_name(true_label.label))) + false_expr = self.visit(node.else_body, child_scope) - self.register_instruction(AssignNode(result,false_expr)) - self.register_instruction(GotoNode(self.to_label_name(end_label.label))) + self.register_instruction(AssignNode(result, false_expr)) + self.register_instruction( + GotoNode(self.to_label_name(end_label.label))) self.register_instruction(true_label) true_expr = self.visit(node.if_body, child_scope) - self.register_instruction(AssignNode(result,true_expr)) + self.register_instruction(AssignNode(result, true_expr)) self.register_instruction(end_label) return result - + @visitor.when(cool.WhileLoopNode) - def visit(self,node:cool.WhileLoopNode,scope): + def visit(self, node: cool.WhileLoopNode, scope): while_scope = Scope(parent=scope) start_label = LabelNode('START') continue_label = LabelNode('CONTINUE') @@ -148,7 +157,7 @@ def visit(self,node:cool.WhileLoopNode,scope): self.register_instruction(start_label) - cond = self.visit(node.condition,scope) + cond = self.visit(node.condition, scope) self.register_instruction(IfGotoNode(cond, continue_label.label)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) @@ -159,17 +168,17 @@ def visit(self,node:cool.WhileLoopNode,scope): return 0 @visitor.when(cool.CaseOfNode) - def visit(self,node: cool.CaseOfNode,scope): + def visit(self, node: cool.CaseOfNode, scope): expr = self.visit(node.expression, scope) result = self.define_internal_local() exptype = self.define_internal_local() end_label = LabelNode('END') - self.register_instruction(TypeOfNode(expr,exptype)) + self.register_instruction(TypeOfNode(expr, exptype)) - for i ,case in enumerate(node.branches): + for i, case in enumerate(node.branches): child_scope = Scope(parent=scope) - expr_n = self.visit(case,child_scope) - self.register_instruction(AssignNode(result,expr_n)) + expr_n = self.visit(case, child_scope) + self.register_instruction(AssignNode(result, expr_n)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(LabelNode(f'CASE_{i}')) self.register_instruction(end_label) @@ -177,81 +186,83 @@ def visit(self,node: cool.CaseOfNode,scope): return result @visitor.when(cool.LetInNode) - def visit(self,node: cool.LetInNode,scope: Scope): + def visit(self, node: cool.LetInNode, scope: Scope): let_scope = Scope(parent=scope) for let_id, let_type, let_expr in node.let_body: let_scope.define_variable(let_id.lex, let_type.lex) - self.visit(let_expr,let_scope) + self.visit(let_expr, let_scope) result = self.define_internal_local() - expr = self.visit(node.in_body,let_scope) - self.register_instruction(AssignNode(result,expr)) + expr = self.visit(node.in_body, let_scope) + self.register_instruction(AssignNode(result, expr)) return result @visitor.when(cool.BlockNode) - def visit(self,node: cool.BlockNode,scope): + def visit(self, node: cool.BlockNode, scope): result = self.define_internal_local() for expr in node.expressions: val = self.visit(expr, scope) - self.register_instruction(AssignNode(result,val)) + self.register_instruction(AssignNode(result, val)) return result @visitor.when(cool.FunctionCallNode) - def visit(self,node: cool.FunctionCallNode, scope): + def visit(self, node: cool.FunctionCallNode, scope): if not (node.type): - typex = self.context.get_type(node.obj.static_type.name).name - else: + typex = self.context.get_type(node.obj.static_type.name).name + else: typex = node.type.lex name = self.to_function_name(node.id.lex, typex) result = self.define_internal_local() rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) - rev_args = [ arg_value ] + rev_args + rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) obj = self.visit(node.obj, scope) self.register_instruction(ArgNode(obj)) self.register_instruction(StaticCallNode(name, result)) if name else \ - self.register_instruction(DynamicCallNode(typex, node.id.lex, result)) - + self.register_instruction( + DynamicCallNode(typex, node.id.lex, result)) + return result @visitor.when(cool.MemberCallNode) - def visit(self,node: cool.MemberCallNode, scope: Scope): + def visit(self, node: cool.MemberCallNode, scope: Scope): type_name = self.current_type.name result = self.define_internal_local() rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) - rev_args = [ arg_value ] + rev_args + rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name self.register_instruction(ArgNode(self_inst)) - self.register_instruction(DynamicCallNode(type_name, node.id.lex, result)) - + self.register_instruction( + DynamicCallNode(type_name, node.id.lex, result)) + return result @visitor.when(cool.PlusNode) - def visit(self, node:cool.PlusNode, scope): - return self.define_binary_node(node,scope,PlusNode) + def visit(self, node: cool.PlusNode, scope): + return self.define_binary_node(node, scope, PlusNode) @visitor.when(cool.MinusNode) - def visit(self, node:cool.MinusNode, scope): - return self.define_binary_node(node,scope,MinusNode) + def visit(self, node: cool.MinusNode, scope): + return self.define_binary_node(node, scope, MinusNode) @visitor.when(cool.StarNode) - def visit(self, node:cool.StarNode, scope): - return self.define_binary_node(node,scope,StarNode) + def visit(self, node: cool.StarNode, scope): + return self.define_binary_node(node, scope, StarNode) @visitor.when(cool.DivNode) - def visit(self, node:cool.DivNode, scope): - return self.define_binary_node(node,scope,DivNode) + def visit(self, node: cool.DivNode, scope): + return self.define_binary_node(node, scope, DivNode) @visitor.when(cool.LessNode) - def visit(self, node:cool.LessNode, scope): - return self.define_binary_node(node,scope,LessNode) + def visit(self, node: cool.LessNode, scope): + return self.define_binary_node(node, scope, LessNode) @visitor.when(cool.LessEqualNode) def visit(self, node: cool.LessEqualNode, scope): @@ -267,15 +278,15 @@ def visit(self, node: cool.EqualNode, scope): self.register_instruction(StringEqualNode(result, left, right)) else: self.register_instruction(EqualNode(result, left, right)) - return result + return result @visitor.when(cool.IsVoidNode) def visit(self, node: cool.IsVoidNode, scope): return self.define_unary_node(node, scope, IsVoidNode) - + @visitor.when(cool.NotNode) def visit(self, node: cool.NotNode, scope): - return self.define_unary_node(node,scope, NotNode) + return self.define_unary_node(node, scope, NotNode) @visitor.when(cool.ComplementNode) def visit(self, node: cool.ComplementNode, scope): @@ -287,28 +298,23 @@ def visit(self, node: cool.IdNode, scope: Scope): if not nvar: selfx = scope.find_variable('self').name nvar = self.define_internal_local() - self.register_instruction(GetAttribNode(nvar, selfx, node.token.lex)) + self.register_instruction( + GetAttribNode(nvar, selfx, node.token.lex)) else: nvar = nvar.name return nvar @visitor.when(cool.BoolNode) - def visit(self, node:cool.BoolNode, scope): + def visit(self, node: cool.BoolNode, scope): return 1 if node.token.lex else 0 @visitor.when(cool.IntegerNode) - def visit(self, node:cool.IntegerNode, scope): + def visit(self, node: cool.IntegerNode, scope): return int(node.token.lex) @visitor.when(cool.StringNode) - def visit(self, node:cool.StringNode, scope): + def visit(self, node: cool.StringNode, scope): string = self.register_data(node.token.lex) dest = self.define_internal_local() - self.register_instruction(LoadNode(dest,string.name)) + self.register_instruction(LoadNode(dest, string.name)) return dest - - - - - - \ No newline at end of file diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 9b83a03f..e1f7f971 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,237 +1,239 @@ from .cil_ast import * from ..cp import visitor -from .mips import * +from .mips import MipsCode as mips +from .mips import Registers as reg + class CIL_TO_MIPS: def __init__(self): - self.data_code = [] - self.mips_code = [] self.reg = Registers - self.code = MipsCode - - def visit_ArithNode(self, node: ArithmeticNode ): + self.code = [] + + def _write(self, line): + self.code.append(line) + + def visit_ArithNode(self, node: ArithmeticNode): # Setting self.visit(node.left) self.visit(node.right) - self.mips_code.append("lw $t0, 8($sp)") - self.mips_code.append("lw $t1, 4($sp)") + self._write(mips.lw(reg.t0, 8, reg.sp)) + self._write(mips.lw(reg.t0, 4, reg.sp)) - self.mips_code.append("lw $a0, 8($t0)") - self.mips_code.append("lw $a1, 8($t1)") + self._write(mips.lw(reg.a0, 8, reg.sp)) + self._write(mips.lw(reg.a1, 8, reg.sp)) - self.mips_code.append("addiu $sp, $sp, 8") + self._write(mips.addiu(reg.sp, reg.sp, 8)) # Operation if isinstance(node, PlusNode): - self.mips_code.append("add $a1, $a0, $a1") + self._write(mips.add(reg.a1, reg.a0, reg.a1)) elif isinstance(node, MinusNode): - self.mips_code.append("sub $a1, $a0, $a1") + self._write(mips.sub(reg.a1, reg.a0, reg.a1)) elif isinstance(node, StarNode): - self.mips_code.append("mult $a0, $a1") - self.mips_code.append("mflo $a1") + self._write(mips.mult(reg.a0, reg.a1)) elif isinstance(node, DivNode): - self.mips_code.append("la $t0, zero_error") - self.mips_code.append("sw $t0, ($sp)") - self.mips_code.append("subu $sp, $sp, 4") - self.mips_code.append("beqz $a1, .raise") - self.mips_code.append("addu $sp, $sp, 4") - self.mips_code.append("div $a0, $a1") - self.mips_code.append("mflo $a1") + self._write("la $t0, zero_error") + self._write("sw $t0, ($sp)") + self._write("subu $sp, $sp, 4") + self._write(mips.beqz(reg.a1, )) + self._write("beqz $a1, .raise") + self._write(mips.addiu(reg.sp, reg.sp, 4)) + self._write(mips.div(reg.a0, reg.a1)) + self._write(mips.mflo(reg.a1)) elif isinstance(node, LessNode): - self.mips_code.append("slt $a1, $a0, $a1") + self._write("slt $a1, $a0, $a1") elif isinstance(node, LessEqNode): - self.mips_code.append("sle $a1, $a0, $a1") + self._write("sle $a1, $a0, $a1") - # Return - self.mips_code.append("li $v0, 9") - self.mips_code.append("li $a0, 12") - self.mips_code.append("syscall") + # Return + self._write("li $v0, 9") + self._write("li $a0, 12") + self._write("syscall") if isinstance(node, EqualNode) or isinstance(node, LessNode): - self.mips_code.append("la $t0, Bool") + self._write("la $t0, Bool") else: - self.mips_code.append("la $t0, Int") - - self.mips_code.append("sw $t0, ($v0)") + self._write("la $t0, Int") - self.mips_code.append("li $t0, 1") - self.mips_code.append("sw $t0, 4($v0)") + self._write("sw $t0, ($v0)") - self.mips_code.append("sw $a1, 8($v0)") - self.mips_code.append("sw $v0, ($sp)") + self._write("li $t0, 1") + self._write("sw $t0, 4($v0)") - self.mips_code.append("subu $sp, $sp, 4") + self._write("sw $a1, 8($v0)") + self._write("sw $v0, ($sp)") + + self._write("subu $sp, $sp, 4") @visitor.on('node') - def visit(self,node): + def visit(self, node): pass @visitor.when(ProgramNode) - def visit(self,node: ProgramNode): - + def visit(self, node: ProgramNode): + for typex in node.dottypes: self.visit(typex) - + for data in node.dotdata: self.visit(data) - + for code in node.dotcode: self.visit(code) - + return self.data_code, self.code @visitor.when(TypeNode) - def visit(self,node): - + def visit(self, node): @visitor.when(FunctionNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(DataNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ParamNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(LocalNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(GetAttribNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(SetAttribNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(AssignNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ComplementNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(NotNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(PlusNode) - def visit(self,node : PlusNode): + def visit(self, node: PlusNode): self.visit_ArithNode(node) @visitor.when(MinusNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(StarNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(DivNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(EqualNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(LessEqNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(LessNode) - def visit(self,node): + def visit(self, node): self.visit_ArithNode(node) @visitor.when(AllocateNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(TypeOfNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(LabelNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(GotoNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(IfGotoNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(StaticCallNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(DynamicCallNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ArgNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ErrorNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(CopyNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(TypeNameNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(LengthNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ConcatNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(StringEqualNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ConcatNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(LoadNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(SubstringNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ToStrNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ToIntNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ReadNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(PrintNode) - def visit(self,node): + def visit(self, node): pass @visitor.when(ReturnNode) - def visit(self,node): + def visit(self, node): pass From a5f8783569ccbc605b2ae9d82661a1a8825fac8c Mon Sep 17 00:00:00 2001 From: stdevlag Date: Sat, 28 Nov 2020 16:31:34 -0500 Subject: [PATCH 063/191] mips code util MipsCode --- src/engine/codegen/mips.py | 278 ++++++++++++++++++++++++++++++++++++- 1 file changed, 271 insertions(+), 7 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 0e0b0394..6d4c06d6 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -1,5 +1,6 @@ from enum import Enum + class Registers: zero = '$zero' # Constant 0 at = '$at' # Reserved for assembler @@ -41,6 +42,8 @@ class ArithmOperations(Enum): Mul = 3 Div = 4 +# class MipsLabel: + class MipsCode: def __init__(self): @@ -53,7 +56,7 @@ def print_str(self, _str): ''' code = [ 'li $v0, 4 # system call code for print_str', - f'la $a0, {_str} # address of string to print' , + f'la $a0, {_str} # address of string to print', 'syscall # print the string', ] return code @@ -65,27 +68,288 @@ def print_int(self, _int): ''' code = [ 'li $v0, 1 # system call code for print_int', - f'la $a0, {_int} # address of string to print' , + f'la $a0, {_int} # address of string to print', 'syscall # print the string', ] return code + # Arithmetic and Logical Operations def abs(self, rdest, rsrc): ''' Absolute Value ''' return f'abs {rdest}, {rsrc}' - def lw(self, reg, memory, offset): - return f'lw {reg},{offset}({reg})' - def addiu(self, rdest, rsrc, constant): ''' Addition Immediate (without overflow) ''' - return f'addiu {rdest}, {offset}, {constant}' + return f'addiu {rdest}, {rsrc}, {constant}' + + def addi(self, rdest, rsrc, constant): + ''' + Addition Immediate (with overflow) + ''' + return f'addi {rdest}, {rsrc}, {constant}' def add(self, rdest, rsrc, src): ''' - + Addition (with overflow) + ''' + return f'add {rdest}, {rsrc}, {src}' + + def addu(self, rdest, rsrc, src): + ''' + Addition (without overflow) + ''' + return f'addu {rdest}, {rsrc}, {src}' + + def and_(self, rdest, rsrc1, rsrc2): + ''' + AND + ''' + return f'and {rdest}, {rsrc1}, {rsrc2}' + + def andi(self, rdest, rsrc, constant): + ''' + ANDI Inmediate + ''' + return f'andi {rdest}, {rsrc}, {constant}' + + def div(self, rdest_src, rsrc1, rsrc2=None): + ''' + Divide (signed) + ''' + if rsrc2 is None: + return f'div {rdest_src}, {rsrc1}' + else: + return f'div {rdest_src}, {rsrc1}, {rsrc2}' + + def divu(self, rdest_src, rsrc1, rsrc2=None): + ''' + Divide (unsigned) + ''' + if rsrc2 is None: + return f'divu {rdest_src}, {rsrc1}' + else: + return f'divu {rdest_src}, {rsrc1}, {rsrc2}' + + def mult(self, rdest, rsrc1): + ''' + Multiply + ''' + return f'mult {rdest}, {rsrc1}' + + def neg(self, rdest, rsrc): + ''' + Negate Value (with overflow) + ''' + return f'neg {rdest}, {rsrc}' + + def negu(self, rdest, rsrc): + ''' + Negate Value (without overflow) + ''' + return f'negu {rdest}, {rsrc}' + + def not_(self, rdest, rsrc): + ''' + Not ''' + return 'or {rdest}, {rsrc}' + + def or_(self, rdest, rsrc1, src2): + ''' + Or + ''' + return 'or {rdest}, {rsrc1}, {rsrc2}' + + def nor(self, rdest, rsrc1, src2): + ''' + Nor + ''' + return 'nor {rdest}, {rsrc1}, {rsrc2}' + + def ori(self, rdest, rsrc1, constant): + ''' + Or Immediate + ''' + return 'ori {rdest}, {rsrc1}, {constant}' + + def rem(self, rdest, rsrc1, src2): + ''' + Remainder + ''' + return f'rem {rdest}, {rsrc1}, {src2}' + + def remu(self, rdest, rsrc1, src2): + ''' + Unsigned Remainder + ''' + return f'remu {rdest}, {rsrc1}, {src2}' + + def sub(self, rdest, rsrc1, src2): + ''' + Substract (with overflow) + ''' + return f'sub {rdest}, {rsrc1}, {src2}' + + def subu(self, rdest, rsrc1, src2): + ''' + Substract (without overflow) + ''' + return f'subu {rdest}, {rsrc1}, {src2}' + + # Constant Manipulating + def li(self, rdest, constant): + ''' + Load Immediate + ''' + return f'li {rdest}, {constant}' + + # Comparison Instructions + def seq(self, rdest, rsrc1, src2): + ''' + Set Equal + ''' + return f'seq {rdest}, {rsrc1}, {src2}' + + def sge(self, rdest, rsrc1, src2): + ''' + Set Greater Than Equal er Than Equal Unsigned + ''' + return f'sge {rdest}, {rsrc1}, {src2}' + + def sle(self, rdest, rsrc1, src2): + ''' + Set Less Than Equal Than Equal Unsigned + ''' + return f'sle {rdest}, {rsrc1}, {src2}' + + def slt(self, rdest, rsrc1, src2): + ''' + Set Less Than + ''' + return f'slt {rdest}, {rsrc1}, {src2}' + # Branch and Jump + + def b(self, label): + ''' + Branch instruction + ''' + return f'b {label}' + + def beq(self, rsrc1, src2, label): + ''' + Branch on Equal + ''' + return f'beq {rsrc1}, {src2}, {label}' + + def beqz(self, rsrc1, src2, label): + ''' + Branch on Equal Zero + ''' + return f'beqz {rsrc1}, {src2}, {label}' + + def bne(self, rsrc1, src2, label): + ''' + Branch on Not Equal Zero + ''' + return f'bne {rsrc1}, {src2}, {label}' + + def j(self, label): + ''' + Jump + ''' + return f'j {label}' + + def jal(self, label): + ''' + Jump and Link + ''' + return f'jal {label}' + + def jr(self, rsrc): + ''' + Jump Register + ''' + return f'jr {rsrc}' + + # Load Instructions + def la(self, rdest, address): + ''' + Load Address + ''' + return f'la {rdest}, {address}' + + def lb(self, rdest, address): + ''' + Load Byte + ''' + return f'la {rdest}, {address}' + + def lw(self, reg, memory, offset): + ''' + Load Word + ''' + return f'lw {reg}, {offset}({reg})' + + def ld(self, rdest, address): + ''' + Load Double-Word + ''' + return f'la {rdest}, {address}' + + # Store Instructions + def sb(self, rsrc, address): + ''' + Store Byte + ''' + return f'sb {rsrc}, {address}' + + def sw(self, rsrc, address): + ''' + Store Word + ''' + return f'sw {rsrc}, {address}' + + def sd(self, rsrc, address): + ''' + Store Double-Word + ''' + return f'sd {rsrc}, {address}' + + # Data Movement Instructions + def move(self, rdest, rsrc): + ''' + Move + ''' + return f'move {rdest}, {rsrc}' + + def mfhi(self, rdest): + ''' + Move from `hi` + ''' + return f'mfhi {rdest}' + + def mflo(self, rdest): + ''' + Move from `lo` + ''' + return f'mflo {rdest}' + + def syscall(self): + ''' + Syscall + ''' + return 'syscall' + + + + + + + + + + From f9480ce1b6225dddaca5e26a3c5574c3c2e20a60 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sat, 28 Nov 2020 16:54:38 -0500 Subject: [PATCH 064/191] arithmetic nodes done --- src/engine/codegen/to_mips.py | 96 ++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index e1f7f971..36b02a2a 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -2,6 +2,7 @@ from ..cp import visitor from .mips import MipsCode as mips from .mips import Registers as reg +from .mips import MipsLabel as label class CIL_TO_MIPS: @@ -18,11 +19,11 @@ def visit_ArithNode(self, node: ArithmeticNode): self.visit(node.left) self.visit(node.right) - self._write(mips.lw(reg.t0, 8, reg.sp)) - self._write(mips.lw(reg.t0, 4, reg.sp)) + self._write(mips.lw(reg.t0, reg.sp, offset=8)) + self._write(mips.lw(reg.t0, reg.sp, offset=4)) - self._write(mips.lw(reg.a0, 8, reg.sp)) - self._write(mips.lw(reg.a1, 8, reg.sp)) + self._write(mips.lw(reg.a0, reg.sp, offset=8)) + self._write(mips.lw(reg.a1, reg.sp, offset=8)) self._write(mips.addiu(reg.sp, reg.sp, 8)) # Operation @@ -33,37 +34,37 @@ def visit_ArithNode(self, node: ArithmeticNode): elif isinstance(node, StarNode): self._write(mips.mult(reg.a0, reg.a1)) elif isinstance(node, DivNode): - self._write("la $t0, zero_error") - self._write("sw $t0, ($sp)") - self._write("subu $sp, $sp, 4") - self._write(mips.beqz(reg.a1, )) - self._write("beqz $a1, .raise") + self._write(mips.la(reg.t0, label.zero_error)) + self._write(mips.sw(reg.t0, reg.sp)) + self._write(mips.subiu(reg.sp, reg.sp, 4)) + self._write(mips.beqz(reg.a1, label.raise_)) self._write(mips.addiu(reg.sp, reg.sp, 4)) self._write(mips.div(reg.a0, reg.a1)) self._write(mips.mflo(reg.a1)) elif isinstance(node, LessNode): - self._write("slt $a1, $a0, $a1") + self._write(mips.slt(reg.a1, reg.a0, reg.a1)) elif isinstance(node, LessEqNode): - self._write("sle $a1, $a0, $a1") + self._write(mips.sle(reg.a1, reg.a0, reg.a1)) # Return - self._write("li $v0, 9") - self._write("li $a0, 12") - self._write("syscall") - if isinstance(node, EqualNode) or isinstance(node, LessNode): - self._write("la $t0, Bool") + self._write(mips.li(reg.v0, 9)) + self._write(mips.li(reg.a0, 12)) + self._write(mips.syscall) + + if isinstance(node, EqualNode) or isinstance(node, LessNode) or isinstance(node, LessEqNode): + self._write(mips.la(reg.t0, 'Bool')) else: - self._write("la $t0, Int") + self._write(mips.la(reg.t0, 'Int')) - self._write("sw $t0, ($v0)") + self._write(mips.sw(reg.t0, reg.v0)) - self._write("li $t0, 1") - self._write("sw $t0, 4($v0)") + self._write(mips.li(reg.t0, 1)) + self._write(mips.sw(reg.t0, reg.v0, offset=4)) - self._write("sw $a1, 8($v0)") - self._write("sw $v0, ($sp)") + self._write(mips.sw(reg.a1, reg.v0, offset=8)) + self._write(mips.sw(reg.v0, reg.sp)) - self._write("subu $sp, $sp, 4") + self._write(mips.subiu(reg.sp, reg.sp, 4)) @visitor.on('node') def visit(self, node): @@ -72,9 +73,6 @@ def visit(self, node): @visitor.when(ProgramNode) def visit(self, node: ProgramNode): - for typex in node.dottypes: - self.visit(typex) - for data in node.dotdata: self.visit(data) @@ -91,8 +89,9 @@ def visit(self, node): pass @visitor.when(DataNode) - def visit(self, node): - pass + def visit(self, node: DataNode): + self._write('.data') + self._write() @visitor.when(ParamNode) def visit(self, node): @@ -115,39 +114,56 @@ def visit(self, node): pass @visitor.when(ComplementNode) - def visit(self, node): - pass + def visit(self, node: ComplementNode): + self.visit(node.expression) - @visitor.when(NotNode) - def visit(self, node): - pass + self._write(mips.lw(reg.t0, reg.sp, offset=4)) + + self._write(mips.lw(reg.a0, reg.sp, offset=8)) + + self._write(mips.nor(reg.a1, reg.a0)) + + self._write(mips.li(reg.v0, 9)) + self._write(mips.li(reg.a0, 12)) + self._write(mips.syscall) + + self._write(mips.la(reg.t0, 'Int')) + + self._write(mips.sw(reg.t0, reg.v0)) + self._write(mips.li(reg.t0, 1)) + self._write(mips.sw(reg.t0, reg.v0, offset=4)) + + self._write(mips.sw(reg.a1, reg.v0, offset=8)) + self._write(mips.sw(reg.v0, reg.sp)) + + self._write(mips.subiu(reg.sp, reg.sp, 4)) @visitor.when(PlusNode) def visit(self, node: PlusNode): self.visit_ArithNode(node) @visitor.when(MinusNode) - def visit(self, node): + def visit(self, node: MinusNode): self.visit_ArithNode(node) @visitor.when(StarNode) - def visit(self, node): + def visit(self, node: StarNode): self.visit_ArithNode(node) @visitor.when(DivNode) - def visit(self, node): + def visit(self, node: DivNode): self.visit_ArithNode(node) @visitor.when(EqualNode) - def visit(self, node): + def visit(self, node: EqualNode): self.visit_ArithNode(node) @visitor.when(LessEqNode) - def visit(self, node): + def visit(self, node: LessEqNode): self.visit_ArithNode(node) @visitor.when(LessNode) - def visit(self, node): + def visit(self, node: LessNode): self.visit_ArithNode(node) @visitor.when(AllocateNode) @@ -167,7 +183,7 @@ def visit(self, node): pass @visitor.when(IfGotoNode) - def visit(self, node): + def visit(self, node: IfGotoNode): pass @visitor.when(StaticCallNode) From 3cb643f2846bcb0320439db9750c59200f61f12a Mon Sep 17 00:00:00 2001 From: thenai310 Date: Sun, 29 Nov 2020 15:12:16 -0500 Subject: [PATCH 065/191] worked on mips visitor, some nodes not implemented --- src/engine/codegen/mips.py | 229 +++++++++++++++++---------- src/engine/codegen/to_mips.py | 283 ++++++++++++++++++++-------------- 2 files changed, 317 insertions(+), 195 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 8bbd0a05..da8a49ae 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -42,241 +42,322 @@ class ArithmOperations(Enum): Mul = 3 Div = 4 + # class MipsLabel: +# word = ".word" +# half = ".half" +# byte = ".byte" +# ascii_ = ".ascii" +# asciiz = ".asciiz" +# space = ".space" +# aling = ".align" +# text = ".text" +# data = ".data" + + +Reg = Registers + class MipsCode: def __init__(self): - pass + self.dotdata = [] + self.dotcode = [] # Data Segmente + # Meta Functions + + def _write(self, line): + self.dotcode.append(line) + + def _write_data(self, line): + self.dotdata.append(line) + + def data_label(self, lname): + self._write_data(f'{lname}') + + def asciiz(self, string): + self._write_data(f'.asciiz "{string}"') + + def push(self, register: Register): + self.addi(Register.sp, Register.sp, -8) + self.store_memory(register, self.offset(Register.sp)) + + def pop(self, register: Register): + """ + First, load from to address `0($sp)` + and then write `addi $sp , $sp , 8` + to restore the stack pointer + """ + self.load_memory(register, self.offset(Reg.sp)) + self.addi(Reg.sp, Reg.sp, 8) + + def load_memory(self, dst: Register, address: str): + """ + Load from a specific address a 32 bits register + """ + self.lw(Reg.t8, address) + self.sll(Reg.t8, Reg.t8, 16) + self.la(Reg.t7, address) + self.addi(Reg.t7, Reg.t7, 4) + self.lw(Reg.t9, self.offset(Reg.t7)) + self.or_(dst, Reg.t8, Reg.t9) + + def store_memory(self, src: Registers, address: str): + """ + Write to a specific address a 32 bits register + """ + self.la(Reg.t8, address) + + self.srl(Reg.t9, src, 16) + + self.sw(Reg.t9, self.offset(Reg.t8)) # store high bits + self.sw(src, self.offset(Reg.t8, 4)) # store low bits + + # System Calls + + def syscall(self, code: int): + self.li(Registers.v0, code) + self._write('syscall') + + def offset(self, r: Register, offset: int = 0): + return f"{offset}({r})" + + def comment(self, text: str): + self._write(f"# {text}") + + def label(self, name: str): + self._write(f"{name.upper()}:") - # IO def print_str(self, _str): - ''' - $v0 - $a0 - ''' - code = [ - 'li $v0, 4 # system call code for print_str', - f'la $a0, {_str} # address of string to print', - 'syscall # print the string', - ] - return code + return self.syscall(4) def print_int(self, _int): - ''' - $v0 - $a0 - ''' - code = [ - 'li $v0, 1 # system call code for print_int', - f'la $a0, {_int} # address of string to print', - 'syscall # print the string', - ] - return code + return self.syscall(1) + + def read_int(self): + return self.syscall(5) + + def read_string(self): + return self.syscall(8) + + def sbrk(self): + return self.syscall(9) + + def exit(self): + return self.syscall(10) # Arithmetic and Logical Operations def abs(self, rdest, rsrc): ''' Absolute Value ''' - return f'abs {rdest}, {rsrc}' + self._write(f'abs {rdest}, {rsrc}') def addiu(self, rdest, rsrc, constant): ''' Addition Immediate (without overflow) ''' - return f'addiu {rdest}, {rsrc}, {constant}' + self._write(f'addiu {rdest}, {rsrc}, {constant}') def addi(self, rdest, rsrc, constant): ''' Addition Immediate (with overflow) ''' - return f'addi {rdest}, {rsrc}, {constant}' + self._write(f'addi {rdest}, {rsrc}, {constant}') def add(self, rdest, rsrc, src): ''' Addition (with overflow) ''' - return f'add {rdest}, {rsrc}, {src}' + self._write(f'add {rdest}, {rsrc}, {src}') def addu(self, rdest, rsrc, src): ''' Addition (without overflow) ''' - return f'addu {rdest}, {rsrc}, {src}' + self._write(f'addu {rdest}, {rsrc}, {src}') def and_(self, rdest, rsrc1, rsrc2): ''' AND ''' - return f'and {rdest}, {rsrc1}, {rsrc2}' + self._write(f'and {rdest}, {rsrc1}, {rsrc2}') def andi(self, rdest, rsrc, constant): ''' ANDI Inmediate ''' - return f'andi {rdest}, {rsrc}, {constant}' + self._write(f'andi {rdest}, {rsrc}, {constant}') def div(self, rdest_src, rsrc1, rsrc2=None): ''' Divide (signed) ''' if rsrc2 is None: - return f'div {rdest_src}, {rsrc1}' + self._write(f'div {rdest_src}, {rsrc1}') else: - return f'div {rdest_src}, {rsrc1}, {rsrc2}' + self._write(f'div {rdest_src}, {rsrc1}, {rsrc2}') def divu(self, rdest_src, rsrc1, rsrc2=None): ''' Divide (unsigned) ''' if rsrc2 is None: - return f'divu {rdest_src}, {rsrc1}' + self._write(f'divu {rdest_src}, {rsrc1}') else: - return f'divu {rdest_src}, {rsrc1}, {rsrc2}' + self._write(f'divu {rdest_src}, {rsrc1}, {rsrc2}') def mult(self, rdest, rsrc1): ''' Multiply ''' - return f'mult {rdest}, {rsrc1}' + self._write(f'mult {rdest}, {rsrc1}') def neg(self, rdest, rsrc): ''' Negate Value (with overflow) ''' - return f'neg {rdest}, {rsrc}' + self._write(f'neg {rdest}, {rsrc}') def negu(self, rdest, rsrc): ''' Negate Value (without overflow) ''' - return f'negu {rdest}, {rsrc}' + self._write(f'negu {rdest}, {rsrc}') def not_(self, rdest, rsrc): ''' Not ''' - return 'or {rdest}, {rsrc}' + self._write(f'or {rdest}, {rsrc}') def or_(self, rdest, rsrc1, src2): ''' Or ''' - return 'or {rdest}, {rsrc1}, {rsrc2}' + self._write(f'or {rdest}, {rsrc1}, {rsrc2}') def nor(self, rdest, rsrc1, src2): ''' Nor ''' - return 'nor {rdest}, {rsrc1}, {rsrc2}' + self._write(f'nor {rdest}, {rsrc1}, {rsrc2}') def ori(self, rdest, rsrc1, constant): ''' Or Immediate ''' - return 'ori {rdest}, {rsrc1}, {constant}' + self._write(f'ori {rdest}, {rsrc1}, {constant}') def rem(self, rdest, rsrc1, src2): ''' Remainder ''' - return f'rem {rdest}, {rsrc1}, {src2}' + self._write(f'rem {rdest}, {rsrc1}, {src2}') def remu(self, rdest, rsrc1, src2): ''' Unsigned Remainder ''' - return f'remu {rdest}, {rsrc1}, {src2}' + self._write(f'remu {rdest}, {rsrc1}, {src2}') def sub(self, rdest, rsrc1, src2): ''' Substract (with overflow) ''' - return f'sub {rdest}, {rsrc1}, {src2}' + self._write(f'sub {rdest}, {rsrc1}, {src2}') def subu(self, rdest, rsrc1, src2): ''' Substract (without overflow) ''' - return f'subu {rdest}, {rsrc1}, {src2}' + self._write(f'subu {rdest}, {rsrc1}, {src2}') + + def sll(self, dst, rl, value: int): + self._write(f"sll {dst}, {rl}, {value}") # Constant Manipulating def li(self, rdest, constant): ''' Load Immediate ''' - return f'li {rdest}, {constant}' + self._write(f'li {rdest}, {int(constant)}') # Comparison Instructions def seq(self, rdest, rsrc1, src2): ''' Set Equal ''' - return f'seq {rdest}, {rsrc1}, {src2}' + self._write(f'seq {rdest}, {rsrc1}, {src2}') def sge(self, rdest, rsrc1, src2): ''' Set Greater Than Equal er Than Equal Unsigned ''' - return f'sge {rdest}, {rsrc1}, {src2}' + self._write(f'sge {rdest}, {rsrc1}, {src2}') def sle(self, rdest, rsrc1, src2): ''' Set Less Than Equal Than Equal Unsigned ''' - return f'sle {rdest}, {rsrc1}, {src2}' + self._write(f'sle {rdest}, {rsrc1}, {src2}') def slt(self, rdest, rsrc1, src2): ''' Set Less Than ''' - return f'slt {rdest}, {rsrc1}, {src2}' + self._write(f'slt {rdest}, {rsrc1}, {src2}') + + def slti(self, rdest, rsrc1, value): + ''' + Set Less Than Immediate + ''' + self._write(f'slti {rdest}, {rsrc1}, {value}') + # Branch and Jump def b(self, label): ''' Branch instruction ''' - return f'b {label}' + self._write(f'b {label}') def beq(self, rsrc1, src2, label): ''' Branch on Equal ''' - return f'beq {rsrc1}, {src2}, {label}' + self._write(f'beq {rsrc1}, {src2}, {label}') def beqz(self, rsrc1, src2, label): ''' Branch on Equal Zero ''' - return f'beqz {rsrc1}, {src2}, {label}' + self._write(f'beqz {rsrc1}, {src2}, {label}') def bne(self, rsrc1, src2, label): ''' Branch on Not Equal Zero ''' - return f'bne {rsrc1}, {src2}, {label}' + self._write(f'bne {rsrc1}, {src2}, {label}') def j(self, label): ''' Jump ''' - return f'j {label}' + self._write(f'j {label}') def jal(self, label): ''' Jump and Link ''' - return f'jal {label}' + self._write(f'jal {label}') def jr(self, rsrc): ''' Jump Register ''' - return f'jr {rsrc}' + self._write(f'jr {rsrc}') # Load Instructions def la(self, rdest, address): @@ -289,70 +370,54 @@ def lb(self, rdest, address): ''' Load Byte ''' - return f'la {rdest}, {address}' + self._write(f'lb {rdest}, {address}') - def lw(self, reg, memory, offset): + def lw(self, reg, address): ''' Load Word ''' - return f'lw {reg}, {offset}({reg})' + self._write(f'lw {reg}, {address}') def ld(self, rdest, address): ''' Load Double-Word ''' - return f'la {rdest}, {address}' + self._write(f'la {rdest}, {address}') # Store Instructions def sb(self, rsrc, address): ''' Store Byte ''' - return f'sb {rsrc}, {address}' + self._write(f'sb {rsrc}, {address}') def sw(self, rsrc, address): ''' Store Word ''' - return f'sw {rsrc}, {address}' + self._write(f'sw {rsrc}, {address}') def sd(self, rsrc, address): ''' Store Double-Word ''' - return f'sd {rsrc}, {address}' + self._write(f'sd {rsrc}, {address}') # Data Movement Instructions def move(self, rdest, rsrc): ''' Move ''' - return f'move {rdest}, {rsrc}' + self._write(f'move {rdest}, {rsrc}') def mfhi(self, rdest): ''' Move from `hi` ''' - return f'mfhi {rdest}' + self._write(f'mfhi {rdest}') def mflo(self, rdest): ''' Move from `lo` ''' - return f'mflo {rdest}' - - def syscall(self): - ''' - Syscall - ''' - return 'syscall' - - - - - - - - - - + self._write(f'mflo {rdest}') diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 36b02a2a..ac12cc94 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,70 +1,55 @@ from .cil_ast import * from ..cp import visitor -from .mips import MipsCode as mips +from .mips import MipsCode from .mips import Registers as reg -from .mips import MipsLabel as label class CIL_TO_MIPS: - def __init__(self): - self.reg = Registers - self.code = [] - - def _write(self, line): - self.code.append(line) - - def visit_ArithNode(self, node: ArithmeticNode): - # Setting - self.visit(node.left) - self.visit(node.right) - - self._write(mips.lw(reg.t0, reg.sp, offset=8)) - self._write(mips.lw(reg.t0, reg.sp, offset=4)) - - self._write(mips.lw(reg.a0, reg.sp, offset=8)) - self._write(mips.lw(reg.a1, reg.sp, offset=8)) - - self._write(mips.addiu(reg.sp, reg.sp, 8)) - # Operation - if isinstance(node, PlusNode): - self._write(mips.add(reg.a1, reg.a0, reg.a1)) - elif isinstance(node, MinusNode): - self._write(mips.sub(reg.a1, reg.a0, reg.a1)) - elif isinstance(node, StarNode): - self._write(mips.mult(reg.a0, reg.a1)) - elif isinstance(node, DivNode): - self._write(mips.la(reg.t0, label.zero_error)) - self._write(mips.sw(reg.t0, reg.sp)) - self._write(mips.subiu(reg.sp, reg.sp, 4)) - self._write(mips.beqz(reg.a1, label.raise_)) - self._write(mips.addiu(reg.sp, reg.sp, 4)) - self._write(mips.div(reg.a0, reg.a1)) - self._write(mips.mflo(reg.a1)) - elif isinstance(node, LessNode): - self._write(mips.slt(reg.a1, reg.a0, reg.a1)) - elif isinstance(node, LessEqNode): - self._write(mips.sle(reg.a1, reg.a0, reg.a1)) - - # Return - self._write(mips.li(reg.v0, 9)) - self._write(mips.li(reg.a0, 12)) - self._write(mips.syscall) - - if isinstance(node, EqualNode) or isinstance(node, LessNode) or isinstance(node, LessEqNode): - self._write(mips.la(reg.t0, 'Bool')) + def __init__(self, data_size=8): + self.arguments = {} + self.local_vars = {} + self.data_size = data_size + self.registers_to_save = [reg.ra] + self.label_count = 0 + self.mips = MipsCode() + + def get_label(self): + return f"mip_label_{self.label_count}" + self.label_count += 1 + + def load_memory(self, dst, arg: str): + if arg in self.arguments or arg in self.local_vars: + offset = ( + self.arguments[arg] + 1 + if arg in self.arguments + else -self.local_vars[arg] + ) * self.data_size + + self.mips.load_memory(dst, self.mips.offset(reg.fp, offset)) else: - self._write(mips.la(reg.t0, 'Int')) + raise Exception( + f"load_memory: The direction {arg} isn't an address") - self._write(mips.sw(reg.t0, reg.v0)) + def store_memory(self, dst, arg: str): + if arg in self.local_vars: + offset = -self.local_vars[arg] * self.data_size + self.mips.store_memory(dst, self.mips.offset(reg.fp, offset)) + else: + raise Exception( + f"store_memory: The direction {arg} isn't an address") - self._write(mips.li(reg.t0, 1)) - self._write(mips.sw(reg.t0, reg.v0, offset=4)) + def load_arithmetic(self, node: ArithmeticNode): + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) - self._write(mips.sw(reg.a1, reg.v0, offset=8)) - self._write(mips.sw(reg.v0, reg.sp)) + def store_registers(self): + for reg in self.registers_to_save: + self.mips.push(reg) - self._write(mips.subiu(reg.sp, reg.sp, 4)) + def load_registers(self): + for reg in reversed(self.registers_to_save): + self.mips.pop(reg) @visitor.on('node') def visit(self, node): @@ -73,33 +58,68 @@ def visit(self, node): @visitor.when(ProgramNode) def visit(self, node: ProgramNode): + # self.types = node.dottypes + # self.build_types(self.types) + for data in node.dotdata: self.visit(data) + self.mips.label('main') + self.mips.jal('entry') + self.mips.exit() + for code in node.dotcode: self.visit(code) - return self.data_code, self.code - @visitor.when(TypeNode) def visit(self, node): + pass @visitor.when(FunctionNode) - def visit(self, node): - pass + def visit(self, node: FunctionNode): + self.mips.label(node.name) + + self.mips.comment("Set stack frame") + self.mips.push(reg.fp) + self.mips.move(reg.fp, reg.sp) + + self.arguments = dict() + + for idx, param in enumerate(node.params): + self.visit(param, index=idx) + + self.mips.comment("Allocate memory for Local variables") + for idx, local in enumerate(node.localvars): + self.visit(local, index=idx) + + self.store_registers() + self.mips.comment("Generating body code") + for instruction in node.instructions: + self.visit(instruction) + + self.arguments = None + self.load_registers() + + self.mips.comment("Clean stack variable space") + self.mips.addi(reg.sp, reg.sp, len(node.localvars) * self.data_size) + self.mips.comment("Return") + self.mips.pop(reg.fp) + self.mips.jr(reg.ra) @visitor.when(DataNode) def visit(self, node: DataNode): - self._write('.data') - self._write() + self.mips.data_label(node.name) + self.mips.asciiz(node.value) @visitor.when(ParamNode) - def visit(self, node): - pass + def visit(self, node: ParamNode, index=0): + self.arguments[node.name] = index @visitor.when(LocalNode) - def visit(self, node): - pass + def visit(self, node: LocalNode, index=0): + self.mips.push(reg.zero) + if node.name in self.local_vars: + self.local_vars[node.name] = index @visitor.when(GetAttribNode) def visit(self, node): @@ -110,61 +130,81 @@ def visit(self, node): pass @visitor.when(AssignNode) - def visit(self, node): - pass + def visit(self, node: AssignNode): + self.mips.comment("AssignNode") + self.load_memory(reg.t0, node.source) + self.store_memory(reg.t0, node.dest) @visitor.when(ComplementNode) def visit(self, node: ComplementNode): - self.visit(node.expression) - - self._write(mips.lw(reg.t0, reg.sp, offset=4)) - - self._write(mips.lw(reg.a0, reg.sp, offset=8)) - - self._write(mips.nor(reg.a1, reg.a0)) - - self._write(mips.li(reg.v0, 9)) - self._write(mips.li(reg.a0, 12)) - self._write(mips.syscall) - - self._write(mips.la(reg.t0, 'Int')) - - self._write(mips.sw(reg.t0, reg.v0)) - self._write(mips.li(reg.t0, 1)) - self._write(mips.sw(reg.t0, reg.v0, offset=4)) - - self._write(mips.sw(reg.a1, reg.v0, offset=8)) - self._write(mips.sw(reg.v0, reg.sp)) - - self._write(mips.subiu(reg.sp, reg.sp, 4)) + self.mips.comment("ComplementNode") + self.load_memory(reg.t0, node.body) + self.mips.nor(reg.t1, reg.t0, reg.t0) + self.store_memory(reg.t1, node.dest) @visitor.when(PlusNode) def visit(self, node: PlusNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.add(reg.t2, reg.t0, reg.t1) + self.store_memory(reg.t2, node.dest) @visitor.when(MinusNode) def visit(self, node: MinusNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.sub(reg.t2, reg.t0, reg.t1) + self.store_memory(reg.t2, node.dest) @visitor.when(StarNode) def visit(self, node: StarNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.mult(reg.t2, reg.t0, reg.t1) + self.mips.mflo(reg.t0) + self.store_memory(reg.t0, node.dest) @visitor.when(DivNode) def visit(self, node: DivNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.div(reg.t2, reg.t0, reg.t1) + self.mips.mflo(reg.t0) + self.store_memory(reg.t0, node.dest) @visitor.when(EqualNode) def visit(self, node: EqualNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.slt(reg.t2, reg.t0, reg.t1) + self.mips.slt(reg.t3, reg.t1, reg.t0) + + self.mips.add(reg.t0, reg.t2, reg.t3) + self.mips.slti(reg.t1, reg.t0, 1) + + self.store_memory(reg.t1, node.dest) @visitor.when(LessEqNode) def visit(self, node: LessEqNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.slt(reg.t2, reg.t1, reg.t0) + self.mips.li(reg.t3, 1) + self.mips.sub(reg.t0, reg.t3, reg.t2) + self.store_memory(reg.t0, node.dest) @visitor.when(LessNode) def visit(self, node: LessNode): - self.visit_ArithNode(node) + self.load_arithmetic(node) + self.mips.slt(reg.t2, reg.t0, reg.t1) + self.store_memory(reg.t2, node.dest) + + @visitor.when(IsVoidNode) + def visit(self, node: IsVoidNode): + self.mips.comment("IsVoidNode") + self.load_memory(reg.t0, node.body) + + label = self.get_label() + + self.mips.li(reg.t1, 0) + self.mips.bne(reg.t0, reg.t1, label) + self.mips.li(reg.t1, 1) + self.mips.label(label) + self.store_memory(reg.t1, node.dest) @visitor.when(AllocateNode) def visit(self, node): @@ -172,43 +212,58 @@ def visit(self, node): @visitor.when(TypeOfNode) def visit(self, node): - pass + self.mips.comment("TypeOfNode") + self.mips.la(reg.t0, node.obj) + self.load_memory(reg.t1, self.mips.offset(reg.t0)) + self.store_memory(reg.t1, node.dest) @visitor.when(LabelNode) - def visit(self, node): - pass + def visit(self, node: LabelNode): + self.mips.label(node.label) @visitor.when(GotoNode) - def visit(self, node): - pass + def visit(self, node: GotoNode): + self.mips.comment("GotoNode") + self.mips.j(node.label) @visitor.when(IfGotoNode) def visit(self, node: IfGotoNode): - pass + self.mips.comment("IfGotoNode") + self.load_memory(reg.t0, node.value) + self.mips.li(reg.t1, 0) + self.mips.bne(reg.t0, reg.t1, node.label) @visitor.when(StaticCallNode) - def visit(self, node): - pass + def visit(self, node: StaticCallNode): + self.mips.comment("StaticCallNode") + self.mips.jal(node.function) @visitor.when(DynamicCallNode) def visit(self, node): pass @visitor.when(ArgNode) - def visit(self, node): - pass + def visit(self, node: ArgNode): + self.mips.comment("ArgNode") + self.load_memory(reg.t0, node.name) + self.mips.push(reg.t0) @visitor.when(ErrorNode) def visit(self, node): - pass + self.mips.comment("ErrorNode") + self.mips.li(reg.a0, 1) + self.mips.syscall(17) @visitor.when(CopyNode) def visit(self, node): pass @visitor.when(TypeNameNode) - def visit(self, node): - pass + def visit(self, node: TypeNameNode): + self.mips.comment("TypeNameNode") + self.load_memory(reg.t0, node.type) + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, self.data_size)) + self.store_memory(reg.t1, node.dest) @visitor.when(LengthNode) def visit(self, node): @@ -247,9 +302,11 @@ def visit(self, node): pass @visitor.when(PrintNode) - def visit(self, node): - pass + def visit(self, node: PrintNode): + self.load_memory(reg.a0, node.str_addr) + self.mips.print_string() @visitor.when(ReturnNode) - def visit(self, node): - pass + def visit(self, node: ReturnNode): + self.mips.comment("ReturnNode") + self.load_memory(reg.v0, node.value) From ce41fc7f80f925b0ab4d8b35a1317ca4a54fc816 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 30 Nov 2020 09:53:07 -0500 Subject: [PATCH 066/191] the mips code is written.. nodes missing --- src/engine/__init__.py | 2 + src/engine/codegen/cil.py | 30 +- src/engine/codegen/cil_ast.py | 2 + src/engine/codegen/mips.py | 108 ++-- src/engine/codegen/to_cil.py | 4 +- src/engine/codegen/to_mips.py | 108 +++- src/main.py | 38 +- src/test.cl | 7 +- src/test.mips | 987 ++++++++++++++++++++++++---------- 9 files changed, 909 insertions(+), 377 deletions(-) diff --git a/src/engine/__init__.py b/src/engine/__init__.py index 132a599e..3b4aa5c8 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -10,3 +10,5 @@ from .errors import * from .codegen.to_cil import COOL_TO_CIL from .codegen.cil_format import CIL_FORMATTER +from .codegen.to_mips import CIL_TO_MIPS +from .codegen.mips import * diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 93d88840..faa3fb19 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -128,7 +128,7 @@ def define_io_type(self): self.to_function_name(self.current_method.name, type_name)) str_val = self.define_internal_local() self.register_instruction(PrintNode(str_val)) - self.register_instruction(ReturnNode(0)) + # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_string') @@ -148,7 +148,7 @@ def define_io_type(self): int_val = self.register_param(VariableInfo('int_val', None)) self.register_instruction(ToStrNode(dest, int_val)) self.register_instruction(PrintNode(dest)) - self.register_instruction(ReturnNode(0)) + # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_int') @@ -177,7 +177,7 @@ def define_object_type(self): self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) self.register_instruction(ErrorNode()) - self.register_instruction(ReturnNode(0)) + # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('copy') @@ -190,15 +190,15 @@ def define_object_type(self): self.register_instruction(ReturnNode(copy_inst)) self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('type_name') - type_name = self.current_type.name - self.current_function = self.register_function( - self.to_function_name(self.current_method.name, type_name)) - self_local = self.register_param(VariableInfo('self', None)) - type_name_inst = self.define_internal_local() - obj_type = self.define_internal_local() - self.register_instruction(TypeOfNode(self_local, obj_type)) - self.register_instruction(TypeNameNode(type_name_inst, obj_type)) - self.register_instruction(ReturnNode(type_name_inst)) - self.current_method = self.current_function = None - self.current_type = None + # self.current_method = self.current_type.get_method('type_name') + # type_name = self.current_type.name + # self.current_function = self.register_function( + # self.to_function_name(self.current_method.name, type_name)) + # self_local = self.register_param(VariableInfo('self', None)) + # type_name_inst = self.define_internal_local() + # obj_type = self.define_internal_local() + # self.register_instruction(TypeOfNode(self_local, obj_type)) + # self.register_instruction(TypeNameNode(type_name_inst, obj_type)) + # self.register_instruction(ReturnNode(type_name_inst)) + # self.current_method = self.current_function = None + # self.current_type = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 8a529c5f..65cf73c9 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -14,8 +14,10 @@ def __init__(self, dottypes, dotdata, dotcode): class TypeNode(Node): def __init__(self, name): self.name = name + self.name_dir = "" self.attributes = [] self.methods = [] + self.features = [] class DataNode(Node): diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index da8a49ae..c2401a67 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -1,4 +1,6 @@ from enum import Enum +from typing import Dict, List +from .cil_ast import TypeNode class Registers: @@ -36,36 +38,53 @@ class Registers: ra = '$ra' # Return address(used by function call) -class ArithmOperations(Enum): - Add = 1 - Sub = 2 - Mul = 3 - Div = 4 +class TypeData: + def __init__(self, type_number: int, typex: TypeNode): + self.type: int = type_number + self.str: str = typex.name_dir + self.attr_offsets: Dict[str, int] = dict() + self.func_offsets: Dict[str, int] = dict() + self.func_names: Dict[str, str] = dict() + # Calculate offsets for attributes and functions + for idx, feature in enumerate(typex.features): + if isinstance(feature, str): + # The plus 2 is because the two first elementes + # in the instance are the type_int and the type_str_dir. + # Also enumerate starts with 0 + self.attr_offsets[feature] = idx + 2 + else: + func_name, long_name = feature + self.func_offsets[func_name] = idx + 2 + self.func_names[func_name] = long_name -# class MipsLabel: -# word = ".word" -# half = ".half" -# byte = ".byte" -# ascii_ = ".ascii" -# asciiz = ".asciiz" -# space = ".space" -# aling = ".align" -# text = ".text" -# data = ".data" +class MipsLabel(str, Enum): + word = ".word" + half = ".half" + byte = ".byte" + ascii_ = ".ascii" + asciiz = ".asciiz" + space = ".space" + aling = ".align" + text = ".text" + data = ".data" -Reg = Registers + +reg = Registers class MipsCode: def __init__(self): self.dotdata = [] self.dotcode = [] - # Data Segmente + # Meta Functions + def compile(self): + return '\n'.join([MipsLabel.data] + self.dotdata + [MipsLabel.text] + self.dotcode) + def _write(self, line): self.dotcode.append(line) @@ -75,43 +94,46 @@ def _write_data(self, line): def data_label(self, lname): self._write_data(f'{lname}') + def empty_line(self): + self._write('') + def asciiz(self, string): self._write_data(f'.asciiz "{string}"') - def push(self, register: Register): - self.addi(Register.sp, Register.sp, -8) - self.store_memory(register, self.offset(Register.sp)) + def push(self, register: Registers): + self.addi(Registers.sp, Registers.sp, -8) + self.store_memory(register, self.offset(Registers.sp)) - def pop(self, register: Register): + def pop(self, register: Registers): """ First, load from to address `0($sp)` and then write `addi $sp , $sp , 8` to restore the stack pointer """ - self.load_memory(register, self.offset(Reg.sp)) - self.addi(Reg.sp, Reg.sp, 8) + self.load_memory(register, self.offset(reg.sp)) + self.addi(reg.sp, reg.sp, 8) - def load_memory(self, dst: Register, address: str): + def load_memory(self, dst: Registers, address: str): """ Load from a specific address a 32 bits register """ - self.lw(Reg.t8, address) - self.sll(Reg.t8, Reg.t8, 16) - self.la(Reg.t7, address) - self.addi(Reg.t7, Reg.t7, 4) - self.lw(Reg.t9, self.offset(Reg.t7)) - self.or_(dst, Reg.t8, Reg.t9) + self.lw(reg.t8, address) + self.sll(reg.t8, reg.t8, 16) + self.la(reg.t7, address) + self.addi(reg.t7, reg.t7, 4) + self.lw(reg.t9, self.offset(reg.t7)) + self.or_(dst, reg.t8, reg.t9) def store_memory(self, src: Registers, address: str): """ Write to a specific address a 32 bits register """ - self.la(Reg.t8, address) + self.la(reg.t8, address) - self.srl(Reg.t9, src, 16) + self.srl(reg.t9, src, 16) - self.sw(Reg.t9, self.offset(Reg.t8)) # store high bits - self.sw(src, self.offset(Reg.t8, 4)) # store low bits + self.sw(reg.t9, self.offset(reg.t8)) # store high bits + self.sw(src, self.offset(reg.t8, 4)) # store low bits # System Calls @@ -119,14 +141,14 @@ def syscall(self, code: int): self.li(Registers.v0, code) self._write('syscall') - def offset(self, r: Register, offset: int = 0): + def offset(self, r: Registers, offset: int = 0): return f"{offset}({r})" def comment(self, text: str): self._write(f"# {text}") def label(self, name: str): - self._write(f"{name.upper()}:") + self._write(f"{name}:") def print_str(self, _str): return self.syscall(4) @@ -236,13 +258,13 @@ def or_(self, rdest, rsrc1, src2): ''' Or ''' - self._write(f'or {rdest}, {rsrc1}, {rsrc2}') + self._write(f'or {rdest}, {rsrc1}, {src2}') def nor(self, rdest, rsrc1, src2): ''' Nor ''' - self._write(f'nor {rdest}, {rsrc1}, {rsrc2}') + self._write(f'nor {rdest}, {rsrc1}, {src2}') def ori(self, rdest, rsrc1, constant): ''' @@ -315,7 +337,13 @@ def slti(self, rdest, rsrc1, value): ''' self._write(f'slti {rdest}, {rsrc1}, {value}') - # Branch and Jump + def srl(self, rdest, rsrc1, src2): + ''' + Shift Right Logical + ''' + self._write(f'srl {rdest}, {rsrc1}, {src2}') + + # Branch and Jump def b(self, label): ''' @@ -355,7 +383,7 @@ def jal(self, label): def jr(self, rsrc): ''' - Jump Register + Jump Registers ''' self._write(f'jr {rsrc}') diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 18a6147a..3eeffe39 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -50,12 +50,12 @@ def visit(self, node: cool.ProgramNode, scope=None): self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() - self.register_instruction(AllocateNode('Main', instance)) + self.register_instruction(AllocateNode(instance, 'Main')) self.init_class_attr(scope, 'Main', instance) self.register_instruction(ArgNode(instance)) name = self.to_function_name('main', 'Main') self.register_instruction(StaticCallNode(name, result)) - self.register_instruction(ReturnNode(0)) + # self.register_instruction(ReturnNode(0)) self.current_function = None classes = [declaration for declaration in node.declarations if isinstance( diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index ac12cc94..579a53e4 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,12 +1,15 @@ from .cil_ast import * from ..cp import visitor -from .mips import MipsCode +from .mips import MipsCode, TypeData from .mips import Registers as reg +from typing import Dict, List class CIL_TO_MIPS: def __init__(self, data_size=8): + self.types = [] + self.types_offsets: Dict[str, TypeData] = dict() self.arguments = {} self.local_vars = {} self.data_size = data_size @@ -14,6 +17,22 @@ def __init__(self, data_size=8): self.label_count = 0 self.mips = MipsCode() + def build_types(self, types): + for idx, typex in enumerate(types): + self.types_offsets[typex.name] = TypeData(idx, typex) + + def get_pc(self, dst): + label = self.get_label() + end = self.get_label() + + self.mips.j(end) + self.mips.label(label) + self.mips.move(dst, reg.ra) + self.mips.jr(reg.ra) + self.mips.label(end) + + return label + def get_label(self): return f"mip_label_{self.label_count}" self.label_count += 1 @@ -58,14 +77,15 @@ def visit(self, node): @visitor.when(ProgramNode) def visit(self, node: ProgramNode): - # self.types = node.dottypes - # self.build_types(self.types) + self.types = node.dottypes + self.build_types(self.types) for data in node.dotdata: self.visit(data) self.mips.label('main') self.mips.jal('entry') + self.mips.empty_line() self.mips.exit() for code in node.dotcode: @@ -82,7 +102,7 @@ def visit(self, node: FunctionNode): self.mips.comment("Set stack frame") self.mips.push(reg.fp) self.mips.move(reg.fp, reg.sp) - + self.mips.empty_line() self.arguments = dict() for idx, param in enumerate(node.params): @@ -96,7 +116,7 @@ def visit(self, node: FunctionNode): self.mips.comment("Generating body code") for instruction in node.instructions: self.visit(instruction) - + self.mips.empty_line() self.arguments = None self.load_registers() @@ -119,15 +139,38 @@ def visit(self, node: ParamNode, index=0): def visit(self, node: LocalNode, index=0): self.mips.push(reg.zero) if node.name in self.local_vars: + pass + else: self.local_vars[node.name] = index @visitor.when(GetAttribNode) - def visit(self, node): - pass + def visit(self, node: GetAttribNode): + self.mips.comment("GetAttribNode") + self.load_memory(reg.t0, node.obj) + type_data = self.types_offsets[node.type] + offset = type_data.attr_offsets[node.attrib] + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset)) + self.store_memory(reg.t1, node.dest) @visitor.when(SetAttribNode) - def visit(self, node): - pass + def visit(self, node: SetAttribNode): + self.mips.comment("SetAttribNode") + self.load_memory(reg.t0, node.obj) + type_data = self.types_offsets[node.type] + offset = type_data.attr_offsets[node.attrib] + if node.value in self.local_vars_offsets: + self.load_memory(reg.t1, node.value) + else: + try: + value = int(node.value) + high = value >> 16 + self.mips.li(reg.t2, high) + self.mips.li(reg.t3, value) + self.mips.sll(reg.t4, reg.t2, 16) + self.mips.or_(reg.t1, reg.t2, reg.t4) + except ValueError: + self.mips.la(reg.t1, node.value) + self.mips.store_memory(reg.t1, self.mips.offset(reg.t0, offset)) @visitor.when(AssignNode) def visit(self, node: AssignNode): @@ -207,14 +250,36 @@ def visit(self, node: IsVoidNode): self.store_memory(reg.t1, node.dest) @visitor.when(AllocateNode) - def visit(self, node): - pass + def visit(self, node: AllocateNode): + type_data = self.types_offsets[node.type] + + length = len(type_data.attr_offsets) + len(type_data.func_offsets) + 2 + length *= self.data_size / 2 + self.mips.li(reg.a0, length) + self.mips.sbrk() + self.store_memory(reg.v0, node.dest) + self.mips.li(reg.t0, type_data.type) + self.mips.store_memory(reg.t0, reg.v0) + self.mips.la(reg.t0, type_data.str) + self.mips.store_memory( + reg.t0, self.mips.offset(reg.v0, 1 * self.data_size)) + + for offset in type_data.attr_offsets.values(): + self.mips.store_memory(reg.zero, self.mips.offset( + reg.v0, offset * self.data_size)) + + for name, offset in type_data.func_offsets.items(): + direct_name = type_data.func_names[name] + self.mips.la(reg.t0, direct_name) + self.mips.store_memory( + reg.t0, + self.mips.offset(reg.v0, offset * self.data_size)) @visitor.when(TypeOfNode) - def visit(self, node): + def visit(self, node: TypeOfNode): self.mips.comment("TypeOfNode") self.mips.la(reg.t0, node.obj) - self.load_memory(reg.t1, self.mips.offset(reg.t0)) + self.load_memory(reg.t1, reg.t0) self.store_memory(reg.t1, node.dest) @visitor.when(LabelNode) @@ -239,8 +304,17 @@ def visit(self, node: StaticCallNode): self.mips.jal(node.function) @visitor.when(DynamicCallNode) - def visit(self, node): - pass + def visit(self, node: DynamicCallNode): + self.mips.comment("DynamicCallNode") + type_data = self.types_offsets[node.type] + offset = type_data.func_offsets[node.method] + self.load_memory(reg.t0, node.obj) + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset)) + label_get_pc = self.get_pc(reg.t2) + self.mips.jal(label_get_pc) + self.mips.move(reg.ra, reg.t2) + self.mips.addi(reg.ra, 12) + self.mips.jr(reg.t1) @visitor.when(ArgNode) def visit(self, node: ArgNode): @@ -249,7 +323,7 @@ def visit(self, node: ArgNode): self.mips.push(reg.t0) @visitor.when(ErrorNode) - def visit(self, node): + def visit(self, node: ErrorNode): self.mips.comment("ErrorNode") self.mips.li(reg.a0, 1) self.mips.syscall(17) @@ -304,7 +378,7 @@ def visit(self, node): @visitor.when(PrintNode) def visit(self, node: PrintNode): self.load_memory(reg.a0, node.str_addr) - self.mips.print_string() + self.mips.print_str(node.str_addr) @visitor.when(ReturnNode) def visit(self, node: ReturnNode): diff --git a/src/main.py b/src/main.py index cda6d828..7b1dd2d6 100644 --- a/src/main.py +++ b/src/main.py @@ -1,4 +1,4 @@ - #!/usr/bin/python3 +#!/usr/bin/python3 from engine import * import sys @@ -17,7 +17,7 @@ tokens, errors = tokenizer(t) -#print(tokens) +# print(tokens) if len(errors): for e in errors: print(e) @@ -26,14 +26,14 @@ parse, operations = CoolParser(tokens) -ast = evaluate_reverse_parse(parse,operations,tokens) +ast = evaluate_reverse_parse(parse, operations, tokens) collect_errors = [] collect = Collector(collect_errors) collect.visit(ast) if len(collect_errors): - #print("coolector") + # print("coolector") for e in collect_errors[::-1]: print(e) exit(1) @@ -44,7 +44,7 @@ builder.visit(ast) if len(builder_errors): - #print("builder") + # print("builder") for e in builder_errors[::-1]: print(e) exit(1) @@ -55,36 +55,36 @@ scope = checker.visit(ast) if len(checker_errors): - #print("checker") + # print("checker") for e in checker_errors[::-1]: print(e) exit(1) - -# cil = COOL_TO_CIL(checker.context) +cil = COOL_TO_CIL(checker.context) # cil = COOL_TO_CIL_VISITOR(checker.context) # sc = Scope() -# cil_ast = cil.visit(ast) +cil_ast = cil.visit(ast) # f_ast = Format().visit(ast) +emsamb = CIL_TO_MIPS() +emsamb.visit(cil_ast) +m_ast = emsamb.mips.compile() # f_ast = CIL_FORMATTER().visit(cil_ast) # string_formatted = str(f_ast) -# output_file.write(string_formatted) +output_file.write(m_ast) output_file.write(str(collect_errors)) -#print(str(collect_errors)) -#output_file.write(str(builder_errors)) -#output_file.write(str(checker_errors)) -#output_file.write(collect_errors) +# print(str(collect_errors)) +# output_file.write(str(builder_errors)) +# output_file.write(str(checker_errors)) +# output_file.write(collect_errors) output_file.close() if not operations: message = f'ERROR at or near "{parse.lex}"' - print(SyntacticError(parse.line,parse.column, message)) + print(SyntacticError(parse.line, parse.column, message)) exit(1) -#print(parse) - - +# print(parse) -exit(0) \ No newline at end of file +exit(0) diff --git a/src/test.cl b/src/test.cl index 3d4300df..d0cba548 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,12 +1,7 @@ class Main inherits IO { main () : Object { - { - let x:E <- new E in x.f() = x@E.f() ; - let x:A <- new B in out_string( x.f().m() ); - let x:A <- new A in out_string( x.f().m() ); - } - + "H" }; }; diff --git a/src/test.mips b/src/test.mips index f59612e3..4844bcb5 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,278 +1,709 @@ -.TYPES -type Object { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type String { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method length: function_length_at_String - method concat: function_concat_at_String - method substr: function_substr_at_String -} -type IO { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO -} -type Main { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method main: function_main_at_Main -} -type A { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method m: function_m_at_A - method f: function_f_at_A -} -type B { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method m: function_m_at_B - method f: function_f_at_A -} -type C { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method f: function_f_at_C -} -type D { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method f: function_f_at_C -} -type E { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method f: function_f_at_E -} - -.DATA -data_0 = "A" -data_1 = "B" -data_2 = "C" -data_3 = "E" - -.CODE -function function_abort_at_Object { - PARAM self - - - - ERROR 0 - RETURN 0 -} -function function_copy_at_Object { - PARAM self - - LOCAL local_copy_at_Object_internal_0 - - local_copy_at_Object_internal_0 = COPY self - RETURN local_copy_at_Object_internal_0 -} -function function_type_name_at_Object { - PARAM self - - LOCAL local_type_name_at_Object_internal_0 - LOCAL local_type_name_at_Object_internal_1 - - local_type_name_at_Object_internal_1 = TYPEOF self - local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 - RETURN local_type_name_at_Object_internal_0 -} -function function_length_at_String { - PARAM self - - LOCAL local_length_at_String_internal_0 - - local_length_at_String_internal_0 = LENGTH self - RETURN local_length_at_String_internal_0 -} -function function_concat_at_String { - PARAM self - PARAM string - - LOCAL local_concat_at_String_internal_0 - - local_concat_at_String_internal_0 = CONCAT self string - RETURN local_concat_at_String_internal_0 -} -function function_substr_at_String { - PARAM self - PARAM start - PARAM length - - LOCAL local_substr_at_String_internal_0 - - local_substr_at_String_internal_0 = SUBSTRING self start length - RETURN local_substr_at_String_internal_0 -} -function function_out_string_at_IO { - - - LOCAL local_out_string_at_IO_internal_0 - - PRINT local_out_string_at_IO_internal_0 - RETURN 0 -} -function function_in_string_at_IO { - - - LOCAL local_in_string_at_IO_internal_0 - - local_in_string_at_IO_internal_0 = READ - RETURN local_in_string_at_IO_internal_0 -} -function function_out_int_at_IO { - PARAM int_val - - LOCAL local_out_int_at_IO_internal_0 - - local_out_int_at_IO_internal_0 = STR int_val - PRINT local_out_int_at_IO_internal_0 - RETURN 0 -} -function function_in_int_at_IO { - - - LOCAL local_in_int_at_IO_internal_0 - LOCAL local_in_int_at_IO_internal_1 - - local_in_int_at_IO_internal_0 = READ - local_in_int_at_IO_internal_1 = INT local_in_int_at_IO_internal_0 - RETURN local_in_int_at_IO_internal_1 -} -function entry { - - - LOCAL local__internal_0 - LOCAL local__internal_1 - - Main = ALLOCATE local__internal_0 - ARG local__internal_0 - local__internal_1 = CALL function_main_at_Main - RETURN 0 -} -function function_main_at_Main { - PARAM self - - LOCAL local_main_at_Main_internal_0 - LOCAL local_main_at_Main_internal_1 - LOCAL local_main_at_Main_internal_2 - LOCAL local_main_at_Main_internal_3 - LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_internal_5 - LOCAL local_main_at_Main_internal_6 - LOCAL local_main_at_Main_internal_7 - LOCAL local_main_at_Main_internal_8 - LOCAL local_main_at_Main_internal_9 - LOCAL local_main_at_Main_internal_10 - LOCAL local_main_at_Main_internal_11 - LOCAL local_main_at_Main_internal_12 - LOCAL local_main_at_Main_internal_13 - LOCAL local_main_at_Main_internal_14 - LOCAL local_main_at_Main_internal_15 - - local_main_at_Main_internal_1 = ALLOCATE E - ARG x - local_main_at_Main_internal_3 = CALL function_f_at_E - ARG x - local_main_at_Main_internal_4 = CALL function_f_at_E - local_main_at_Main_internal_5 = STREQ local_main_at_Main_internal_3 local_main_at_Main_internal_4 - local_main_at_Main_internal_2 = local_main_at_Main_internal_5 - local_main_at_Main_internal_6 = ALLOCATE B - ARG x - local_main_at_Main_internal_10 = CALL function_f_at_A - ARG local_main_at_Main_internal_10 - local_main_at_Main_internal_9 = CALL function_m_at_A - ARG local_main_at_Main_internal_9 - ARG self - local_main_at_Main_internal_8 = VCALL Main out_string - local_main_at_Main_internal_7 = local_main_at_Main_internal_8 - local_main_at_Main_internal_11 = ALLOCATE A - ARG x - local_main_at_Main_internal_15 = CALL function_f_at_A - ARG local_main_at_Main_internal_15 - local_main_at_Main_internal_14 = CALL function_m_at_A - ARG local_main_at_Main_internal_14 - ARG self - local_main_at_Main_internal_13 = VCALL Main out_string - local_main_at_Main_internal_12 = local_main_at_Main_internal_13 - local_main_at_Main_internal_0 = local_main_at_Main_internal_12 - RETURN local_main_at_Main_internal_0 -} -function function_m_at_A { - PARAM self - - LOCAL local_m_at_A_internal_0 - - local_m_at_A_internal_0 = LOAD data_0 - RETURN local_m_at_A_internal_0 -} -function function_f_at_A { - PARAM self - - LOCAL local_f_at_A_internal_0 - - local_f_at_A_internal_0 = ALLOCATE A - RETURN local_f_at_A_internal_0 -} -function function_m_at_B { - PARAM self - - LOCAL local_m_at_B_internal_0 - - local_m_at_B_internal_0 = LOAD data_1 - RETURN local_m_at_B_internal_0 -} -function function_f_at_C { - PARAM self - - LOCAL local_f_at_C_internal_0 - - local_f_at_C_internal_0 = LOAD data_2 - RETURN local_f_at_C_internal_0 -} -function function_f_at_E { - PARAM self - - LOCAL local_f_at_E_internal_0 - - local_f_at_E_internal_0 = LOAD data_3 - RETURN local_f_at_E_internal_0 -} \ No newline at end of file +.data +data_0 +.asciiz "H" +data_1 +.asciiz "A" +data_2 +.asciiz "B" +data_3 +.asciiz "C" +data_4 +.asciiz "E" +.text +main: +jal entry + +li $v0, 10 +syscall +function_abort_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_copy_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_length_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_concat_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_substr_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, -8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +entry: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +li $a0, 8 +li $v0, 9 +syscall +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $t0, 3 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# ArgNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +addi $sp, $sp, -8 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# StaticCallNode +jal function_main_at_Main + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_m_at_A: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_A: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +li $a0, 8 +li $v0, 9 +syscall +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $t0, 4 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_m_at_B: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_C: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_E: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra[] \ No newline at end of file From 713bc79d6b6efc60e94af8b7f61c26ab54878cec Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 30 Nov 2020 15:59:32 -0500 Subject: [PATCH 067/191] commit --- src/engine/codegen/cil.py | 24 +- src/engine/codegen/cil_ast.py | 6 +- src/engine/codegen/to_cil.py | 5 +- src/engine/codegen/to_mips.py | 22 +- src/main.py | 14 +- src/test.cl | 6 +- src/test.mips | 1133 ++++++++++++--------------------- 7 files changed, 470 insertions(+), 740 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index faa3fb19..e361273c 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -190,15 +190,15 @@ def define_object_type(self): self.register_instruction(ReturnNode(copy_inst)) self.current_method = self.current_function = None - # self.current_method = self.current_type.get_method('type_name') - # type_name = self.current_type.name - # self.current_function = self.register_function( - # self.to_function_name(self.current_method.name, type_name)) - # self_local = self.register_param(VariableInfo('self', None)) - # type_name_inst = self.define_internal_local() - # obj_type = self.define_internal_local() - # self.register_instruction(TypeOfNode(self_local, obj_type)) - # self.register_instruction(TypeNameNode(type_name_inst, obj_type)) - # self.register_instruction(ReturnNode(type_name_inst)) - # self.current_method = self.current_function = None - # self.current_type = None + self.current_method = self.current_type.get_method('type_name') + type_name = self.current_type.name + self.current_function = self.register_function( + self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo('self', None)) + type_name_inst = self.define_internal_local() + obj_type = self.define_internal_local() + self.register_instruction(TypeOfNode(self_local, obj_type)) + self.register_instruction(TypeNameNode(type_name_inst, obj_type)) + self.register_instruction(ReturnNode(type_name_inst)) + self.current_method = self.current_function = None + self.current_type = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 65cf73c9..8616f5e3 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -49,17 +49,19 @@ class InstructionNode(Node): class GetAttribNode(InstructionNode): - def __init__(self, dest, obj, attrib): + def __init__(self, dest, obj, attrib, typex): self.dest = dest self.obj = obj self.attrib = attrib + self.type = typex class SetAttribNode(InstructionNode): - def __init__(self, obj, attrib, value): + def __init__(self, obj, attrib, value, typex): self.obj = obj self.attrib = attrib self.value = value + self.type = typex class AssignNode(InstructionNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 3eeffe39..c1e5498e 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -92,6 +92,7 @@ def visit(self, node: cool.FuncDeclarationNode, scope: Scope): self_local = self.register_param(VariableInfo('self', None)) fun_scope.define_variable('self', self_local) for param_name, param_type in node.params: + fun_scope.define_variable(param_name.lex, param_type.lex) self.register_param(VariableInfo(param_name.lex, param_type.lex)) body = self.visit(node.body, fun_scope) @@ -104,7 +105,7 @@ def visit(self, node: cool.AttrDeclarationNode, scope): result = self.visit(node.expression, scope) if node.expression else 0 self_inst = scope.find_variable('self').name self.register_instruction( - SetAttribNode(self_inst, node.id.lex, result)) + SetAttribNode(self_inst, node.id.lex, result, self.current_type.name)) @visitor.when(cool.AssignNode) def visit(self, node: cool.AssignNode, scope): @@ -299,7 +300,7 @@ def visit(self, node: cool.IdNode, scope: Scope): selfx = scope.find_variable('self').name nvar = self.define_internal_local() self.register_instruction( - GetAttribNode(nvar, selfx, node.token.lex)) + GetAttribNode(nvar, selfx, node.token.lex, self.current_type.name)) else: nvar = nvar.name return nvar diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 579a53e4..2dc7f01b 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -13,7 +13,16 @@ def __init__(self, data_size=8): self.arguments = {} self.local_vars = {} self.data_size = data_size - self.registers_to_save = [reg.ra] + self.registers_to_save = [ + reg.ra, + reg.s0, + reg.s1, + reg.s2, + reg.s3, + reg.s4, + reg.s5, + reg.s6, + reg.s7, ] self.label_count = 0 self.mips = MipsCode() @@ -278,9 +287,9 @@ def visit(self, node: AllocateNode): @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): self.mips.comment("TypeOfNode") - self.mips.la(reg.t0, node.obj) - self.load_memory(reg.t1, reg.t0) - self.store_memory(reg.t1, node.dest) + self.load_memory(reg.s0, node.obj) + self.mips.load_memory(reg.s1, reg.s0) + self.store_memory(reg.s1, node.dest) @visitor.when(LabelNode) def visit(self, node: LabelNode): @@ -302,6 +311,7 @@ def visit(self, node: IfGotoNode): def visit(self, node: StaticCallNode): self.mips.comment("StaticCallNode") self.mips.jal(node.function) + self.store_memory(reg.v0, node.dest) @visitor.when(DynamicCallNode) def visit(self, node: DynamicCallNode): @@ -319,8 +329,8 @@ def visit(self, node: DynamicCallNode): @visitor.when(ArgNode) def visit(self, node: ArgNode): self.mips.comment("ArgNode") - self.load_memory(reg.t0, node.name) - self.mips.push(reg.t0) + self.load_memory(reg.s0, node.name) + self.mips.push(reg.s0) @visitor.when(ErrorNode) def visit(self, node: ErrorNode): diff --git a/src/main.py b/src/main.py index 7b1dd2d6..4d3e2342 100644 --- a/src/main.py +++ b/src/main.py @@ -64,15 +64,15 @@ cil = COOL_TO_CIL(checker.context) # cil = COOL_TO_CIL_VISITOR(checker.context) # sc = Scope() -cil_ast = cil.visit(ast) -# f_ast = Format().visit(ast) +# cil_ast = cil.visit(ast) +f_ast = Format().visit(ast) emsamb = CIL_TO_MIPS() -emsamb.visit(cil_ast) -m_ast = emsamb.mips.compile() +# emsamb.visit(cil_ast) +# m_ast = emsamb.mips.compile() # f_ast = CIL_FORMATTER().visit(cil_ast) -# string_formatted = str(f_ast) -output_file.write(m_ast) -output_file.write(str(collect_errors)) +string_formatted = str(f_ast) +output_file.write(string_formatted) +# output_file.write(str(collect_errors)) # print(str(collect_errors)) # output_file.write(str(builder_errors)) # output_file.write(str(checker_errors)) diff --git a/src/test.cl b/src/test.cl index d0cba548..2881a261 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,13 +1,15 @@ class Main inherits IO { main () : Object { - "H" + { + a <- 34; + } }; }; class A { m () : String { "A" }; - f () : A { new A }; + f ( a : B) : B { a }; }; class B inherits A { diff --git a/src/test.mips b/src/test.mips index 4844bcb5..a523e245 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,709 +1,424 @@ -.data -data_0 -.asciiz "H" -data_1 -.asciiz "A" -data_2 -.asciiz "B" -data_3 -.asciiz "C" -data_4 -.asciiz "E" -.text -main: -jal entry - -li $v0, 10 -syscall -function_abort_at_Object: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_copy_at_Object: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_length_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_concat_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_substr_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_out_string_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 -li $v0, 4 -syscall - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_in_string_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_out_int_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 -li $v0, 4 -syscall - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_in_int_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, -8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -entry: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -li $a0, 8 -li $v0, 9 -syscall -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -li $t0, 3 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -# ArgNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -addi $sp, $sp, -8 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -# StaticCallNode -jal function_main_at_Main - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_main_at_Main: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_m_at_A: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_A: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -li $a0, 8 -li $v0, 9 -syscall -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -li $t0, 4 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_m_at_B: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_C: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_E: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra[] \ No newline at end of file +.TYPES +type Object { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type String { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method length: function_length_at_String + method concat: function_concat_at_String + method substr: function_substr_at_String +} +type IO { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO +} +type Main { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method main: function_main_at_Main +} +type Complex { + attribute x + attribute y + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method init: function_init_at_Complex + method print: function_print_at_Complex + method reflect_0: function_reflect_0_at_Complex + method reflect_X: function_reflect_X_at_Complex + method reflect_Y: function_reflect_Y_at_Complex + method equal: function_equal_at_Complex + method x_value: function_x_value_at_Complex + method y_value: function_y_value_at_Complex +} + +.DATA +data_0 = "=(n" +data_1 = "=)n" +data_2 = "=(n" +data_3 = "=)n" +data_4 = "I" +data_5 = "+" + +.CODE +function function_abort_at_Object { + PARAM self + + + + ERROR 0 +} +function function_copy_at_Object { + PARAM self + + LOCAL local_copy_at_Object_internal_0 + + local_copy_at_Object_internal_0 = COPY self + RETURN local_copy_at_Object_internal_0 +} +function function_type_name_at_Object { + PARAM self + + LOCAL local_type_name_at_Object_internal_0 + LOCAL local_type_name_at_Object_internal_1 + + local_type_name_at_Object_internal_1 = TYPEOF self + local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 + RETURN local_type_name_at_Object_internal_0 +} +function function_length_at_String { + PARAM self + + LOCAL local_length_at_String_internal_0 + + local_length_at_String_internal_0 = LENGTH self + RETURN local_length_at_String_internal_0 +} +function function_concat_at_String { + PARAM self + PARAM string + + LOCAL local_concat_at_String_internal_0 + + local_concat_at_String_internal_0 = CONCAT self string + RETURN local_concat_at_String_internal_0 +} +function function_substr_at_String { + PARAM self + PARAM start + PARAM length + + LOCAL local_substr_at_String_internal_0 + + local_substr_at_String_internal_0 = SUBSTRING self start length + RETURN local_substr_at_String_internal_0 +} +function function_out_string_at_IO { + + + LOCAL local_out_string_at_IO_internal_0 + + PRINT local_out_string_at_IO_internal_0 +} +function function_in_string_at_IO { + + + LOCAL local_in_string_at_IO_internal_0 + + local_in_string_at_IO_internal_0 = READ + RETURN local_in_string_at_IO_internal_0 +} +function function_out_int_at_IO { + PARAM int_val + + LOCAL local_out_int_at_IO_internal_0 + + local_out_int_at_IO_internal_0 = STR int_val + PRINT local_out_int_at_IO_internal_0 +} +function function_in_int_at_IO { + + + LOCAL local_in_int_at_IO_internal_0 + LOCAL local_in_int_at_IO_internal_1 + + local_in_int_at_IO_internal_0 = READ + local_in_int_at_IO_internal_1 = INT local_in_int_at_IO_internal_0 + RETURN local_in_int_at_IO_internal_1 +} +function entry { + + + LOCAL local__internal_0 + LOCAL local__internal_1 + + local__internal_0 = ALLOCATE Main + ARG local__internal_0 + local__internal_1 = CALL function_main_at_Main +} +function function_main_at_Main { + PARAM self + + LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_internal_1 + LOCAL local_main_at_Main_internal_2 + LOCAL local_main_at_Main_internal_3 + LOCAL local_main_at_Main_internal_4 + LOCAL local_main_at_Main_internal_5 + LOCAL local_main_at_Main_internal_6 + LOCAL local_main_at_Main_internal_7 + LOCAL local_main_at_Main_internal_8 + LOCAL local_main_at_Main_internal_9 + LOCAL local_main_at_Main_internal_10 + LOCAL local_main_at_Main_internal_11 + LOCAL local_main_at_Main_internal_12 + LOCAL local_main_at_Main_internal_13 + LOCAL local_main_at_Main_internal_14 + LOCAL local_main_at_Main_internal_15 + LOCAL local_main_at_Main_internal_16 + LOCAL local_main_at_Main_internal_17 + LOCAL local_main_at_Main_internal_18 + LOCAL local_main_at_Main_internal_19 + LOCAL local_main_at_Main_internal_20 + + ARG 1 + ARG 1 + local_main_at_Main_internal_1 = ALLOCATE Complex + SETATTR self x 0 + SETATTR self y 0 + ARG local_main_at_Main_internal_1 + local_main_at_Main_internal_0 = CALL function_init_at_Complex + ARG c + local_main_at_Main_internal_4 = CALL function_reflect_X_at_Complex + ARG c + local_main_at_Main_internal_5 = CALL function_reflect_0_at_Complex + local_main_at_Main_internal_6 = local_main_at_Main_internal_4 == local_main_at_Main_internal_5 + IF local_main_at_Main_internal_6 GOTO TRUE + local_main_at_Main_internal_9 = LOAD data_0 + ARG local_main_at_Main_internal_9 + ARG self + local_main_at_Main_internal_8 = VCALL Main out_string + local_main_at_Main_internal_7 = local_main_at_Main_internal_8 + GOTO END + LABEL TRUE + local_main_at_Main_internal_11 = LOAD data_1 + ARG local_main_at_Main_internal_11 + ARG self + local_main_at_Main_internal_10 = VCALL Main out_string + local_main_at_Main_internal_7 = local_main_at_Main_internal_10 + LABEL END + ARG c + local_main_at_Main_internal_13 = CALL function_reflect_0_at_Complex + ARG local_main_at_Main_internal_13 + ARG c + local_main_at_Main_internal_15 = CALL function_reflect_X_at_Complex + ARG local_main_at_Main_internal_15 + local_main_at_Main_internal_14 = CALL function_reflect_Y_at_Complex + ARG local_main_at_Main_internal_14 + local_main_at_Main_internal_12 = CALL function_equal_at_Complex + IF local_main_at_Main_internal_12 GOTO TRUE + local_main_at_Main_internal_18 = LOAD data_2 + ARG local_main_at_Main_internal_18 + ARG self + local_main_at_Main_internal_17 = VCALL Main out_string + local_main_at_Main_internal_16 = local_main_at_Main_internal_17 + GOTO END + LABEL TRUE + local_main_at_Main_internal_20 = LOAD data_3 + ARG local_main_at_Main_internal_20 + ARG self + local_main_at_Main_internal_19 = VCALL Main out_string + local_main_at_Main_internal_16 = local_main_at_Main_internal_19 + LABEL END + local_main_at_Main_internal_3 = local_main_at_Main_internal_16 + local_main_at_Main_internal_2 = local_main_at_Main_internal_3 + RETURN local_main_at_Main_internal_2 +} +function function_init_at_Complex { + PARAM self + PARAM a + PARAM b + + LOCAL local_init_at_Complex_internal_0 + LOCAL local_init_at_Complex_internal_1 + LOCAL local_init_at_Complex_internal_2 + LOCAL local_init_at_Complex_internal_3 + LOCAL local_init_at_Complex_internal_4 + LOCAL local_init_at_Complex_internal_5 + LOCAL local_init_at_Complex_internal_6 + + local_init_at_Complex_internal_1 = GETATTR self x + local_init_at_Complex_internal_2 = GETATTR self a + local_init_at_Complex_internal_3 = local_init_at_Complex_internal_1 == local_init_at_Complex_internal_2 + local_init_at_Complex_internal_4 = GETATTR self y + local_init_at_Complex_internal_5 = GETATTR self b + local_init_at_Complex_internal_6 = local_init_at_Complex_internal_4 == local_init_at_Complex_internal_5 + local_init_at_Complex_internal_0 = self + RETURN local_init_at_Complex_internal_0 +} +function function_print_at_Complex { + PARAM self + + LOCAL local_print_at_Complex_internal_0 + LOCAL local_print_at_Complex_internal_1 + LOCAL local_print_at_Complex_internal_2 + LOCAL local_print_at_Complex_internal_3 + LOCAL local_print_at_Complex_internal_4 + LOCAL local_print_at_Complex_internal_5 + LOCAL local_print_at_Complex_internal_6 + LOCAL local_print_at_Complex_internal_7 + LOCAL local_print_at_Complex_internal_8 + LOCAL local_print_at_Complex_internal_9 + LOCAL local_print_at_Complex_internal_10 + LOCAL local_print_at_Complex_internal_11 + LOCAL local_print_at_Complex_internal_12 + + local_print_at_Complex_internal_0 = GETATTR self y + local_print_at_Complex_internal_1 = local_print_at_Complex_internal_0 == 0 + IF local_print_at_Complex_internal_1 GOTO TRUE + local_print_at_Complex_internal_4 = LOAD data_4 + ARG local_print_at_Complex_internal_4 + local_print_at_Complex_internal_6 = GETATTR self y + ARG local_print_at_Complex_internal_6 + local_print_at_Complex_internal_8 = LOAD data_5 + ARG local_print_at_Complex_internal_8 + local_print_at_Complex_internal_10 = GETATTR self x + ARG local_print_at_Complex_internal_10 + ARG self + local_print_at_Complex_internal_9 = VCALL Complex out_int + ARG local_print_at_Complex_internal_9 + local_print_at_Complex_internal_7 = CALL function_out_string_at_Complex + ARG local_print_at_Complex_internal_7 + local_print_at_Complex_internal_5 = CALL function_out_int_at_Complex + ARG local_print_at_Complex_internal_5 + local_print_at_Complex_internal_3 = CALL function_out_string_at_Complex + local_print_at_Complex_internal_2 = local_print_at_Complex_internal_3 + GOTO END + LABEL TRUE + local_print_at_Complex_internal_12 = GETATTR self x + ARG local_print_at_Complex_internal_12 + ARG self + local_print_at_Complex_internal_11 = VCALL Complex out_int + local_print_at_Complex_internal_2 = local_print_at_Complex_internal_11 + LABEL END + RETURN local_print_at_Complex_internal_2 +} +function function_reflect_0_at_Complex { + PARAM self + + LOCAL local_reflect_0_at_Complex_internal_0 + LOCAL local_reflect_0_at_Complex_internal_1 + LOCAL local_reflect_0_at_Complex_internal_2 + LOCAL local_reflect_0_at_Complex_internal_3 + LOCAL local_reflect_0_at_Complex_internal_4 + LOCAL local_reflect_0_at_Complex_internal_5 + LOCAL local_reflect_0_at_Complex_internal_6 + LOCAL local_reflect_0_at_Complex_internal_7 + LOCAL local_reflect_0_at_Complex_internal_8 + + local_reflect_0_at_Complex_internal_1 = GETATTR self x + local_reflect_0_at_Complex_internal_3 = GETATTR self x + local_reflect_0_at_Complex_internal_2 = COMPLEMENT local_reflect_0_at_Complex_internal_3 + local_reflect_0_at_Complex_internal_4 = local_reflect_0_at_Complex_internal_1 == local_reflect_0_at_Complex_internal_2 + local_reflect_0_at_Complex_internal_5 = GETATTR self y + local_reflect_0_at_Complex_internal_7 = GETATTR self y + local_reflect_0_at_Complex_internal_6 = COMPLEMENT local_reflect_0_at_Complex_internal_7 + local_reflect_0_at_Complex_internal_8 = local_reflect_0_at_Complex_internal_5 == local_reflect_0_at_Complex_internal_6 + local_reflect_0_at_Complex_internal_0 = self + RETURN local_reflect_0_at_Complex_internal_0 +} +function function_reflect_X_at_Complex { + PARAM self + + LOCAL local_reflect_X_at_Complex_internal_0 + LOCAL local_reflect_X_at_Complex_internal_1 + LOCAL local_reflect_X_at_Complex_internal_2 + LOCAL local_reflect_X_at_Complex_internal_3 + LOCAL local_reflect_X_at_Complex_internal_4 + + local_reflect_X_at_Complex_internal_1 = GETATTR self y + local_reflect_X_at_Complex_internal_3 = GETATTR self y + local_reflect_X_at_Complex_internal_2 = COMPLEMENT local_reflect_X_at_Complex_internal_3 + local_reflect_X_at_Complex_internal_4 = local_reflect_X_at_Complex_internal_1 == local_reflect_X_at_Complex_internal_2 + local_reflect_X_at_Complex_internal_0 = self + RETURN local_reflect_X_at_Complex_internal_0 +} +function function_reflect_Y_at_Complex { + PARAM self + + LOCAL local_reflect_Y_at_Complex_internal_0 + LOCAL local_reflect_Y_at_Complex_internal_1 + LOCAL local_reflect_Y_at_Complex_internal_2 + LOCAL local_reflect_Y_at_Complex_internal_3 + LOCAL local_reflect_Y_at_Complex_internal_4 + + local_reflect_Y_at_Complex_internal_1 = GETATTR self x + local_reflect_Y_at_Complex_internal_3 = GETATTR self x + local_reflect_Y_at_Complex_internal_2 = COMPLEMENT local_reflect_Y_at_Complex_internal_3 + local_reflect_Y_at_Complex_internal_4 = local_reflect_Y_at_Complex_internal_1 == local_reflect_Y_at_Complex_internal_2 + local_reflect_Y_at_Complex_internal_0 = self + RETURN local_reflect_Y_at_Complex_internal_0 +} +function function_equal_at_Complex { + PARAM self + PARAM d + + LOCAL local_equal_at_Complex_internal_0 + LOCAL local_equal_at_Complex_internal_1 + LOCAL local_equal_at_Complex_internal_2 + LOCAL local_equal_at_Complex_internal_3 + LOCAL local_equal_at_Complex_internal_4 + LOCAL local_equal_at_Complex_internal_5 + LOCAL local_equal_at_Complex_internal_6 + LOCAL local_equal_at_Complex_internal_7 + LOCAL local_equal_at_Complex_internal_8 + LOCAL local_equal_at_Complex_internal_9 + + local_equal_at_Complex_internal_0 = GETATTR self x + local_equal_at_Complex_internal_2 = GETATTR self d + ARG local_equal_at_Complex_internal_2 + local_equal_at_Complex_internal_1 = CALL function_x_value_at_Complex + local_equal_at_Complex_internal_3 = local_equal_at_Complex_internal_0 == local_equal_at_Complex_internal_1 + IF local_equal_at_Complex_internal_3 GOTO TRUE + local_equal_at_Complex_internal_4 = 0 + GOTO END + LABEL TRUE + local_equal_at_Complex_internal_5 = GETATTR self y + local_equal_at_Complex_internal_7 = GETATTR self d + ARG local_equal_at_Complex_internal_7 + local_equal_at_Complex_internal_6 = CALL function_y_value_at_Complex + local_equal_at_Complex_internal_8 = local_equal_at_Complex_internal_5 == local_equal_at_Complex_internal_6 + IF local_equal_at_Complex_internal_8 GOTO TRUE + local_equal_at_Complex_internal_9 = 0 + GOTO END + LABEL TRUE + local_equal_at_Complex_internal_9 = 1 + LABEL END + local_equal_at_Complex_internal_4 = local_equal_at_Complex_internal_9 + LABEL END + RETURN local_equal_at_Complex_internal_4 +} +function function_x_value_at_Complex { + PARAM self + + LOCAL local_x_value_at_Complex_internal_0 + + local_x_value_at_Complex_internal_0 = GETATTR self x + RETURN local_x_value_at_Complex_internal_0 +} +function function_y_value_at_Complex { + PARAM self + + LOCAL local_y_value_at_Complex_internal_0 + + local_y_value_at_Complex_internal_0 = GETATTR self y + RETURN local_y_value_at_Complex_internal_0 +} \ No newline at end of file From e86363c20feeac36acde213e506cc2af1b20b8c5 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 30 Nov 2020 18:24:18 -0500 Subject: [PATCH 068/191] string nodes done --- src/engine/codegen/mips.py | 4 +- src/engine/codegen/to_mips.py | 216 ++++++++++++++++- src/main.py | 8 +- src/test.cl | 4 +- src/test.mips | 424 ---------------------------------- 5 files changed, 211 insertions(+), 445 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index c2401a67..ab4fdfcd 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -357,11 +357,11 @@ def beq(self, rsrc1, src2, label): ''' self._write(f'beq {rsrc1}, {src2}, {label}') - def beqz(self, rsrc1, src2, label): + def beqz(self, rsrc1, label): ''' Branch on Equal Zero ''' - self._write(f'beqz {rsrc1}, {src2}, {label}') + self._write(f'beqz {rsrc1}, {label}') def bne(self, rsrc1, src2, label): ''' diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 2dc7f01b..7890703e 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -30,6 +30,18 @@ def build_types(self, types): for idx, typex in enumerate(types): self.types_offsets[typex.name] = TypeData(idx, typex) + def get_offset(self, arg: str): + if arg in self.arguments or arg in self.local_vars: + offset = ( + self.arguments[arg] + if arg in self.arguments + else self.local_vars[arg] + ) * 4 + return self.mips.offset(reg.fp, offset) + else: + raise Exception( + f"load_memory: The direction {arg} isn't an address") + def get_pc(self, dst): label = self.get_label() end = self.get_label() @@ -338,9 +350,40 @@ def visit(self, node: ErrorNode): self.mips.li(reg.a0, 1) self.mips.syscall(17) + def copy_data(self, src, dst, length): + """ + length: fixed in bytes size. + """ + loop = self.get_label() + end = self.get_label() + + self.mips.move(reg.t0, src) + self.mips.move(reg.t1, dst) + self.mips.move(reg.t3, length) # i = length + + self.mips.label(loop) + + self.mips.lb(reg.t2, self.mips.offset(reg.t0)) + self.mips.sb(reg.t2, self.mips.offset(reg.t1)) + + self.mips.addi(reg.t0, reg.t0, 2) + self.mips.addi(reg.t1, reg.t1, 2) + + self.mips.addi(reg.t3, reg.t3, -1) # i -- + + self.mips.beqz(reg.t3, end) + self.mips.j(loop) + + self.mips.label(end) + @visitor.when(CopyNode) def visit(self, node): - pass + dst = self.get_offset(node.dest) + length = 0 # TODO: donde saco el size este? + self.mips.la(reg.s1, dst) + # copy data raw byte to byte + self.mips.li(reg.s3, length) + self.copy_data(reg.s0, reg.s1, reg.s3) @visitor.when(TypeNameNode) def visit(self, node: TypeNameNode): @@ -349,29 +392,178 @@ def visit(self, node: TypeNameNode): self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, self.data_size)) self.store_memory(reg.t1, node.dest) + def get_string_length(self, src, dst): + loop = self.get_label() + end = self.get_label() + + self.mips.move(reg.t0, src) + self.mips.li(reg.t1, 0) + + self.mips.label(loop) + + self.mips.lb(reg.t3, self.mips.offset(reg.t0)) + self.mips.beqz(reg.t3, end) + + self.mips.addi(reg.t1, reg.t1, 1) + self.mips.addi(reg.t0, reg.t0, 1) + + self.mips.j(loop) + self.mips.label(end) + + self.mips.move(dst, reg.t1) + @visitor.when(LengthNode) - def visit(self, node): - pass + def visit(self, node: LengthNode): + self.mips.comment("LengthNode") + self.load_memory(reg.s1, node.msg) + self.get_string_length(reg.s1, reg.s0) + self.store_memory(reg.s0, node.dest) + + def copy_str(self, src, dst, result): + loop = self.get_label() + end = self.get_label() + + self.mips.move(reg.t0, src) + self.mips.move(reg.t1, dst) + + self.mips.label(loop) + + self.mips.lb(reg.t2, self.mips.offset(reg.t0)) + self.mips.sb(reg.t2, self.mips.offset(reg.t1)) + + self.mips.beqz(reg.t2, end) + + self.mips.addi(reg.t0, reg.t0, 1) + self.mips.addi(reg.t1, reg.t1, 1) + + self.mips.j(loop) + self.mips.label(end) + + self.mips.move(result, reg.t1) @visitor.when(ConcatNode) - def visit(self, node): - pass + def visit(self, node: ConcatNode): + self.load_memory(reg.s0, node.msg1) + self.load_memory(reg.s1, node.msg2) + + self.get_string_length(reg.s0, reg.s4) + self.get_string_length(reg.s1, reg.s5) + + # WARNING: Divide in 2, from half to byte + self.mips.add(reg.a0, reg.s4, reg.s5) + self.mips.sbrk() + self.mips.move(reg.s3, reg.v0) # The new space reserved + + self.copy_str(reg.s0, reg.s3, reg.v0) + self.copy_str(reg.s1, reg.v0, reg.v0) + + self.store_memory(reg.s3, node.dest) @visitor.when(StringEqualNode) - def visit(self, node): - pass + def visit(self, node: StringEqualNode): + end_label = self.get_label() + end_ok_label = self.get_label() + loop_label = self.get_label() + + self.load_memory(reg.s0, node.msg1) # load string address + self.load_memory(reg.s1, node.msg2) + + self.get_string_length(reg.s0, reg.s2) # load size of string + self.get_string_length(reg.s1, reg.s3) + + self.mips.move(reg.v0, reg.zero) # return 0 + # end and return 0 if size not equal + self.mips.bne(reg.s2, reg.s3, end_label) + + self.mips.move(reg.s2, reg.s0) # lets use temporal register + self.mips.move(reg.s3, reg.s1) + + self.mips.label(loop_label) + + self.mips.lb(reg.s4, self.mips.offset(reg.s2)) # load string character + self.mips.lb(reg.s5, self.mips.offset(reg.s3)) + + self.mips.bne(reg.s4, reg.s5, end_label) # if no equal then return 0 + + self.mips.addi(reg.s2, reg.s2, 1) # move next character + self.mips.addi(reg.s3, reg.s3, 1) + + self.mips.beqz( + reg.s4, end_ok_label + ) # if end the string return 1 (they are equal) + self.mips.j(loop_label) # continue loop + + self.mips.label(end_ok_label) + self.mips.li(reg.v0, 1) # return 1 + self.mips.label(end_label) + self.mips.store_memory(reg.v0, node.dest) # store value in dst @visitor.when(ConcatNode) def visit(self, node): - pass + self.load_memory(reg.s0, node.msg1) + self.load_memory(reg.s1, node.msg2) - @visitor.when(LoadNode) - def visit(self, node): - pass + self.get_string_length(reg.s0, reg.s4) + self.get_string_length(reg.s1, reg.s5) + + # WARNING: Divide in 2, from half to byte + self.mips.add(reg.a0, reg.s4, reg.s5) + self.mips.sbrk() + self.mips.move(reg.s3, reg.v0) # The new space reserved + + self.copy_str(reg.s0, reg.s3, reg.v0) + self.copy_str(reg.s1, reg.v0, reg.v0) + + self.store_memory(reg.s3, node.dest) + + # @visitor.when(LoadNode) + # def visit(self, node: LoadNode): + # self.load_memory(reg.t0, node.msg) + # self.store_memory(reg.t0, node.dest) + + def copy_substr(self, src, dst, length): + loop = self.get_label() + end = self.get_label() + + self.mips.move(reg.t0, src) + self.mips.move(reg.t1, dst) + + self.mips.move(reg.t3, length) # i = length + + self.mips.label(loop) + + self.mips.lb(reg.t2, self.mips.offset(reg.t0)) + self.mips.sb(reg.t2, self.mips.offset(reg.t1)) + + self.mips.addi(reg.t0, reg.t0, 1) + self.mips.addi(reg.t1, reg.t1, 1) + + self.mips.addi(reg.t3, reg.t3, -1) # i -- + + self.mips.beqz(reg.t3, end) + self.mips.j(loop) + + self.mips.label(end) + + self.mips.move(reg.t2, reg.zero) + self.mips.sb(reg.t2, self.mips.offset(reg.t1)) @visitor.when(SubstringNode) def visit(self, node): - pass + # self.mips.li(reg.a0, 10) + # self.mips.print_int() + self.load_memory(reg.s0, node.msg1) + self.load_memory(reg.s1, node.length) + self.load_memory(reg.s3, node.start) + + self.mips.add(reg.s0, reg.s0, reg.s3) + + self.mips.move(reg.a0, reg.s1) # allocate heap memory + # self.mips.print_int() + self.mips.sbrk() + self.copy_substr(reg.s0, reg.v0, reg.s1) + + self.store_memory(reg.v0, node.dest) @visitor.when(ToStrNode) def visit(self, node): diff --git a/src/main.py b/src/main.py index 4d3e2342..0e0354d1 100644 --- a/src/main.py +++ b/src/main.py @@ -64,12 +64,12 @@ cil = COOL_TO_CIL(checker.context) # cil = COOL_TO_CIL_VISITOR(checker.context) # sc = Scope() -# cil_ast = cil.visit(ast) -f_ast = Format().visit(ast) +cil_ast = cil.visit(ast) +# f_ast = Format().visit(ast) emsamb = CIL_TO_MIPS() -# emsamb.visit(cil_ast) +emsamb.visit(cil_ast) # m_ast = emsamb.mips.compile() -# f_ast = CIL_FORMATTER().visit(cil_ast) +f_ast = CIL_FORMATTER().visit(cil_ast) string_formatted = str(f_ast) output_file.write(string_formatted) # output_file.write(str(collect_errors)) diff --git a/src/test.cl b/src/test.cl index 2881a261..46688344 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,9 +1,7 @@ class Main inherits IO { main () : Object { - { - a <- 34; - } + "H" }; }; diff --git a/src/test.mips b/src/test.mips index a523e245..e69de29b 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,424 +0,0 @@ -.TYPES -type Object { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type String { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method length: function_length_at_String - method concat: function_concat_at_String - method substr: function_substr_at_String -} -type IO { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO -} -type Main { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method main: function_main_at_Main -} -type Complex { - attribute x - attribute y - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method init: function_init_at_Complex - method print: function_print_at_Complex - method reflect_0: function_reflect_0_at_Complex - method reflect_X: function_reflect_X_at_Complex - method reflect_Y: function_reflect_Y_at_Complex - method equal: function_equal_at_Complex - method x_value: function_x_value_at_Complex - method y_value: function_y_value_at_Complex -} - -.DATA -data_0 = "=(n" -data_1 = "=)n" -data_2 = "=(n" -data_3 = "=)n" -data_4 = "I" -data_5 = "+" - -.CODE -function function_abort_at_Object { - PARAM self - - - - ERROR 0 -} -function function_copy_at_Object { - PARAM self - - LOCAL local_copy_at_Object_internal_0 - - local_copy_at_Object_internal_0 = COPY self - RETURN local_copy_at_Object_internal_0 -} -function function_type_name_at_Object { - PARAM self - - LOCAL local_type_name_at_Object_internal_0 - LOCAL local_type_name_at_Object_internal_1 - - local_type_name_at_Object_internal_1 = TYPEOF self - local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 - RETURN local_type_name_at_Object_internal_0 -} -function function_length_at_String { - PARAM self - - LOCAL local_length_at_String_internal_0 - - local_length_at_String_internal_0 = LENGTH self - RETURN local_length_at_String_internal_0 -} -function function_concat_at_String { - PARAM self - PARAM string - - LOCAL local_concat_at_String_internal_0 - - local_concat_at_String_internal_0 = CONCAT self string - RETURN local_concat_at_String_internal_0 -} -function function_substr_at_String { - PARAM self - PARAM start - PARAM length - - LOCAL local_substr_at_String_internal_0 - - local_substr_at_String_internal_0 = SUBSTRING self start length - RETURN local_substr_at_String_internal_0 -} -function function_out_string_at_IO { - - - LOCAL local_out_string_at_IO_internal_0 - - PRINT local_out_string_at_IO_internal_0 -} -function function_in_string_at_IO { - - - LOCAL local_in_string_at_IO_internal_0 - - local_in_string_at_IO_internal_0 = READ - RETURN local_in_string_at_IO_internal_0 -} -function function_out_int_at_IO { - PARAM int_val - - LOCAL local_out_int_at_IO_internal_0 - - local_out_int_at_IO_internal_0 = STR int_val - PRINT local_out_int_at_IO_internal_0 -} -function function_in_int_at_IO { - - - LOCAL local_in_int_at_IO_internal_0 - LOCAL local_in_int_at_IO_internal_1 - - local_in_int_at_IO_internal_0 = READ - local_in_int_at_IO_internal_1 = INT local_in_int_at_IO_internal_0 - RETURN local_in_int_at_IO_internal_1 -} -function entry { - - - LOCAL local__internal_0 - LOCAL local__internal_1 - - local__internal_0 = ALLOCATE Main - ARG local__internal_0 - local__internal_1 = CALL function_main_at_Main -} -function function_main_at_Main { - PARAM self - - LOCAL local_main_at_Main_internal_0 - LOCAL local_main_at_Main_internal_1 - LOCAL local_main_at_Main_internal_2 - LOCAL local_main_at_Main_internal_3 - LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_internal_5 - LOCAL local_main_at_Main_internal_6 - LOCAL local_main_at_Main_internal_7 - LOCAL local_main_at_Main_internal_8 - LOCAL local_main_at_Main_internal_9 - LOCAL local_main_at_Main_internal_10 - LOCAL local_main_at_Main_internal_11 - LOCAL local_main_at_Main_internal_12 - LOCAL local_main_at_Main_internal_13 - LOCAL local_main_at_Main_internal_14 - LOCAL local_main_at_Main_internal_15 - LOCAL local_main_at_Main_internal_16 - LOCAL local_main_at_Main_internal_17 - LOCAL local_main_at_Main_internal_18 - LOCAL local_main_at_Main_internal_19 - LOCAL local_main_at_Main_internal_20 - - ARG 1 - ARG 1 - local_main_at_Main_internal_1 = ALLOCATE Complex - SETATTR self x 0 - SETATTR self y 0 - ARG local_main_at_Main_internal_1 - local_main_at_Main_internal_0 = CALL function_init_at_Complex - ARG c - local_main_at_Main_internal_4 = CALL function_reflect_X_at_Complex - ARG c - local_main_at_Main_internal_5 = CALL function_reflect_0_at_Complex - local_main_at_Main_internal_6 = local_main_at_Main_internal_4 == local_main_at_Main_internal_5 - IF local_main_at_Main_internal_6 GOTO TRUE - local_main_at_Main_internal_9 = LOAD data_0 - ARG local_main_at_Main_internal_9 - ARG self - local_main_at_Main_internal_8 = VCALL Main out_string - local_main_at_Main_internal_7 = local_main_at_Main_internal_8 - GOTO END - LABEL TRUE - local_main_at_Main_internal_11 = LOAD data_1 - ARG local_main_at_Main_internal_11 - ARG self - local_main_at_Main_internal_10 = VCALL Main out_string - local_main_at_Main_internal_7 = local_main_at_Main_internal_10 - LABEL END - ARG c - local_main_at_Main_internal_13 = CALL function_reflect_0_at_Complex - ARG local_main_at_Main_internal_13 - ARG c - local_main_at_Main_internal_15 = CALL function_reflect_X_at_Complex - ARG local_main_at_Main_internal_15 - local_main_at_Main_internal_14 = CALL function_reflect_Y_at_Complex - ARG local_main_at_Main_internal_14 - local_main_at_Main_internal_12 = CALL function_equal_at_Complex - IF local_main_at_Main_internal_12 GOTO TRUE - local_main_at_Main_internal_18 = LOAD data_2 - ARG local_main_at_Main_internal_18 - ARG self - local_main_at_Main_internal_17 = VCALL Main out_string - local_main_at_Main_internal_16 = local_main_at_Main_internal_17 - GOTO END - LABEL TRUE - local_main_at_Main_internal_20 = LOAD data_3 - ARG local_main_at_Main_internal_20 - ARG self - local_main_at_Main_internal_19 = VCALL Main out_string - local_main_at_Main_internal_16 = local_main_at_Main_internal_19 - LABEL END - local_main_at_Main_internal_3 = local_main_at_Main_internal_16 - local_main_at_Main_internal_2 = local_main_at_Main_internal_3 - RETURN local_main_at_Main_internal_2 -} -function function_init_at_Complex { - PARAM self - PARAM a - PARAM b - - LOCAL local_init_at_Complex_internal_0 - LOCAL local_init_at_Complex_internal_1 - LOCAL local_init_at_Complex_internal_2 - LOCAL local_init_at_Complex_internal_3 - LOCAL local_init_at_Complex_internal_4 - LOCAL local_init_at_Complex_internal_5 - LOCAL local_init_at_Complex_internal_6 - - local_init_at_Complex_internal_1 = GETATTR self x - local_init_at_Complex_internal_2 = GETATTR self a - local_init_at_Complex_internal_3 = local_init_at_Complex_internal_1 == local_init_at_Complex_internal_2 - local_init_at_Complex_internal_4 = GETATTR self y - local_init_at_Complex_internal_5 = GETATTR self b - local_init_at_Complex_internal_6 = local_init_at_Complex_internal_4 == local_init_at_Complex_internal_5 - local_init_at_Complex_internal_0 = self - RETURN local_init_at_Complex_internal_0 -} -function function_print_at_Complex { - PARAM self - - LOCAL local_print_at_Complex_internal_0 - LOCAL local_print_at_Complex_internal_1 - LOCAL local_print_at_Complex_internal_2 - LOCAL local_print_at_Complex_internal_3 - LOCAL local_print_at_Complex_internal_4 - LOCAL local_print_at_Complex_internal_5 - LOCAL local_print_at_Complex_internal_6 - LOCAL local_print_at_Complex_internal_7 - LOCAL local_print_at_Complex_internal_8 - LOCAL local_print_at_Complex_internal_9 - LOCAL local_print_at_Complex_internal_10 - LOCAL local_print_at_Complex_internal_11 - LOCAL local_print_at_Complex_internal_12 - - local_print_at_Complex_internal_0 = GETATTR self y - local_print_at_Complex_internal_1 = local_print_at_Complex_internal_0 == 0 - IF local_print_at_Complex_internal_1 GOTO TRUE - local_print_at_Complex_internal_4 = LOAD data_4 - ARG local_print_at_Complex_internal_4 - local_print_at_Complex_internal_6 = GETATTR self y - ARG local_print_at_Complex_internal_6 - local_print_at_Complex_internal_8 = LOAD data_5 - ARG local_print_at_Complex_internal_8 - local_print_at_Complex_internal_10 = GETATTR self x - ARG local_print_at_Complex_internal_10 - ARG self - local_print_at_Complex_internal_9 = VCALL Complex out_int - ARG local_print_at_Complex_internal_9 - local_print_at_Complex_internal_7 = CALL function_out_string_at_Complex - ARG local_print_at_Complex_internal_7 - local_print_at_Complex_internal_5 = CALL function_out_int_at_Complex - ARG local_print_at_Complex_internal_5 - local_print_at_Complex_internal_3 = CALL function_out_string_at_Complex - local_print_at_Complex_internal_2 = local_print_at_Complex_internal_3 - GOTO END - LABEL TRUE - local_print_at_Complex_internal_12 = GETATTR self x - ARG local_print_at_Complex_internal_12 - ARG self - local_print_at_Complex_internal_11 = VCALL Complex out_int - local_print_at_Complex_internal_2 = local_print_at_Complex_internal_11 - LABEL END - RETURN local_print_at_Complex_internal_2 -} -function function_reflect_0_at_Complex { - PARAM self - - LOCAL local_reflect_0_at_Complex_internal_0 - LOCAL local_reflect_0_at_Complex_internal_1 - LOCAL local_reflect_0_at_Complex_internal_2 - LOCAL local_reflect_0_at_Complex_internal_3 - LOCAL local_reflect_0_at_Complex_internal_4 - LOCAL local_reflect_0_at_Complex_internal_5 - LOCAL local_reflect_0_at_Complex_internal_6 - LOCAL local_reflect_0_at_Complex_internal_7 - LOCAL local_reflect_0_at_Complex_internal_8 - - local_reflect_0_at_Complex_internal_1 = GETATTR self x - local_reflect_0_at_Complex_internal_3 = GETATTR self x - local_reflect_0_at_Complex_internal_2 = COMPLEMENT local_reflect_0_at_Complex_internal_3 - local_reflect_0_at_Complex_internal_4 = local_reflect_0_at_Complex_internal_1 == local_reflect_0_at_Complex_internal_2 - local_reflect_0_at_Complex_internal_5 = GETATTR self y - local_reflect_0_at_Complex_internal_7 = GETATTR self y - local_reflect_0_at_Complex_internal_6 = COMPLEMENT local_reflect_0_at_Complex_internal_7 - local_reflect_0_at_Complex_internal_8 = local_reflect_0_at_Complex_internal_5 == local_reflect_0_at_Complex_internal_6 - local_reflect_0_at_Complex_internal_0 = self - RETURN local_reflect_0_at_Complex_internal_0 -} -function function_reflect_X_at_Complex { - PARAM self - - LOCAL local_reflect_X_at_Complex_internal_0 - LOCAL local_reflect_X_at_Complex_internal_1 - LOCAL local_reflect_X_at_Complex_internal_2 - LOCAL local_reflect_X_at_Complex_internal_3 - LOCAL local_reflect_X_at_Complex_internal_4 - - local_reflect_X_at_Complex_internal_1 = GETATTR self y - local_reflect_X_at_Complex_internal_3 = GETATTR self y - local_reflect_X_at_Complex_internal_2 = COMPLEMENT local_reflect_X_at_Complex_internal_3 - local_reflect_X_at_Complex_internal_4 = local_reflect_X_at_Complex_internal_1 == local_reflect_X_at_Complex_internal_2 - local_reflect_X_at_Complex_internal_0 = self - RETURN local_reflect_X_at_Complex_internal_0 -} -function function_reflect_Y_at_Complex { - PARAM self - - LOCAL local_reflect_Y_at_Complex_internal_0 - LOCAL local_reflect_Y_at_Complex_internal_1 - LOCAL local_reflect_Y_at_Complex_internal_2 - LOCAL local_reflect_Y_at_Complex_internal_3 - LOCAL local_reflect_Y_at_Complex_internal_4 - - local_reflect_Y_at_Complex_internal_1 = GETATTR self x - local_reflect_Y_at_Complex_internal_3 = GETATTR self x - local_reflect_Y_at_Complex_internal_2 = COMPLEMENT local_reflect_Y_at_Complex_internal_3 - local_reflect_Y_at_Complex_internal_4 = local_reflect_Y_at_Complex_internal_1 == local_reflect_Y_at_Complex_internal_2 - local_reflect_Y_at_Complex_internal_0 = self - RETURN local_reflect_Y_at_Complex_internal_0 -} -function function_equal_at_Complex { - PARAM self - PARAM d - - LOCAL local_equal_at_Complex_internal_0 - LOCAL local_equal_at_Complex_internal_1 - LOCAL local_equal_at_Complex_internal_2 - LOCAL local_equal_at_Complex_internal_3 - LOCAL local_equal_at_Complex_internal_4 - LOCAL local_equal_at_Complex_internal_5 - LOCAL local_equal_at_Complex_internal_6 - LOCAL local_equal_at_Complex_internal_7 - LOCAL local_equal_at_Complex_internal_8 - LOCAL local_equal_at_Complex_internal_9 - - local_equal_at_Complex_internal_0 = GETATTR self x - local_equal_at_Complex_internal_2 = GETATTR self d - ARG local_equal_at_Complex_internal_2 - local_equal_at_Complex_internal_1 = CALL function_x_value_at_Complex - local_equal_at_Complex_internal_3 = local_equal_at_Complex_internal_0 == local_equal_at_Complex_internal_1 - IF local_equal_at_Complex_internal_3 GOTO TRUE - local_equal_at_Complex_internal_4 = 0 - GOTO END - LABEL TRUE - local_equal_at_Complex_internal_5 = GETATTR self y - local_equal_at_Complex_internal_7 = GETATTR self d - ARG local_equal_at_Complex_internal_7 - local_equal_at_Complex_internal_6 = CALL function_y_value_at_Complex - local_equal_at_Complex_internal_8 = local_equal_at_Complex_internal_5 == local_equal_at_Complex_internal_6 - IF local_equal_at_Complex_internal_8 GOTO TRUE - local_equal_at_Complex_internal_9 = 0 - GOTO END - LABEL TRUE - local_equal_at_Complex_internal_9 = 1 - LABEL END - local_equal_at_Complex_internal_4 = local_equal_at_Complex_internal_9 - LABEL END - RETURN local_equal_at_Complex_internal_4 -} -function function_x_value_at_Complex { - PARAM self - - LOCAL local_x_value_at_Complex_internal_0 - - local_x_value_at_Complex_internal_0 = GETATTR self x - RETURN local_x_value_at_Complex_internal_0 -} -function function_y_value_at_Complex { - PARAM self - - LOCAL local_y_value_at_Complex_internal_0 - - local_y_value_at_Complex_internal_0 = GETATTR self y - RETURN local_y_value_at_Complex_internal_0 -} \ No newline at end of file From 9d943beb38f5203c7234c072f409cb67dc27a442 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 30 Nov 2020 20:04:14 -0500 Subject: [PATCH 069/191] all mips nodes done...still not test passing --- src/engine/codegen/cil.py | 14 +- src/engine/codegen/cil_ast.py | 22 +- src/engine/codegen/cil_format.py | 24 +- src/engine/codegen/to_mips.py | 36 +- src/main.py | 6 +- src/test.mips | 2275 ++++++++++++++++++++++++++++++ 6 files changed, 2326 insertions(+), 51 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index e361273c..a37eae7f 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -127,7 +127,7 @@ def define_io_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) str_val = self.define_internal_local() - self.register_instruction(PrintNode(str_val)) + self.register_instruction(PrintStrNode(str_val)) # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None @@ -136,7 +136,7 @@ def define_io_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) dest = self.define_internal_local() - self.register_instruction(ReadNode(dest)) + self.register_instruction(ReadStrNode(dest)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None @@ -144,10 +144,8 @@ def define_io_type(self): type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) - dest = self.define_internal_local() int_val = self.register_param(VariableInfo('int_val', None)) - self.register_instruction(ToStrNode(dest, int_val)) - self.register_instruction(PrintNode(dest)) + self.register_instruction(PrintIntNode(int_val)) # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None @@ -156,10 +154,8 @@ def define_io_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) dest = self.define_internal_local() - int_val = self.define_internal_local() - self.register_instruction(ReadNode(dest)) - self.register_instruction(ToIntNode(int_val, dest)) - self.register_instruction(ReturnNode(int_val)) + self.register_instruction(ReadIntNode(dest)) + self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None self.current_type = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 8616f5e3..5a9e73cd 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -225,26 +225,24 @@ def __init__(self, dest, msg1, start, length): self.length = length -class ToStrNode(InstructionNode): - def __init__(self, dest, ivalue): - self.dest = dest - self.ivalue = ivalue +class PrintStrNode(InstructionNode): + def __init__(self, str_addr): + self.str_addr = str_addr -class ToIntNode(InstructionNode): - def __init__(self, dest, msg): - self.dest = dest - self.msg = msg +class PrintIntNode(InstructionNode): + def __init__(self, str_addr): + self.str_addr = str_addr -class ReadNode(InstructionNode): +class ReadIntNode(InstructionNode): def __init__(self, dest): self.dest = dest -class PrintNode(InstructionNode): - def __init__(self, str_addr): - self.str_addr = str_addr +class ReadStrNode(InstructionNode): + def __init__(self, dest): + self.dest = dest ################# nodes que me tengo que definir ############## diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 14cca39a..e5c03f40 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -87,13 +87,13 @@ def visit(self, node: ArgNode): def visit(self, node: ReturnNode): return f'RETURN {node.value if node.value is not None else ""}' - @visitor.when(ReadNode) - def visit(self, node: ReadNode): - return f'{node.dest} = READ' + @visitor.when(ReadStrNode) + def visit(self, node: ReadStrNode): + return f'{node.dest} = READSTR' - @visitor.when(PrintNode) - def visit(self, node: PrintNode): - return f'PRINT {node.str_addr}' + @visitor.when(PrintStrNode) + def visit(self, node: PrintStrNode): + return f'PRINTSTR {node.str_addr}' @visitor.when(LoadNode) def visit(self, node: LoadNode): @@ -115,13 +115,13 @@ def visit(self, node: ConcatNode): def visit(self, node: SubstringNode): return f'{node.dest} = SUBSTRING {node.msg1} {node.start} {node.length}' - @visitor.when(ToStrNode) - def visit(self, node: ToStrNode): - return f'{node.dest} = STR {node.ivalue}' + @visitor.when(ReadIntNode) + def visit(self, node: ReadIntNode): + return f'{node.dest} = READINT' - @visitor.when(ToIntNode) - def visit(self, node: ToIntNode): - return f'{node.dest} = INT {node.msg}' + @visitor.when(PrintIntNode) + def visit(self, node: PrintIntNode): + return f'PRINTINT {node.str_addr}' @visitor.when(GetAttribNode) def visit(self, node: GetAttribNode): diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 7890703e..f10d4cd2 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -516,10 +516,9 @@ def visit(self, node): self.store_memory(reg.s3, node.dest) - # @visitor.when(LoadNode) - # def visit(self, node: LoadNode): - # self.load_memory(reg.t0, node.msg) - # self.store_memory(reg.t0, node.dest) + @visitor.when(LoadNode) + def visit(self, node: LoadNode): + self.load_memory(reg.t0, node.dest) def copy_substr(self, src, dst, length): loop = self.get_label() @@ -565,22 +564,29 @@ def visit(self, node): self.store_memory(reg.v0, node.dest) - @visitor.when(ToStrNode) + @visitor.when(ReadStrNode) def visit(self, node): - pass + self.mips.li(reg.a0, 1024) + self.mips.sbrk() + self.mips.move(reg.a0, reg.v0) + self.store_memory(reg.v0, node.dest) + self.mips.li(reg.a1, 1024) # Change this later + self.mips.read_string() - @visitor.when(ToIntNode) - def visit(self, node): - pass + @visitor.when(PrintStrNode) + def visit(self, node: PrintStrNode): # noqa: F811 + self.load_memory(reg.a0, node.str_addr) + self.mips.print_str() - @visitor.when(ReadNode) - def visit(self, node): - pass + @visitor.when(ReadIntNode) + def visit(self, node: ReadIntNode): + self.mips.read_int() + self.store_memory(reg.v0, node.dest) - @visitor.when(PrintNode) - def visit(self, node: PrintNode): + @visitor.when(PrintIntNode) + def visit(self, node: PrintIntNode): self.load_memory(reg.a0, node.str_addr) - self.mips.print_str(node.str_addr) + self.mips.print_int() @visitor.when(ReturnNode) def visit(self, node: ReturnNode): diff --git a/src/main.py b/src/main.py index 0e0354d1..c458cfd5 100644 --- a/src/main.py +++ b/src/main.py @@ -68,9 +68,9 @@ # f_ast = Format().visit(ast) emsamb = CIL_TO_MIPS() emsamb.visit(cil_ast) -# m_ast = emsamb.mips.compile() -f_ast = CIL_FORMATTER().visit(cil_ast) -string_formatted = str(f_ast) +m_ast = emsamb.mips.compile() +# f_ast = CIL_FORMATTER().visit(cil_ast) +string_formatted = str(m_ast) output_file.write(string_formatted) # output_file.write(str(collect_errors)) # print(str(collect_errors)) diff --git a/src/test.mips b/src/test.mips index e69de29b..c38d7f33 100644 --- a/src/test.mips +++ b/src/test.mips @@ -0,0 +1,2275 @@ +.data +data_0 +.asciiz "H" +data_1 +.asciiz "A" +data_2 +.asciiz "B" +data_3 +.asciiz "C" +data_4 +.asciiz "E" +.text +main: +jal entry + +li $v0, 10 +syscall +function_abort_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_copy_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $s3, 0 +move $t0, $s0 +move $t1, $s1 +move $t3, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 2 +addi $t1, $t1, 2 +addi $t3, $t3, -1 +beqz $t3, mip_label_0 +j mip_label_0 +mip_label_0: +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_type_name_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# TypeOfNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, $s0 +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +# TypeNameNode +lw $t8, -8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 8($t0) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +srl $t9, $t1, 16 +sw $t9, 0($t8) +sw $t1, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_length_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# LengthNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s0, $t1 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_concat_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_substr_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, 24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +add $s0, $s0, $s3 +move $a0, $s1 +li $v0, 9 +syscall +move $t0, $s0 +move $t1, $v0 +move $t3, $s1 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 1 +addi $t1, $t1, 1 +addi $t3, $t3, -1 +beqz $t3, mip_label_0 +j mip_label_0 +mip_label_0: +move $t2, $zero +sb $t2, 0($t1) +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $a0, 1024 +li $v0, 9 +syscall +move $a0, $v0 +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $a1, 1024 +li $v0, 8 +syscall +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +entry: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $a0, 8 +li $v0, 9 +syscall +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $t0, 3 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# ArgNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# StaticCallNode +jal function_main_at_Main +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_m_at_A: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_A: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# ReturnNode +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_m_at_B: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_C: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_f_at_E: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 + +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra \ No newline at end of file From f85794355451750ec5e0f687c2bac7e982868b7a Mon Sep 17 00:00:00 2001 From: stdevlag Date: Mon, 30 Nov 2020 20:42:37 -0500 Subject: [PATCH 070/191] [grammar] try --- src/engine/parser.py | 37 +++++++++++++++++++++++++++---------- src/main.py | 8 +++++++- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/engine/parser.py b/src/engine/parser.py index 99f88e64..2f0716d0 100644 --- a/src/engine/parser.py +++ b/src/engine/parser.py @@ -181,8 +181,8 @@ class BoolNode(AtomicNode): feature_list, feature = CoolGrammar.NonTerminals(' ') param_list, param = CoolGrammar.NonTerminals(' ') expr, member_call, expr_list, let_list, case_list = CoolGrammar.NonTerminals(' ') -arith, arith_2, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') -atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') +sub_expr, arith, arith_2, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') +atom, pre_atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') # terminals classx, inherits = CoolGrammar.Terminals('class inherits') @@ -247,7 +247,15 @@ class BoolNode(AtomicNode): expr %= expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) expr %= expr + less + arith, lambda h, s: LessNode(s[1], s[3]) expr %= expr + equal + arith, lambda h, s: EqualNode(s[1], s[3]) -expr %= arith, lambda h, s: s[1] +expr %= sub_expr, lambda h, s: s[1] + +sub_expr %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) +sub_expr %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) +sub_expr %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) +sub_expr %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) +sub_expr %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) +sub_expr %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) +sub_expr %= arith, lambda h, s: s[1] # ??? arith %= notx + arith_2, lambda h, s: NotNode(s[2]) @@ -271,13 +279,22 @@ class BoolNode(AtomicNode): factor_2 %= compl + atom, lambda h, s: ComplementNode(s[2]) factor_2 %= atom, lambda h, s: s[1] +# +# pre_atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) +# pre_atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) +# pre_atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) +# pre_atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) +# pre_atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) +# pre_atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) +# pre_atom %= atom, lambda h, s: s[1] + # () ??? -atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) -atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) -atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) -atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) -atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) -atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) +# atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) +# atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) +# atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) +# atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) +# atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) +# atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) # ??? atom %= atom + func_call, lambda h, s: FunctionCallNode(s[1], *s[2]) atom %= member_call, lambda h, s: s[1] @@ -308,4 +325,4 @@ class BoolNode(AtomicNode): if __name__ == '__main__': if CoolParser.is_lr1: print('The grammar is LR1') - print(CoolGrammar) \ No newline at end of file + print(CoolGrammar) diff --git a/src/main.py b/src/main.py index 7b1dd2d6..53433e3b 100644 --- a/src/main.py +++ b/src/main.py @@ -25,9 +25,15 @@ parse, operations = CoolParser(tokens) - ast = evaluate_reverse_parse(parse, operations, tokens) +#print(ast) + +fmatter = Format() +tree = fmatter.visit(ast, 0) + +print(tree) + collect_errors = [] collect = Collector(collect_errors) collect.visit(ast) From 56e4df0a3223adc2c16aae0745346946954f0866 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 30 Nov 2020 20:52:51 -0500 Subject: [PATCH 071/191] comment fixed --- src/engine/codegen/to_cil.py | 1 + src/engine/codegen/to_mips.py | 46 +++++++++++++++-------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index c1e5498e..05ba7270 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -50,6 +50,7 @@ def visit(self, node: cool.ProgramNode, scope=None): self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() + self.current_type = 'Main' self.register_instruction(AllocateNode(instance, 'Main')) self.init_class_attr(scope, 'Main', instance) self.register_instruction(ArgNode(instance)) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index f10d4cd2..65d0d724 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -449,10 +449,9 @@ def visit(self, node: ConcatNode): self.get_string_length(reg.s0, reg.s4) self.get_string_length(reg.s1, reg.s5) - # WARNING: Divide in 2, from half to byte self.mips.add(reg.a0, reg.s4, reg.s5) self.mips.sbrk() - self.mips.move(reg.s3, reg.v0) # The new space reserved + self.mips.move(reg.s3, reg.v0) self.copy_str(reg.s0, reg.s3, reg.v0) self.copy_str(reg.s1, reg.v0, reg.v0) @@ -465,38 +464,37 @@ def visit(self, node: StringEqualNode): end_ok_label = self.get_label() loop_label = self.get_label() - self.load_memory(reg.s0, node.msg1) # load string address + self.load_memory(reg.s0, node.msg1) self.load_memory(reg.s1, node.msg2) - self.get_string_length(reg.s0, reg.s2) # load size of string + self.get_string_length(reg.s0, reg.s2) self.get_string_length(reg.s1, reg.s3) - self.mips.move(reg.v0, reg.zero) # return 0 - # end and return 0 if size not equal + self.mips.move(reg.v0, reg.zero) self.mips.bne(reg.s2, reg.s3, end_label) - self.mips.move(reg.s2, reg.s0) # lets use temporal register + self.mips.move(reg.s2, reg.s0) self.mips.move(reg.s3, reg.s1) self.mips.label(loop_label) - self.mips.lb(reg.s4, self.mips.offset(reg.s2)) # load string character + self.mips.lb(reg.s4, self.mips.offset(reg.s2)) self.mips.lb(reg.s5, self.mips.offset(reg.s3)) - self.mips.bne(reg.s4, reg.s5, end_label) # if no equal then return 0 + self.mips.bne(reg.s4, reg.s5, end_label) - self.mips.addi(reg.s2, reg.s2, 1) # move next character + self.mips.addi(reg.s2, reg.s2, 1) self.mips.addi(reg.s3, reg.s3, 1) self.mips.beqz( reg.s4, end_ok_label - ) # if end the string return 1 (they are equal) - self.mips.j(loop_label) # continue loop + ) + self.mips.j(loop_label) self.mips.label(end_ok_label) - self.mips.li(reg.v0, 1) # return 1 + self.mips.li(reg.v0, 1) self.mips.label(end_label) - self.mips.store_memory(reg.v0, node.dest) # store value in dst + self.mips.store_memory(reg.v0, node.dest) @visitor.when(ConcatNode) def visit(self, node): @@ -506,10 +504,9 @@ def visit(self, node): self.get_string_length(reg.s0, reg.s4) self.get_string_length(reg.s1, reg.s5) - # WARNING: Divide in 2, from half to byte self.mips.add(reg.a0, reg.s4, reg.s5) self.mips.sbrk() - self.mips.move(reg.s3, reg.v0) # The new space reserved + self.mips.move(reg.s3, reg.v0) self.copy_str(reg.s0, reg.s3, reg.v0) self.copy_str(reg.s1, reg.v0, reg.v0) @@ -527,7 +524,7 @@ def copy_substr(self, src, dst, length): self.mips.move(reg.t0, src) self.mips.move(reg.t1, dst) - self.mips.move(reg.t3, length) # i = length + self.mips.move(reg.t3, length) self.mips.label(loop) @@ -537,7 +534,7 @@ def copy_substr(self, src, dst, length): self.mips.addi(reg.t0, reg.t0, 1) self.mips.addi(reg.t1, reg.t1, 1) - self.mips.addi(reg.t3, reg.t3, -1) # i -- + self.mips.addi(reg.t3, reg.t3, -1) self.mips.beqz(reg.t3, end) self.mips.j(loop) @@ -549,16 +546,13 @@ def copy_substr(self, src, dst, length): @visitor.when(SubstringNode) def visit(self, node): - # self.mips.li(reg.a0, 10) - # self.mips.print_int() self.load_memory(reg.s0, node.msg1) self.load_memory(reg.s1, node.length) self.load_memory(reg.s3, node.start) self.mips.add(reg.s0, reg.s0, reg.s3) - self.mips.move(reg.a0, reg.s1) # allocate heap memory - # self.mips.print_int() + self.mips.move(reg.a0, reg.s1) self.mips.sbrk() self.copy_substr(reg.s0, reg.v0, reg.s1) @@ -570,13 +564,13 @@ def visit(self, node): self.mips.sbrk() self.mips.move(reg.a0, reg.v0) self.store_memory(reg.v0, node.dest) - self.mips.li(reg.a1, 1024) # Change this later + self.mips.li(reg.a1, 1024) self.mips.read_string() @visitor.when(PrintStrNode) - def visit(self, node: PrintStrNode): # noqa: F811 + def visit(self, node: PrintStrNode): self.load_memory(reg.a0, node.str_addr) - self.mips.print_str() + self.mips.print_str(node.str_addr) @visitor.when(ReadIntNode) def visit(self, node: ReadIntNode): @@ -586,7 +580,7 @@ def visit(self, node: ReadIntNode): @visitor.when(PrintIntNode) def visit(self, node: PrintIntNode): self.load_memory(reg.a0, node.str_addr) - self.mips.print_int() + self.mips.print_int(node.str_addr) @visitor.when(ReturnNode) def visit(self, node: ReturnNode): From ad60685bd5d63da458b72a139470c306aa4f2b5d Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Mon, 30 Nov 2020 23:38:43 -0500 Subject: [PATCH 072/191] Report redaction --- Informe/informe.pdf | Bin 0 -> 120864 bytes Informe/informe.sty | 309 ++++++++++++++++++++++++++++++++++++++++++++ Informe/informe.tex | 179 +++++++++++++++++++++++++ 3 files changed, 488 insertions(+) create mode 100644 Informe/informe.pdf create mode 100644 Informe/informe.sty create mode 100644 Informe/informe.tex diff --git a/Informe/informe.pdf b/Informe/informe.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a79194961a1e66eed55cb025cefbb1b900b3ddaa GIT binary patch literal 120864 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

8AhH56|Zf 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\c@secnumdepth + \def\@svsec{}\else + \refstepcounter{#1}\edef\@svsec{\csname the#1\endcsname}\fi + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@ + \begingroup #6\relax + \@hangfrom{\hskip #3\relax\@svsec.\hskip 0.1em} + {\interlinepenalty \@M #8\par} + \endgroup + \csname #1mark\endcsname{#7}\addcontentsline + {toc}{#1}{\ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}\fi + #7}\else + \def\@svsechd{#6\hskip #3\@svsec #8\csname #1mark\endcsname + {#7}\addcontentsline + {toc}{#1}{\ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}\fi + #7}}\fi + \@xsect{#5}} + +\def\@sect#1#2#3#4#5#6[#7]#8{\ifnum #2>\c@secnumdepth + \def\@svsec{}\else + \refstepcounter{#1}\edef\@svsec{\csname the#1\endcsname\hskip 0.5em }\fi + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@ + \begingroup #6\relax + \@hangfrom{\hskip #3\relax\@svsec}{\interlinepenalty \@M #8\par} + \endgroup + \csname #1mark\endcsname{#7}\addcontentsline + {toc}{#1}{\ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}\fi + #7}\else + \def\@svsechd{#6\hskip #3\@svsec #8\csname #1mark\endcsname + {#7}\addcontentsline + {toc}{#1}{\ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}\fi + #7}}\fi + \@xsect{#5}} + +\def\thesection {\arabic{section}} +\def\thesubsection {\thesection.\arabic{subsection}} +\def\section{\@startsiction{section}{1}{\z@}{-0.24in}{0.10in} + {\large\bf\raggedright}} +\def\subsection{\@startsection{subsection}{2}{\z@}{-0.20in}{0.08in} + {\normalsize\bf\raggedright}} +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-0.18in}{0.08in} + {\normalsize\sc\raggedright}} +\def\paragraph{\@startsiction{paragraph}{4}{\z@}{1.5ex plus + 0.5ex minus .2ex}{-1em}{\normalsize\bf}} +\def\subparagraph{\@startsiction{subparagraph}{5}{\z@}{1.5ex plus + 0.5ex minus .2ex}{-1em}{\normalsize\bf}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% F O O T N O T E S +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Change the size of the footnote rule +% +% \renewcommand{\footnoterule}{\vspace{10pt}\hrule width 0mm} + +\long\def\@makefntext#1{\@setpar{\@@par\@tempdima \hsize + \advance\@tempdima-15pt\parshape \@ne 15pt \@tempdima}\par + \parindent 2em\noindent \hbox to \z@{\hss{\@thefnmark}. \hfil}#1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% A B S T R A C T +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% use \begin{abstract} .. \end{abstract} for abstracts. +\renewenvironment{abstract} +{\centerline{\large\bf Resumen}\vspace{0.7ex}% + \bgroup\leftskip 20pt\rightskip 20pt\small\noindent}% +{\par\egroup\vskip 0.25ex} + +\newenvironment{enabstract} +{\centerline{\large\bf \\Abstract}\vspace{0.7ex}% + \bgroup\leftskip 20pt\rightskip 20pt\small\noindent}% +{\par\egroup\vskip 0.25ex} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% KEYWORDS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% use \begin{keywords} .. \end{keywords} for keywordss. +\newenvironment{keywords} +{\bgroup\leftskip 20pt\rightskip 20pt \small\noindent{\bf \\Palabras Clave:} }% +{\par\egroup\vskip 0.25ex} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% TEMAS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Use \begin{topics} .. \end{topics} para los temas. +\newenvironment{topics} +{\bgroup\leftskip 20pt\rightskip 20pt \small\noindent{\bf Tema:} }% +{\par\egroup\vskip 0.25ex} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% FIRST PAGE, TITLE, AUTHOR +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Author information can be set in various styles: +% For several authors from the same institution: +% \author{Author 1 \and ... \and Author n \\ +% \addr{Address line} \\ ... \\ \addr{Address line}} +% if the names do not fit well on one line use +% Author 1 \\ {\bf Author 2} \\ ... \\ {\bf Author n} \\ +% To start a seperate ``row'' of authors use \AND, as in +% \author{Author 1 \\ \addr{Address line} \\ ... \\ \addr{Address line} +% \AND +% Author 2 \\ \addr{Address line} \\ ... \\ \addr{Address line} \And +% Author 3 \\ \addr{Address line} \\ ... \\ \addr{Address line}} + +% Title stuff, borrowed in part from aaai92.sty + +\newlength\aftertitskip \newlength\beforetitskip +\newlength\interauthorskip \newlength\aftermaketitskip + +%% Changeable parameters. +\setlength\aftertitskip{0.1in plus 0.2in minus 0.2in} +\setlength\beforetitskip{0.05in plus 0.08in minus 0.08in} +\setlength\interauthorskip{0.08in plus 0.1in minus 0.1in} +\setlength\aftermaketitskip{0.3in plus 0.1in minus 0.1in} + +%% overall definition of maketitle, @maketitle does the real work +\def\maketitle{\par + \begingroup + \def\thefootnote{\fnsymbol{footnote}} + \def\@makefnmark{\hbox to 0pt{$^{\@thefnmark}$\hss}} + \@maketitle \@thanks + \endgroup +\setcounter{footnote}{0} + \let\maketitle\relax \let\@maketitle\relax + \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax} + +\def\@startauthor{\noindent \normalsize\bf} +\def\@endauthor{} +\def\@starttutors{\noindent \small {\bf Tutor(es):~}} +\def\@endtutors{\normalsize} +\def\@maketitle{\vbox{\hsize\textwidth + \linewidth\hsize \vskip \beforetitskip + {\begin{center} \Large\bf \@title \par \end{center}} \vskip \aftertitskip + {\def\and{\unskip\enspace{\rm y}\enspace}% + \def\addr{\small\it}% + \def\email{\hfill\small\sc}% + \def\name{\normalsize\bf}% + \def\AND{\@endauthor\rm\hss \vskip \interauthorskip \@startauthor} + \@startauthor \@author \@endauthor} + + \vskip \aftermaketitskip + \noindent \@starttutors \@tutors \@endtutors + \vskip \aftermaketitskip +}} + +\newcommand\kernelmachines{(for {\sc{http://www.kernel-machines.org}})} +\def\tutors#1{\gdef\@tutors{#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% +%%% Pagestyle +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Defines the pagestyle for the title page. +%% Usage: \jcematcomheading{2009}{1-15}{Mat y Com}{Jane Q. Public and A. U. Thor} +%% \jcematcomheading{year}{pages}{Tribunal}{authors} + +\def\firstpageno#1{\setcounter{page}{#1}} + +\def\jcematcomheading#1#2#3{\def\ps@jmlrtps{\let\@mkboth\@gobbletwo% +\def\@oddhead{\scriptsize Compilación MatCom #1 % +\hfill Páginas #2}% +\def\@oddfoot{\scriptsize \copyright #1 #3. \hfill}% +\def\@evenhead{}\def\@evenfoot{}}% +\thispagestyle{jmlrtps}} + +%% Defines the pagestyle for the rest of the pages +%% Usage: \ShortHeadings{Minimizing Conflicts}{Minton et al} +%% \ShortHeadings{short title}{short authors} + +\def\ShortHeadings#1#2{\def\ps@jmlrps{\let\@mkboth\@gobbletwo% +\def\@oddhead{\hfill {\small\sc #1} \hfill}% +\def\@oddfoot{\hfill \small\rm \thepage \hfill}% +\def\@evenhead{\hfill {\small\sc #2} \hfill}% +\def\@evenfoot{\hfill \small\rm \thepage \hfill}}% +\pagestyle{jmlrps}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% MISCELLANY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Define macros for figure captions and table titles + +% Figurecaption prints the caption title flush left. +% \def\figurecaption#1#2{\noindent\hangindent 42pt +% \hbox to 36pt {\sl #1 \hfil} +% \ignorespaces #2} +% \def\figurecaption#1#2{\noindent\hangindent 46pt +% \hbox to 41pt {\small\sl #1 \hfil} +% \ignorespaces {\small #2}} +\def\figurecaption#1#2{\noindent\hangindent 40pt + \hbox to 36pt {\small\sl #1 \hfil} + \ignorespaces {\small #2}} +% Figurecenter prints the caption title centered. +\def\figurecenter#1#2{\centerline{{\sl #1} #2}} +\def\figurecenter#1#2{\centerline{{\small\sl #1} {\small #2}}} + +% +% Allow ``hanging indents'' in long captions +% +\long\def\@makecaption#1#2{ + \vskip 10pt + \setbox\@tempboxa\hbox{#1: #2} + \ifdim \wd\@tempboxa >\hsize % IF longer than one line: + \begin{list}{#1:}{ + \settowidth{\labelwidth}{#1:} + \setlength{\leftmargin}{\labelwidth} + \addtolength{\leftmargin}{\labelsep} + }\item #2 \end{list}\par % Output in quote mode + \else % ELSE center. + \hbox to\hsize{\hfil\box\@tempboxa\hfil} + \fi} + + +% Define strut macros for skipping spaces above and below text in a +% tabular environment. +\def\abovestrut#1{\rule[0in]{0in}{#1}\ignorespaces} +\def\belowstrut#1{\rule[-#1]{0in}{#1}\ignorespaces} + +% Acknowledgments +\long\def\acks#1{\vskip 0.3in\noindent{\large\bf Agradecimientos}\vskip 0.2in +\noindent #1} + +% Research Note +\long\def\researchnote#1{\noindent {\LARGE\it Research Note} #1} + +\renewcommand{\appendix}{\par + \setcounter{section}{0} + \setcounter{subsection}{0} + \def\thesection{\Alph{section}} +\def\section{\@ifnextchar*{\@startsiction{section}{1}{\z@}{-0.24in}{0.10in}% + {\large\bf\raggedright}}% +{\@startsiction{section}{1}{\z@}{-0.24in}{0.10in} + {\large\bf\raggedright Appendix\ }}}} + + + + diff --git a/Informe/informe.tex b/Informe/informe.tex new file mode 100644 index 00000000..0eb62b91 --- /dev/null +++ b/Informe/informe.tex @@ -0,0 +1,179 @@ +%=================================================================================== +% JORNADA CIENTÍFICA ESTUDIANTIL - MATCOM, UH +%=================================================================================== +% Esta plantilla ha sido diseñada para ser usada en los artículos de la +% Jornada Científica Estudiantil, MatCom. +% +% Por favor, siga las instrucciones de esta plantilla y rellene en las secciones +% correspondientes. +% +% NOTA: Necesitará el archivo 'jcematcom.sty' en la misma carpeta donde esté este +% archivo para poder utilizar esta plantila. +%=================================================================================== + + + +%=================================================================================== +% PREÁMBULO +%----------------------------------------------------------------------------------- +\documentclass[a4paper,10pt,twocolumn]{article} + +%=================================================================================== +% Paquetes +%----------------------------------------------------------------------------------- +\usepackage{amsmath} +\usepackage{amsfonts} +\usepackage{amssymb} +\usepackage{informe} +\usepackage[utf8]{inputenc} +\usepackage{listings} +\usepackage[pdftex]{hyperref} +%----------------------------------------------------------------------------------- +% Configuración +%----------------------------------------------------------------------------------- +\hypersetup{colorlinks,% + citecolor=black,% + filecolor=black,% + linkcolor=black,% + urlcolor=blue} + +%=================================================================================== + + + +%=================================================================================== +% Presentacion +%----------------------------------------------------------------------------------- +% Título +%----------------------------------------------------------------------------------- +\title{Informe de Entrega CoolCompiler 2020} + +%----------------------------------------------------------------------------------- +% Autores +%----------------------------------------------------------------------------------- +\author{\\ + \name Jorge Daniel Valle Días \email \href{mailto:jorge.valle@estudiantes.matcom.uh.cu}{jorge.valle@estudiantes.matcom.uh.cu} + \\ \addr Grupo C412 \AND + \name Leonel Alejandro Garc\'ia L\'opez \email \href{mailto:l.garcia3@estudiantes.matcom.uh.cu}{l.garcia3@estudiantes.matcom.uh.cu} + \\ \addr Grupo C412 \AND + \name Roberto Marti Cede\~no \email \href{mailto:r.marti@estudiantes.matcom.uh.cu}{r.marti@estudiantes.matcom.uh.cu} + \\ \addr Grupo C412 +} + +%----------------------------------------------------------------------------------- +% Tutores +%----------------------------------------------------------------------------------- +\tutors{\\ +Msc. Alejandro Piad Morffis, \emph{Facultad de Matemática y Computación, Universidad de La Habana}} + +%----------------------------------------------------------------------------------- +% Headings +%----------------------------------------------------------------------------------- +\jcematcomheading{\the\year}{1-\pageref{end}}{Jorge Daniel Valle Días, Leonel Alejandro Garc\'ia L\'opez, Roberto Marti Cede\~no} + +%----------------------------------------------------------------------------------- +\ShortHeadings{Ejemplo JCE}{Autores} +%=================================================================================== + + + +%=================================================================================== +% DOCUMENTO +%----------------------------------------------------------------------------------- +\begin{document} + +%----------------------------------------------------------------------------------- +% NO BORRAR ESTA LINEA! +%----------------------------------------------------------------------------------- +\twocolumn[ +%----------------------------------------------------------------------------------- + +\maketitle + +%=================================================================================== +% Resumen y Abstract +%----------------------------------------------------------------------------------- +\selectlanguage{spanish} % Para producir el documento en Español + +%----------------------------------------------------------------------------------- +% Resumen en Español +%----------------------------------------------------------------------------------- + + +\vspace{0.5cm} + +%----------------------------------------------------------------------------------- +% Palabras clave +%----------------------------------------------------------------------------------- + +%----------------------------------------------------------------------------------- +% Temas +%----------------------------------------------------------------------------------- +\begin{topics} + Compilación, Cool Language. +\end{topics} + + +%----------------------------------------------------------------------------------- +% NO BORRAR ESTAS LINEAS! +%----------------------------------------------------------------------------------- +\vspace{0.8cm} +] +%----------------------------------------------------------------------------------- + + +%=================================================================================== + +%=================================================================================== +% Introducción +%----------------------------------------------------------------------------------- +\section{Introducción}\label{sec:intro} +%----------------------------------------------------------------------------------- + El siguiente trabajo representa el informe sobre la confección del compilador. Para la confección del mismo se empleó el lenguaje python de programación. El proyecto se dividió en varias etapas: Análisis lexicográfico, sintáctico, semántico, código intermedio y generación de código de máquina. Es importante destacar que se reutilizaron en la medida de lo posible los archivos de clase práctica y los proyectos realizados en el curso previo de la asignatura. + +%=================================================================================== + + + +%=================================================================================== +% Desarrollo +%----------------------------------------------------------------------------------- +\section{Lexer}\label{sec:dev} +%----------------------------------------------------------------------------------- + En la fase de análisis lexicográfico se empleó la biblioteca ply, en especial su módulo lex. + Salvo en el caso de las cadenas de caracteres y los comentarios multi-línea, el resto de los tokens fueron procesados mediante expresiones regulares. Para el caso de las cadenas de caracteres y los comentarios multi-líneas se emplearon estados especiales exclusivos. + +\section{Parser} + La fase de análisis sintáctico ha sido una de las fases mas controversiales a la hora de la realización del proyecto. Se empleó en una primera fase el parser LR1 tomado de clase práctica y los proyectos previos de la asignatura. La gramática que se definió durante la primera entrega del proyecto contenía ambigüedades, las cuales fueron detectada comprobando las pruebas correspondientes a la parte de semántica. + + Dado el tiempo restante que se disponía para la entrega, el equipo decidió tratar de adelantar todas las funcionalidades posibles para minimizar los cambios después de la fecha de entrega. + + Actualmente se esta valorando la posibilidad de emplear el módulo yacc de ply para definir la gramática y evitar las ambigüedades que se desprenden de nuestra implementación inicial. + +\section{Análisis Semántico} + + La fase de análisis semántico se compuso por 3 recorridos del árbol de sintaxis abstracta derivado de la fase de análisis sintáctico que siguen el patrón visitor. + + \begin{description} + \item [Recolector de tipos:] Primer recorrido del ast, en el cual se conforman los tipos nativos y los definidos en el archivo de código a procesar. En este mismo recorrido también se detectan los problemas relacionados con la herencia cíclica. + \item [Constructor de tipos:] Segundo recorrido del ast, en el cual se construyen los tipos, se definen sus métodos y atributos. + \item [Verificador de tipos:] Tercer y ultimo recorrido del ast, en el cual se verifica la estructura de cada uno de los nodos del ast, este recorrido es el que mas abarca las reglas semánticas del lenguaje cool. + \end{description} + +\section{Código intermedio y código de máquina} + + El equipo decidió realizar una representación intermedia del lenguaje cool antes de pasara a la generación de código de máquina. Para ello se definieron 2 nuevos recorridos a árboles de sintaxis. + + \begin{description} + \item [Árbol de representación intermedia:] Cuarto recorrido del ast, en el cual se conforma la representación intermedia del árbol de código intermedio de cool. + \item [Constructor de código Mips:] Ultimo recorrido, en este caso del árbol de sintaxis de representación intermedia. Mediante el cual se genera el código a ejecutar en el microprocesador con arquitectura MIPS. + \end{description} + + + + +\label{end} + +\end{document} + +%=================================================================================== From bba66d7270df70095ff418995e0b90d40c2ddaf6 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Tue, 1 Dec 2020 04:45:51 -0500 Subject: [PATCH 073/191] [ply] grammar finalized --- src/engine/ast_parser.py | 187 +++++++++++++ src/engine/parser.py | 559 ++++++++++++++++----------------------- 2 files changed, 421 insertions(+), 325 deletions(-) create mode 100644 src/engine/ast_parser.py diff --git a/src/engine/ast_parser.py b/src/engine/ast_parser.py new file mode 100644 index 00000000..d2d47e26 --- /dev/null +++ b/src/engine/ast_parser.py @@ -0,0 +1,187 @@ + +# AST Classes +class Node: + pass + +class ProgramNode(Node): + def __init__(self, declarations): + self.declarations = declarations + self.line = declarations[0].line + self.column = declarations[0].column + +class DeclarationNode(Node): + pass + +class LetVariableDeclaration(DeclarationNode): + def __init__(self, idx, typex, expression=None): + self.id = idx + self.type = typex + self.expression = expression + self.line = self.idx.line + self.column = self.idx.column + +class CaseVariableDeclaration(DeclarationNode): + def __init__(self, idx, typex, expression=Node): + self.id = idx + self.type = typex + self.expression = expression + self.line = self.idx.line + self.column = self.idx.column + +class ClassDeclarationNode(DeclarationNode): + def __init__(self, idx, features, parent=None): + self.id = idx + self.parent = parent + self.features = features + self.line = idx.line + self.column = idx.column + +class AttrDeclarationNode(DeclarationNode): + def __init__(self, idx, typex, expression=None): + self.id = idx + self.type = typex + self.expression = expression + self.line = idx.line + self.column = idx.column + +class FuncDeclarationNode(DeclarationNode): + def __init__(self, idx, params, return_type, body): + self.id = idx + self.params = params + self.type = return_type + self.body = body + self.line = idx.line + self.column = idx.column + +class ExpressionNode(Node): + pass + +class IfThenElseNode(ExpressionNode): + def __init__(self, condition, if_body, else_body): + self.condition = condition + self.if_body = if_body + self.else_body = else_body + self.line = condition.line + self.column = condition.column + +class WhileLoopNode(ExpressionNode): + def __init__(self, condition, body): + self.condition = condition + self.body = body + self.line = condition.line + self.column = condition.column + + +class BlockNode(ExpressionNode): + def __init__(self, expressions): + self.expressions = expressions + self.line = expressions[-1].line + self.column = expressions[-1].column + +class LetInNode(ExpressionNode): + def __init__(self, let_body, in_body=None): + self.let_body = let_body # [LetVariableDeclarations] + self.in_body = in_body + self.line = in_body.line + self.column = in_body.column + +class CaseOfNode(ExpressionNode): + def __init__(self, expression, branches): + self.expression = expression + self.branches = branches + self.line = expression.line + self.column = expression.column + +class AssignNode(ExpressionNode): + def __init__(self, idx, expression): + self.id = idx + self.expression = expression + self.line = idx.line + self.column = idx.column + +class UnaryNode(ExpressionNode): + def __init__(self, expression): + self.expression = expression + self.line = expression.line + self.column = expression.column + +class NotNode(UnaryNode): + pass + +class BinaryNode(ExpressionNode): + def __init__(self, left, right): + self.left = left + self.right = right + self.line = left.line + self.column = left.column + +class LessEqualNode(BinaryNode): + pass + +class LessNode(BinaryNode): + pass + +class EqualNode(BinaryNode): + pass + +class ArithmeticNode(BinaryNode): + pass + +class PlusNode(ArithmeticNode): + pass + +class MinusNode(ArithmeticNode): + pass + +class StarNode(ArithmeticNode): + pass + +class DivNode(ArithmeticNode): + pass + +class IsVoidNode(UnaryNode): + pass + +class ComplementNode(UnaryNode): + pass + +class FunctionCallNode(ExpressionNode): + def __init__(self, obj, idx, args, typex=None): + self.obj = obj + self.id = idx + self.args = args + self.type = typex + self.line = idx.line + self.column = idx.column + +class MemberCallNode(ExpressionNode): + def __init__(self, idx, args): + self.id = idx + self.args = args + self.line = idx.line + self.column = idx.column + +class NewNode(ExpressionNode): + def __init__(self, typex): + self.type = typex + self.line = typex.line + self.column = typex.column + +class AtomicNode(ExpressionNode): + def __init__(self, token): + self.token = token + self.line = token.line + self.column = token.column + +class IntegerNode(AtomicNode): + pass + +class IdNode(AtomicNode): + pass + +class StringNode(AtomicNode): + pass + +class BoolNode(AtomicNode): + pass + diff --git a/src/engine/parser.py b/src/engine/parser.py index 2f0716d0..2e6cd06c 100644 --- a/src/engine/parser.py +++ b/src/engine/parser.py @@ -1,328 +1,237 @@ from .cp import Grammar, LR1Parser - -# AST Classes -class Node: - pass - -class ProgramNode(Node): - def __init__(self, declarations): - self.declarations = declarations - self.line = declarations[0].line - self.column = declarations[0].column - -class DeclarationNode(Node): - pass - -class ClassDeclarationNode(DeclarationNode): - def __init__(self, idx, features, parent=None): - self.id = idx - self.parent = parent - self.features = features - self.line = idx.line - self.column = idx.column - -class AttrDeclarationNode(DeclarationNode): - def __init__(self, idx, typex, expression=None): - self.id = idx - self.type = typex - self.expression = expression - self.line = idx.line - self.column = idx.column - -class FuncDeclarationNode(DeclarationNode): - def __init__(self, idx, params, return_type, body): - self.id = idx - self.params = params - self.type = return_type - self.body = body - self.line = idx.line - self.column = idx.column - -class ExpressionNode(Node): - pass - -class IfThenElseNode(ExpressionNode): - def __init__(self, condition, if_body, else_body): - self.condition = condition - self.if_body = if_body - self.else_body = else_body - self.line = condition.line - self.column = condition.column - -class WhileLoopNode(ExpressionNode): - def __init__(self, condition, body): - self.condition = condition - self.body = body - self.line = condition.line - self.column = condition.column - - -class BlockNode(ExpressionNode): - def __init__(self, expressions): - self.expressions = expressions - self.line = expressions[-1].line - self.column = expressions[-1].column - -class LetInNode(ExpressionNode): - def __init__(self, let_body, in_body): - self.let_body = let_body - self.in_body = in_body - self.line = in_body.line - self.column = in_body.column - -class CaseOfNode(ExpressionNode): - def __init__(self, expression, branches): - self.expression = expression - self.branches = branches - self.line = expression.line - self.column = expression.column - -class AssignNode(ExpressionNode): - def __init__(self, idx, expression): - self.id = idx - self.expression = expression - self.line = idx.line - self.column = idx.column - -class UnaryNode(ExpressionNode): - def __init__(self, expression): - self.expression = expression - self.line = expression.line - self.column = expression.column - -class NotNode(UnaryNode): - pass - -class BinaryNode(ExpressionNode): - def __init__(self, left, right): - self.left = left - self.right = right - self.line = left.line - self.column = left.column - -class LessEqualNode(BinaryNode): - pass - -class LessNode(BinaryNode): - pass - -class EqualNode(BinaryNode): - pass - -class ArithmeticNode(BinaryNode): - pass - -class PlusNode(ArithmeticNode): - pass - -class MinusNode(ArithmeticNode): - pass - -class StarNode(ArithmeticNode): - pass - -class DivNode(ArithmeticNode): - pass - -class IsVoidNode(UnaryNode): - pass - -class ComplementNode(UnaryNode): - pass - -class FunctionCallNode(ExpressionNode): - def __init__(self, obj, idx, args, typex=None): - self.obj = obj - self.id = idx - self.args = args - self.type = typex - self.line = idx.line - self.column = idx.column - -class MemberCallNode(ExpressionNode): - def __init__(self, idx, args): - self.id = idx - self.args = args - self.line = idx.line - self.column = idx.column - -class NewNode(ExpressionNode): - def __init__(self, typex): - self.type = typex - self.line = typex.line - self.column = typex.column - -class AtomicNode(ExpressionNode): - def __init__(self, token): - self.token = token - self.line = token.line - self.column = token.column - -class IntegerNode(AtomicNode): - pass - -class IdNode(AtomicNode): - pass - -class StringNode(AtomicNode): - pass - -class BoolNode(AtomicNode): - pass - - - -# grammar -CoolGrammar = Grammar() - -# non-terminals -program = CoolGrammar.NonTerminal('', startSymbol=True) -class_list, def_class = CoolGrammar.NonTerminals(' ') -feature_list, feature = CoolGrammar.NonTerminals(' ') -param_list, param = CoolGrammar.NonTerminals(' ') -expr, member_call, expr_list, let_list, case_list = CoolGrammar.NonTerminals(' ') -sub_expr, arith, arith_2, term, factor, factor_2 = CoolGrammar.NonTerminals(' ') -atom, pre_atom, func_call, arg_list = CoolGrammar.NonTerminals(' ') - -# terminals -classx, inherits = CoolGrammar.Terminals('class inherits') -ifx, then, elsex, fi = CoolGrammar.Terminals('if then else fi') -whilex, loop, pool = CoolGrammar.Terminals('while loop pool') -let, inx = CoolGrammar.Terminals('let in') -case, of, esac = CoolGrammar.Terminals('case of esac') -semi, colon, comma, dot, at, opar, cpar, ocur, ccur, larrow, rarrow = CoolGrammar.Terminals('; : , . @ ( ) { } assign action') -plus, minus, star, div, isvoid, compl = CoolGrammar.Terminals('+ - * / isvoid int_complement') -notx, less, leq, equal = CoolGrammar.Terminals('not less lessequal equal') -new, idx, typex, integer, string, boolx = CoolGrammar.Terminals('new id type integer string bool') - -# productions -program %= class_list, lambda h, s: ProgramNode(s[1]) - -# ??? -class_list %= def_class + class_list, lambda h, s: [s[1]] + s[2] -class_list %= def_class, lambda h, s: [s[1]] - -# ??? -def_class %= classx + typex + ocur + feature_list + ccur + semi, lambda h, s: ClassDeclarationNode(s[2], s[4]) -def_class %= classx + typex + inherits + typex + ocur + feature_list + ccur + semi, lambda h, s: ClassDeclarationNode(s[2], s[6], s[4]) - -# ??? -feature_list %= feature + feature_list, lambda h, s: [s[1]] + s[2] -feature_list %= CoolGrammar.Epsilon, lambda h, s: [] - -# ??? -feature %= idx + colon + typex + semi, lambda h, s: AttrDeclarationNode(s[1], s[3]) -feature %= idx + colon + typex + larrow + expr + semi, lambda h, s: AttrDeclarationNode(s[1], s[3], s[5]) - -# ??? -feature %= idx + opar + param_list + cpar + colon + typex + ocur + expr + ccur + semi, lambda h, s: FuncDeclarationNode(s[1], s[3], s[6], s[8]) -feature %= idx + opar + cpar + colon + typex + ocur + expr + ccur + semi, lambda h, s: FuncDeclarationNode(s[1], [], s[5], s[7]) - -# ??? -param_list %= param, lambda h, s: [s[1]] -param_list %= param + comma + param_list, lambda h, s: [s[1]] + s[3] - -# ??? -param %= idx + colon + typex, lambda h, s: (s[1], s[3]) - -# ??? -expr_list %= expr + semi, lambda h, s: [s[1]] -expr_list %= expr + semi + expr_list, lambda h, s: [s[1]] + s[3] - -# ??? -let_list %= idx + colon + typex, lambda h, s: [(s[1], s[3], None)] -let_list %= idx + colon + typex + larrow + expr, lambda h, s: [(s[1], s[3], s[5])] -let_list %= idx + colon + typex + comma + let_list, lambda h, s: [(s[1], s[3], None)] + s[5] -let_list %= idx + colon + typex + larrow + expr + comma + let_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] - -# ??? -case_list %= idx + colon + typex + rarrow + expr + semi, lambda h, s: [(s[1], s[3], s[5])] -case_list %= idx + colon + typex + rarrow + expr + semi + case_list, lambda h, s: [(s[1], s[3], s[5])] + s[7] - -# == ??? -# expr %= notx + expr, lambda h, s: NotNode(s[2]) -# expr %= comp_expr, lambda h, s: s[1] - -# ??? -expr %= expr + leq + arith, lambda h, s: LessEqualNode(s[1], s[3]) -expr %= expr + less + arith, lambda h, s: LessNode(s[1], s[3]) -expr %= expr + equal + arith, lambda h, s: EqualNode(s[1], s[3]) -expr %= sub_expr, lambda h, s: s[1] - -sub_expr %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) -sub_expr %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) -sub_expr %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) -sub_expr %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) -sub_expr %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) -sub_expr %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) -sub_expr %= arith, lambda h, s: s[1] - -# ??? -arith %= notx + arith_2, lambda h, s: NotNode(s[2]) -arith %= arith_2, lambda h, s: s[1] - -# ??? -arith_2 %= arith_2 + plus + term, lambda h, s: PlusNode(s[1], s[3]) -arith_2 %= arith_2 + minus + term, lambda h, s: MinusNode(s[1], s[3]) -arith_2 %= term, lambda h, s: s[1] - -# ??? -term %= term + star + factor, lambda h, s: StarNode(s[1], s[3]) -term %= term + div + factor, lambda h, s: DivNode(s[1], s[3]) -term %= factor, lambda h, s: s[1] - -# ??? -factor %= isvoid + factor_2, lambda h, s: IsVoidNode(s[2]) -factor %= factor_2, lambda h, s: s[1] - -# ??? -factor_2 %= compl + atom, lambda h, s: ComplementNode(s[2]) -factor_2 %= atom, lambda h, s: s[1] - -# -# pre_atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) -# pre_atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) -# pre_atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) -# pre_atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) -# pre_atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) -# pre_atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) -# pre_atom %= atom, lambda h, s: s[1] - -# () ??? -# atom %= ifx + expr + then + expr + elsex + expr + fi, lambda h, s: IfThenElseNode(s[2], s[4], s[6]) -# atom %= whilex + expr + loop + expr + pool, lambda h, s: WhileLoopNode(s[2], s[4]) -# atom %= ocur + expr_list + ccur, lambda h, s: BlockNode(s[2]) -# atom %= let + let_list + inx + expr, lambda h, s: LetInNode(s[2], s[4]) -# atom %= case + expr + of + case_list + esac, lambda h, s: CaseOfNode(s[2], s[4]) -# atom %= idx + larrow + expr, lambda h, s: AssignNode(s[1], s[3]) -# ??? -atom %= atom + func_call, lambda h, s: FunctionCallNode(s[1], *s[2]) -atom %= member_call, lambda h, s: s[1] -atom %= new + typex, lambda h, s: NewNode(s[2]) -atom %= opar + expr + cpar, lambda h, s: s[2] -atom %= idx, lambda h, s: IdNode(s[1]) -atom %= integer, lambda h, s: IntegerNode(s[1]) -atom %= string, lambda h, s: StringNode(s[1]) -atom %= boolx, lambda h, s: BoolNode(s[1]) - -# ??? -func_call %= dot + idx + opar + arg_list + cpar, lambda h, s: (s[2], s[4]) -func_call %= dot + idx + opar + cpar, lambda h, s: (s[2], []) -func_call %= at + typex + dot + idx + opar + arg_list + cpar, lambda h, s: (s[4], s[6], s[2]) -func_call %= at + typex + dot + idx + opar + cpar, lambda h, s: (s[4], [], s[2]) - -# ??? -arg_list %= expr, lambda h, s: [s[1]] -arg_list %= expr + comma + arg_list, lambda h, s: [s[1]] + s[3] - -# ??? -member_call %= idx + opar + arg_list + cpar, lambda h, s: MemberCallNode(s[1], s[3]) -member_call %= idx + opar + cpar, lambda h, s: MemberCallNode(s[1], []) - -# parser -CoolParser = LR1Parser(CoolGrammar) +from ply import yacc +from ast_parser import * +from lexer import tokens,literals + +# Parser + +class CoolParser: + """ + CoolParser class. + """ + def __init__(self, tokens, literals): + self.tokens = None + self.literals = None + self.parser = yacc.yacc(module=self,start='program') + self.error_list = [] + + + precedence = ( + ('right', 'ASSIGN'), + ('right', 'NOT'), + ('nonassoc', 'LESS', 'LESSEQUAL', 'EQUAL'), + ('left', '+', '-'), + ('left', '*', '/'), + ('right', 'ISVOID') + ('right', 'INT_COMPLEMENT') + ('left', '@'), + ('left', '.'), + ) + + def p_epsilon(p): + 'epsilon :' + pass + + def p_program(p): + '''program : class_list''' + p[0] = ProgramNode(p[1]) + + def p_class_list(p): + '''class_list : def_class class_list + | def_class''' + if len(p) == 3: + p[0] = [s[1]] + s[2] + else: + p[0] = [p[1]] + + def p_def_class(p): + '''def_class : CLASS TYPE '(' feature_list ')' ';' + | CLASS TYPE INHERITS TYPE '(' feature_list ')' ';' ''' + if len(p) == 7: + p[0] = ClassDeclarationNode(p[2], p[4]) + else: + p[0] = ClassDeclarationNode(p[2], p[6], parent=p[4]) + + def p_feature_list(p): + '''feature_list : feature feature_list + | epsilon''' + if len(p) == 3: + p[0] = [p[1]] + p[2] + + def p_feature_attribute(p): + '''feature : ID ':' TYPE ';' + | ID ':' TYPE ASSIGN expr ';' ''' + if len(p) == 5: + p[0] = AttrDeclarationNode(p[1], p[3]) + else: + p[0] = AttrDeclarationNode(p[1], p[3], p[5]) + + def p_feature_function(p): + '''feature : ID '(' param_list ')' ':' TYPE '(' expr ')' ';' + | ID '(' ')' ':' TYPE '(' expr ')' ';'''' + if len(p) == 11: + p[0] = FuncDeclarationNode(p[1], p[3], p[6], p[8]) + else: + p[0] = FuncDeclarationNode(p[1], [], p[5], p[7]) + + def p_param_list(p): + '''param_list : param + | param comma param_list''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[3] + + def p_param(p): + '''param : ID ':' TYPE''' + p[0] = (p[1], p[3]) + + def p_expr_list(p): + '''expr_block : expr semi + | expr semi expr_block''' + if len(p) == 3: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[3] + + def p_let_list(p): + '''let_list : ID ':' TYPE + | ID ':' TYPE ACTION expr + | ID ':' TYPE comma let_list + | ID ':' TYPE ACTION expr comma let_list''' + if len(p) == 4: + p[0] = [LetVariableDeclaration(p[1], p[3], None)] + elif len(p) == 6 and p[4].lex == '=>': + p[0] = [LetVariableDeclaration(p[1], p[3], p[5])] + elif len(p) == 6: + p[0] = [LetVariableDeclaration(p[1], p[3], None)] + p[5] + else: + p[0] = [LetVariableDeclaration(p[1], p[3], p[5])] + p[7] + + def p_case_list(p): + '''case_list : ID ':' TYPE ACTION expr ';' + | ID ':' TYPE ACTION expr ';' case_list ''' + if len(p) == 7: + p[0] = [CaseVariableDeclaration(s[1], s[3], s[5])] + else: + p[0] = [CaseVariableDeclaration(s[1], s[3], s[5])] + p[7] + + def p_compar(p): + '''expr : expr LESSEQUAL expr + | expr LESS expr + | expr EQUAL expr''' + if p[2].lex == '<=': + p[0] = LessEqualNode(p[1], p[3]) + elif p[2] == '<': + p[0] = LessNode(p[1], p[3]) + else: + p[0] = EqualNode(p[1], p[3]) + + def p_unary(p): + ''' expr : '~' expr + | NOT expr + | ISVOID expr''' + if p[1].lex == '~': + p[0] = ComplementNode(p[2]) + elif p[1].lex == 'not': + p[0] = NotNode(p[2]) + else: + p[0] = IsVoidNode(p[2]) + + def p_arith(p): + '''expr : expr '+' expr + | expr '-' expr''' + if p[2].lex == '+': + p[0] = PlusNode(p[0], p[3]) + elif p[2].lex == '-': + p[0] = MinusNode(p[0], p[3]) + + def p_term(p): + '''expr : expr '*' expr + | expr '/' expr''' + elif p[2].lex == '*': + p[0] = StarNode(p[1], p[3]) + else: + p[0] = DivNode(p[1], p[3]) + + def p_sub_atomic(p): + '''expr : IF expr THEN expr ELSE expr FI + | WHILE expr LOOP expr POOL + | '(' expr_list ')' + | LET let_list IN expr + | LET let_list + | CASE expr of case_list ESAC + | ID ASSIGN expr''' + if p[1].lex == 'if': + p[0] = IfThenElseNode(p[2], p[4], p[6]) + elif p[1].lex == 'while': + p[0] = WhileLoopNode(p[2], p[4]) + elif p[1].lex == '(': + p[0] = BlockNode(p[2]) + elif len(p) == 5 and p[1].lex == 'let': + p[0] = LetInNode(p[2], p[4]) + elif p[1].lex == 'let': + p[0] = LetInNode(p[2], None) + elif p[1].lex == 'case': + p[0] = CaseOfNode(p[2], p[4]) + else: + p[0] = AssignNode(p[1], p[3]) + + def p_atomic(p): + '''expr : new0 TYPE + | '(' expr ')'''' + if p[0].lex == 'new': + p[0] = NewNode(p[2]) + elif p[0].lex == '(': + p[0] = p[2] + + def p_atomic_func_call(p): + '''expr : expr func_call''' + p[0] = FunctionCallNode(p[1], *p[2]) + + def p_static_call(p): + '''func_call : '.' ID '(' arg_list ')' + | '.' ID '(' ')'''' + if len(p) == 6: + p[0] = (p[2], p[4]) + else: + p[0] = (p[2], []) + + def p_dynamic_call(p): + '''func_call : '@' TYPE '.' ID '(' arg_list ')' + | '@' TYPE '.' ID '(' ')'''' + if len(p) == 6: + p[0] = (p[4], p[6], p[2]) + else: + p[0] = (p[4], [], p[2]) + def p_atomic_member_call(p): + '''expr : ID '(' arg_list ')' + | ID '(' ')'''' + + def p_arg_list(p): + ''' arg_list : expr + | expr ',' arg_list''' + if len(p) == 2: + p[0] = [p[1]] + else:`` + p[0] = [p[1]] + p[3] + + def p_atomic_id(p): + '''expr : ID''' + p[0] = IdNode(p[1]) + + def p_atomic_integer(p): + '''expr : INTEGER''' + p[0] = IntegerNode(p[1]) + + def p_atomic_string(p): + '''expr : STRING''' + p[0] = StringNode(p[1]) + + def p_atomic_bool(p): + '''expr : BOOL''' + p[0] = BoolNode(p[1]) + +parser = CoolParser(tokens, literals) if __name__ == '__main__': - if CoolParser.is_lr1: - print('The grammar is LR1') - print(CoolGrammar) From 16f3786e1462dac9ec1399abf0d8d776e85d50ae Mon Sep 17 00:00:00 2001 From: stdevlag Date: Wed, 2 Dec 2020 09:05:51 -0500 Subject: [PATCH 074/191] add token implementation to commons --- src/engine/__init__.py | 2 +- src/engine/ast_parser.py | 187 --------------------------------------- src/engine/cp/utils.py | 16 ++++ 3 files changed, 17 insertions(+), 188 deletions(-) delete mode 100644 src/engine/ast_parser.py diff --git a/src/engine/__init__.py b/src/engine/__init__.py index 3b4aa5c8..39c9033a 100644 --- a/src/engine/__init__.py +++ b/src/engine/__init__.py @@ -1,4 +1,4 @@ -from .lexer import tokenizer +from .lexer import CoolLexer from .parser import * from .cp import evaluate_reverse_parse from .cp.semantic import Scope diff --git a/src/engine/ast_parser.py b/src/engine/ast_parser.py deleted file mode 100644 index d2d47e26..00000000 --- a/src/engine/ast_parser.py +++ /dev/null @@ -1,187 +0,0 @@ - -# AST Classes -class Node: - pass - -class ProgramNode(Node): - def __init__(self, declarations): - self.declarations = declarations - self.line = declarations[0].line - self.column = declarations[0].column - -class DeclarationNode(Node): - pass - -class LetVariableDeclaration(DeclarationNode): - def __init__(self, idx, typex, expression=None): - self.id = idx - self.type = typex - self.expression = expression - self.line = self.idx.line - self.column = self.idx.column - -class CaseVariableDeclaration(DeclarationNode): - def __init__(self, idx, typex, expression=Node): - self.id = idx - self.type = typex - self.expression = expression - self.line = self.idx.line - self.column = self.idx.column - -class ClassDeclarationNode(DeclarationNode): - def __init__(self, idx, features, parent=None): - self.id = idx - self.parent = parent - self.features = features - self.line = idx.line - self.column = idx.column - -class AttrDeclarationNode(DeclarationNode): - def __init__(self, idx, typex, expression=None): - self.id = idx - self.type = typex - self.expression = expression - self.line = idx.line - self.column = idx.column - -class FuncDeclarationNode(DeclarationNode): - def __init__(self, idx, params, return_type, body): - self.id = idx - self.params = params - self.type = return_type - self.body = body - self.line = idx.line - self.column = idx.column - -class ExpressionNode(Node): - pass - -class IfThenElseNode(ExpressionNode): - def __init__(self, condition, if_body, else_body): - self.condition = condition - self.if_body = if_body - self.else_body = else_body - self.line = condition.line - self.column = condition.column - -class WhileLoopNode(ExpressionNode): - def __init__(self, condition, body): - self.condition = condition - self.body = body - self.line = condition.line - self.column = condition.column - - -class BlockNode(ExpressionNode): - def __init__(self, expressions): - self.expressions = expressions - self.line = expressions[-1].line - self.column = expressions[-1].column - -class LetInNode(ExpressionNode): - def __init__(self, let_body, in_body=None): - self.let_body = let_body # [LetVariableDeclarations] - self.in_body = in_body - self.line = in_body.line - self.column = in_body.column - -class CaseOfNode(ExpressionNode): - def __init__(self, expression, branches): - self.expression = expression - self.branches = branches - self.line = expression.line - self.column = expression.column - -class AssignNode(ExpressionNode): - def __init__(self, idx, expression): - self.id = idx - self.expression = expression - self.line = idx.line - self.column = idx.column - -class UnaryNode(ExpressionNode): - def __init__(self, expression): - self.expression = expression - self.line = expression.line - self.column = expression.column - -class NotNode(UnaryNode): - pass - -class BinaryNode(ExpressionNode): - def __init__(self, left, right): - self.left = left - self.right = right - self.line = left.line - self.column = left.column - -class LessEqualNode(BinaryNode): - pass - -class LessNode(BinaryNode): - pass - -class EqualNode(BinaryNode): - pass - -class ArithmeticNode(BinaryNode): - pass - -class PlusNode(ArithmeticNode): - pass - -class MinusNode(ArithmeticNode): - pass - -class StarNode(ArithmeticNode): - pass - -class DivNode(ArithmeticNode): - pass - -class IsVoidNode(UnaryNode): - pass - -class ComplementNode(UnaryNode): - pass - -class FunctionCallNode(ExpressionNode): - def __init__(self, obj, idx, args, typex=None): - self.obj = obj - self.id = idx - self.args = args - self.type = typex - self.line = idx.line - self.column = idx.column - -class MemberCallNode(ExpressionNode): - def __init__(self, idx, args): - self.id = idx - self.args = args - self.line = idx.line - self.column = idx.column - -class NewNode(ExpressionNode): - def __init__(self, typex): - self.type = typex - self.line = typex.line - self.column = typex.column - -class AtomicNode(ExpressionNode): - def __init__(self, token): - self.token = token - self.line = token.line - self.column = token.column - -class IntegerNode(AtomicNode): - pass - -class IdNode(AtomicNode): - pass - -class StringNode(AtomicNode): - pass - -class BoolNode(AtomicNode): - pass - diff --git a/src/engine/cp/utils.py b/src/engine/cp/utils.py index 80f649d8..35fd38de 100644 --- a/src/engine/cp/utils.py +++ b/src/engine/cp/utils.py @@ -77,6 +77,22 @@ def __init__(self, lex, token_type, line=0, column=0): self.line = line self.column = column + @property + def type(self): + return self.token_type + + @property + def value(self): + return self.lex + + @property + def lineno(self): + return self.line + + @property + def lexpos(self): + return self.column + def __str__(self): return f'{self.token_type}: {self.lex}' From 5c115a84a3ddaa1394a19927050def7f1df79d21 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Wed, 2 Dec 2020 09:08:14 -0500 Subject: [PATCH 075/191] modifies formatter visitor to accept let whit empty bodies --- src/engine/lexer.py | 486 +++++++++++++++++++--------------- src/engine/visitors/format.py | 13 +- 2 files changed, 284 insertions(+), 215 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 017fd318..7191db13 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -1,225 +1,289 @@ import ply.lex as lex from .errors import LexicographicError -from .parser import CoolGrammar -from .cp import Token - -####### Tokens ####### - -keywords = [ - 'CLASS', - 'ELSE', - ### false case is independently treated - 'FI', - 'IF', - 'IN', - 'INHERITS', - 'ISVOID', - 'LET', - 'LOOP', - 'POOL', - 'THEN', - 'WHILE', - 'CASE', - 'ESAC', - 'NEW', - 'OF', - 'NOT' - ### true case is independently treated -] - -literals = ['+', '-', '*', '/', ':', ';', '(', ')', '{', '}', '@', '.', ','] - -tokens = [ - # Identifiers - 'TYPE', 'ID', - # Primitive data types - 'INTEGER', 'STRING', 'BOOL', - # Special keywords - 'ACTION', - # Operators - 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', -] + list(keywords) - -####### Extra Methods ####### - -def iskeyword(t): - d = t.value.upper() - if d in keywords: - t.type = d - -def addline(t): - t.lexer.lineno += len(t.value) - -def find_position(input, token): - line_start = input.rfind('\n', 0, token.lexpos) + 1 - return (token.lineno, (token.lexpos - line_start) + 1) - -def lexer_error(t, message): - t.lexer.errors.append(LexicographicError(*find_position(t.lexer.lexdata, t), message)) +from .cp import Token, Grammar + +def find_column(lexer, token): + line_start = lexer.lexdata.rfind('\n', 0, token.lexpos) + return token.lexpos - line_start + + +class CoolLexer: + def __init__(self): + self.CoolGrammar = None + self.build() + self.last_token = None # dont touch + + ####### Tokens ####### + + keywords = [ + 'CLASS', + 'ELSE', + # false case is independently treated + 'FI', + 'IF', + 'IN', + 'INHERITS', + 'ISVOID', + 'LET', + 'LOOP', + 'POOL', + 'THEN', + 'WHILE', + 'CASE', + 'ESAC', + 'NEW', + 'OF', + 'NOT' + # true case is independently treated + ] + + literals = ['+', '-', '*', '/', ':', ';', + '(', ')', '{', '}', '@', '.', ','] + + tokens = [ + # Identifiers + 'TYPE', 'ID', + # Primitive data types + 'INTEGER', 'STRING', 'BOOL', + # Special keywords + 'ACTION', + # Operators + 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', + 'OPAR','CPAR','OCURL','CCURL','COLON','COMMA', + 'DOT', 'SEMI', 'AT','STAR','DIV','PLUS','MINUS' + ] + list(keywords) + t_ASSIGN = r'\<\-' # <- + t_LESS = r'\<' # < + t_LESSEQUAL = r'\<\=' # <= + t_EQUAL = r'\=' # = + t_INT_COMPLEMENT = r'\~' # ~ + t_ACTION = r'\=\>' # => + + t_OPAR = r'\(' # ( + t_CPAR = r'\)' # ) + t_OCURL = r'\{' # { + t_CCURL = r'\}' # } + t_COLON = r'\:' # : + t_COMMA = r'\,' # , + t_DOT = r'\.' # . + t_SEMI = r'\;' # ; + t_AT = r'\@' # @ + t_STAR = r'\*' # * + t_DIV = r'\/' # / + t_PLUS = r'\+' # + + t_MINUS = r'\-' # - + + ####### Extra Methods ####### + + def iskeyword(self, t): + d = t.value.upper() + if d in self.keywords: + t.type = d + + def addline(self, t): + t.lexer.lineno += len(t.value) + + def find_position(self, input, token): + line_start = input.rfind('\n', 0, token.lexpos) + 1 + return (token.lineno, (token.lexpos - line_start) + 1) + + def lexer_error(self, t, message): + self.lexer.errors.append(LexicographicError( + *self.find_position(t.lexer.lexdata, t), message)) + + ##### TOKEN RULES ##### + + t_ignore = ' \t\f\r\v' + t_ignore_single_comment = r'\-\-[^\n]*' + + # count line number + def t_INITIAL_comment_newline(self, t): + r'\n+' + self.addline(t) + + def t_BOOL(self, t): + r't[rR][uU][eE]|f[aA][lL][sS][eE]' + d = t.value.lower() + t.value = True if d == 'true' else False + return t -##### TOKEN RULES ##### - -t_ignore = ' \t\f\r\v' -t_ignore_single_comment = r'\-\-[^\n]*' - -# count line number -def t_INITIAL_comment_newline(t): - r'\n+' - addline(t) - -def t_BOOL(t): - r't[rR][uU][eE]|f[aA][lL][sS][eE]' - d = t.value.lower() - t.value = True if d == 'true' else False - return t - -def t_INTEGER(t): - r'[0-9]+' - t.value = int(t.value) - return t - -def t_TYPE(t): - r'[A-Z][A-Za-z0-9_]*' - iskeyword(t) - return t - -def t_ID(t): - r'[a-z][A-Za-z0-9_]*' - iskeyword(t) - return t - -def t_error(t): - lexer_error(t,f'ERROR "{t.value}"') - t.lexer.skip(1) - -t_ASSIGN = r'\<\-' -t_LESS = r'\<' -t_LESSEQUAL = r'\<\=' -t_EQUAL = r'\=' -t_INT_COMPLEMENT = r'\~' - -t_ACTION = r'\=\>' - -states = ( - ('string','exclusive'), - ('comment','exclusive') - ) - -def t_comment(t): - r'\(\*' - t.lexer.comments = 1 - #t.lexer.unterminated_slash = False - t.lexer.begin('comment') - -t_comment_ignore = '' - -def t_comment_opar(t): - r'\(\*' - t.lexer.comments += 1 - -def t_comment_cpar(t): - r'\*\)' - t.lexer.comments -=1 - if not t.lexer.comments: - t.lexer.begin('INITIAL') - -def t_comment_eof(t): - lexer_error(t,'EOF in comment') - -def t_comment_error(t): - #print(t.value, 'error en comment') - t.lexer.skip(1) - -def t_comment_literals(t): - r'\+|\-|\*|\:|\;|\(|\)|\{|\}|\@|\.|\,|\/|\<|\<\-|\<\=|\=|\~|\=|>' - -# string state -def t_string(t): - r'\"' - t.lexer.begin('string') - t.lexer.string = '' - -t_string_ignore = '' - -def t_string_error(t): - #print(t.value, 'error en string ') - t.lexer.skip(1) - -def t_string_end(t): - r'\"' - if not t.lexer.unterminated_slash: - t.value = t.lexer.string - t.type = 'STRING' - t.lexer.begin('INITIAL') - t.lexer.string = '' + def t_INTEGER(self, t): + r'[0-9]+' + t.value = int(t.value) return t - else: - t.lexer.string += '"' - t.lexer.unterminated_slash = False - -def t_string_newline(t): - r'\n' - t.lexer.lineno += 1 - if not t.lexer.unterminated_slash: - lexer_error(t,'Unterminated string constant') - else: - t.lexer.unterminated_slash = False - t.lexer.string += '\n' - -def t_string_null(t): - r'\0' - lexer_error(t,'String contains null character') - -def t_string_slash(t): - r'\\' - if t.lexer.unterminated_slash: - t.lexer.string += '\\' - t.lexer.unterminated_slash = False - else: - t.lexer.unterminated_slash = True - -def t_string_eof(t): - lexer_error(t,'EOF in string constant') - -def t_string_all(t): - r'[^\n]' - if t.lexer.unterminated_slash: - spec = {'b':'\b','t':'\t','f':'\f'} - if t.value in ['b','t','f']: - t.lexer.string += spec[t.value] - else: - t.lexer.string += t.value - t.lexer.unterminated_slash = False - else: - t.lexer.string += t.value - -lexer = lex.lex(debug=0) -lexer.errors = [] -lexer.unterminated_slash = False -lexer.string = '' -###### CoolGrammar ###### + def t_TYPE(self, t): + r'[A-Z][A-Za-z0-9_]*' + self.iskeyword(t) + return t + + def t_ID(self, t): + r'[a-z][A-Za-z0-9_]*' + self.iskeyword(t) + return t -tokens_dict = dict() + def t_error(self, t): + self.lexer_error(t, f'ERROR "{t.value}"') + t.lexer.skip(1) + + + states = ( + ('string', 'exclusive'), + ('comment', 'exclusive') + ) + + def t_comment(self, t): + r'\(\*' + t.lexer.comments = 1 + #t.lexer.unterminated_slash = False + t.lexer.begin('comment') + + t_comment_ignore = '' + + def t_comment_opar(self, t): + r'\(\*' + t.lexer.comments += 1 + + def t_comment_cpar(self, t): + r'\*\)' + t.lexer.comments -= 1 + if not t.lexer.comments: + t.lexer.begin('INITIAL') + + def t_comment_eof(self, t): + self.lexer_error(t, 'EOF in comment') + + def t_comment_error(self, t): + #print(t.value, 'error en comment') + t.lexer.skip(1) + + def t_comment_literals(self, t): + r'\+|\-|\*|\:|\;|\(|\)|\{|\}|\@|\.|\,|\/|\<|\<\-|\<\=|\=|\~|\=|>' + + # string state + def t_string(self, t): + r'\"' + t.lexer.begin('string') + t.lexer.string = '' -for tok in tokens + literals: - if tok not in tokens_dict: - tokens_dict[tok] = CoolGrammar[tok.lower()] + t_string_ignore = '' + def t_string_error(self, t): + #print(t.value, 'error en string ') + t.lexer.skip(1) -###### TOKENIZER ###### + def t_string_end(self, t): + r'\"' + if not t.lexer.unterminated_slash: + t.value = t.lexer.string + t.type = 'STRING' + t.lexer.begin('INITIAL') + t.lexer.string = '' + return t + else: + t.lexer.string += '"' + t.lexer.unterminated_slash = False + + def t_string_newline(self, t): + r'\n' + t.lexer.lineno += 1 + if not t.lexer.unterminated_slash: + self.lexer_error(t, 'Unterminated string constant') + else: + t.lexer.unterminated_slash = False + t.lexer.string += '\n' + + def t_string_null(self, t): + r'\0' + self.lexer_error(t, 'String contains null character') + + def t_string_slash(self, t): + r'\\' + if t.lexer.unterminated_slash: + t.lexer.string += '\\' + t.lexer.unterminated_slash = False + else: + t.lexer.unterminated_slash = True + + def t_string_eof(self, t): + self.lexer_error(t, 'EOF in string constant') + + def t_string_all(self, t): + r'[^\n]' + if t.lexer.unterminated_slash: + spec = {'b': '\b', 't': '\t', 'f': '\f'} + if t.value in ['b', 't', 'f']: + t.lexer.string += spec[t.value] + else: + t.lexer.string += t.value + t.lexer.unterminated_slash = False + else: + t.lexer.string += t.value -def tokenizer(code): + def build(self): + self.lexer = lex.lex(debug=0, module=self) + self.lexer.errors = [] + self.lexer.unterminated_slash = False + self.lexer.string = '' + + ###### CoolGrammar ###### + CoolGrammar = Grammar() + # terminals + CoolGrammar.Terminals('class inherits') + CoolGrammar.Terminals('if then else fi') + CoolGrammar.Terminals('while loop pool') + CoolGrammar.Terminals('let in') + CoolGrammar.Terminals('case of esac') + CoolGrammar.Terminals('; : , . @ ( ) { } assign action') + CoolGrammar.Terminals('+ - * / isvoid int_complement') + CoolGrammar.Terminals('not less lessequal equal') + CoolGrammar.Terminals('new id type integer string bool') + + self.CoolGrammar = CoolGrammar + tokens_dict = dict() + + for tok in self.tokens + self.literals: + if tok not in tokens_dict: + tokens_dict[tok] = CoolGrammar[tok.lower()] + + ###### TOKENIZER ###### + + def token(self): + if not (self.last_token is None) and self.last_token.token_type==self.CoolGrammar.EOF: + return None + token = self.lexer.token() + if token is None: + self.last_token = Token('$', self.CoolGrammar.EOF) + return None + else: + self.last_token = Token(token.value, token.type, *self.find_position(self.lexer.lexdata, token)) + return self.last_token - tokens = [] - lexer.input(code) - while True: - token = lexer.token() - if token is None: - break - tokens.append(Token(token.value, tokens_dict[token.type], *find_position(lexer.lexdata, token))) + def reset(self): + self.last_token = None + + def tokenize(self, code): + tokens = [] + self.lexer.input(code) + while True: + token = self.token() + if token is None: + break + tokens.append(token) + + # tokens.append(Token('$', self.CoolGrammar.EOF)) + + return tokens, self.lexer.errors + + def __iter__(self): + return self - tokens.append(Token('$', CoolGrammar.EOF)) + def __next__(self): + t = self.token() + if t is None: + raise StopIteration + return t - return tokens, lexer.errors + def next(self): + return self.__next__() diff --git a/src/engine/visitors/format.py b/src/engine/visitors/format.py index 72329938..d96ff723 100644 --- a/src/engine/visitors/format.py +++ b/src/engine/visitors/format.py @@ -61,9 +61,14 @@ def visit(self, node, tabs=0): let_body = ', '.join(f'{idx.lex}: {typex.lex}' + (' <- ' if expr else '') for idx, typex, expr in node.let_body) ans = '\t' * tabs + f'\\_LetInNode: let {let_body} in ' lets = '\n'.join(self.visit(expr, tabs + 1) for _, _, expr in node.let_body if expr) - body = self.visit(node.in_body, tabs + 1) - return f'{ans}\n{lets}\n{body}' - + if node.in_body is None: + return f'{ans}\n{lets}' + else: + body = self.visit(node.in_body, tabs + 1) + return f'{ans}\n{lets}\n{body}' + # @visitor.when(Let) + # def visit(self, node, tabs=0): + @visitor.when(CaseOfNode) def visit(self, node, tabs=0): case_body = ' '.join(f'{idx.lex}: {typex.lex} => ;' for idx, typex, expr in node.branches) @@ -111,4 +116,4 @@ def visit(self, node, tabs=0): @visitor.when(AtomicNode) def visit(self, node, tabs=0): - return '\t' * tabs + f'\\__ {node.__class__.__name__}: {node.token.lex}' \ No newline at end of file + return '\t' * tabs + f'\\__ {node.__class__.__name__}: {node.token.lex}' From 5972af9697c2dbe42aadd821855e268300b79e92 Mon Sep 17 00:00:00 2001 From: stdevlag Date: Wed, 2 Dec 2020 09:09:13 -0500 Subject: [PATCH 076/191] error handling in progress --- src/assignment1_error.txt | 1 + src/engine/commons/__init__.py | 1 + src/engine/commons/tokens.py | 98 ++++++++ src/engine/parser.py | 237 ------------------ src/engine/parser/__init__.py | 2 + src/engine/parser/ast_parser.py | 235 ++++++++++++++++++ src/engine/parser/cool_parser.py | 410 +++++++++++++++++++++++++++++++ src/engine/parser/parsetab.py | 167 +++++++++++++ src/main.py | 132 +++++----- src/test.cl | 42 ++-- 10 files changed, 1010 insertions(+), 315 deletions(-) create mode 100644 src/assignment1_error.txt create mode 100644 src/engine/commons/__init__.py create mode 100644 src/engine/commons/tokens.py delete mode 100644 src/engine/parser.py create mode 100644 src/engine/parser/__init__.py create mode 100644 src/engine/parser/ast_parser.py create mode 100644 src/engine/parser/cool_parser.py create mode 100644 src/engine/parser/parsetab.py diff --git a/src/assignment1_error.txt b/src/assignment1_error.txt new file mode 100644 index 00000000..cef0d394 --- /dev/null +++ b/src/assignment1_error.txt @@ -0,0 +1 @@ +(29, 9) - SyntacticError: ERROR at or near "Test1" \ No newline at end of file diff --git a/src/engine/commons/__init__.py b/src/engine/commons/__init__.py new file mode 100644 index 00000000..bec48162 --- /dev/null +++ b/src/engine/commons/__init__.py @@ -0,0 +1 @@ +from .tokens import * diff --git a/src/engine/commons/tokens.py b/src/engine/commons/tokens.py new file mode 100644 index 00000000..cbafc3c3 --- /dev/null +++ b/src/engine/commons/tokens.py @@ -0,0 +1,98 @@ +####### Tokens ####### + +keywords = ( + 'CLASS', + 'ELSE', + ### false case is independently treated + 'FI', + 'IF', + 'IN', + 'INHERITS', + 'ISVOID', + 'LET', + 'LOOP', + 'POOL', + 'THEN', + 'WHILE', + 'CASE', + 'ESAC', + 'NEW', + 'OF', + 'NOT' + ### true case is independently treated +) + +literals = ['+', '-', '*', '/', ':', ';', '(', ')', '{', '}', '@', '.', ','] +# ['+', '-', '*', '/', ':', ';', '(', ')', '{', '}', '@', '.', ','] +terminals = { + r'\(': 'OPAR', + r'\)': 'CPAR', + r'\{': 'OCURL', + r'\}': 'CCURL', + r'\:': 'COLON', + r'\,': 'COMMA', + r'\.': 'DOT', + r'\;': 'SEMI', + r'\@': 'AT', + r'\*': 'STAR', + r'\/': 'DIV', + r'\+': 'PLUS', + r'\-': 'MINUS', + 'class': 'CLASS', + 'else': 'ELSE', + 'fi': 'FI', + 'if': 'IF', + 'in': 'IN', + 'inherits': 'INHERITS', + 'isvoid': 'ISVOID', + 'let': 'LET', + 'loop': 'LOOP', + 'pool': 'POOL', + 'then': 'THEN', + 'while': 'WHILE', + 'case': 'CASE', + 'esac': 'ESAC', + 'new': 'NEW', + 'of': 'OF', + 'not': 'NOT', +} + +tokens = ( + # Identifiers + 'TYPE', 'ID', + # Primitive data types + 'INTEGER', 'STRING', 'BOOL', + # Special keywords + 'ACTION', + # Operators + 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', +) + + +class Token: + """ + Basic token class. + + Parameters + ---------- + lex : str + Token's lexeme. + token_type : Enum + Token's type. + """ + + def __init__(self, lex, token_type, line=0, column=0): + self.lex = lex + self.token_type = token_type + self.line = line + self.column = column + + @property + def type(self): + return self.type + + def __str__(self): + return f'{self.token_type}: {self.lex}' + + def __repr__(self): + return str(self) diff --git a/src/engine/parser.py b/src/engine/parser.py deleted file mode 100644 index 2e6cd06c..00000000 --- a/src/engine/parser.py +++ /dev/null @@ -1,237 +0,0 @@ -from .cp import Grammar, LR1Parser -from ply import yacc -from ast_parser import * -from lexer import tokens,literals - -# Parser - -class CoolParser: - """ - CoolParser class. - """ - def __init__(self, tokens, literals): - self.tokens = None - self.literals = None - self.parser = yacc.yacc(module=self,start='program') - self.error_list = [] - - - precedence = ( - ('right', 'ASSIGN'), - ('right', 'NOT'), - ('nonassoc', 'LESS', 'LESSEQUAL', 'EQUAL'), - ('left', '+', '-'), - ('left', '*', '/'), - ('right', 'ISVOID') - ('right', 'INT_COMPLEMENT') - ('left', '@'), - ('left', '.'), - ) - - def p_epsilon(p): - 'epsilon :' - pass - - def p_program(p): - '''program : class_list''' - p[0] = ProgramNode(p[1]) - - def p_class_list(p): - '''class_list : def_class class_list - | def_class''' - if len(p) == 3: - p[0] = [s[1]] + s[2] - else: - p[0] = [p[1]] - - def p_def_class(p): - '''def_class : CLASS TYPE '(' feature_list ')' ';' - | CLASS TYPE INHERITS TYPE '(' feature_list ')' ';' ''' - if len(p) == 7: - p[0] = ClassDeclarationNode(p[2], p[4]) - else: - p[0] = ClassDeclarationNode(p[2], p[6], parent=p[4]) - - def p_feature_list(p): - '''feature_list : feature feature_list - | epsilon''' - if len(p) == 3: - p[0] = [p[1]] + p[2] - - def p_feature_attribute(p): - '''feature : ID ':' TYPE ';' - | ID ':' TYPE ASSIGN expr ';' ''' - if len(p) == 5: - p[0] = AttrDeclarationNode(p[1], p[3]) - else: - p[0] = AttrDeclarationNode(p[1], p[3], p[5]) - - def p_feature_function(p): - '''feature : ID '(' param_list ')' ':' TYPE '(' expr ')' ';' - | ID '(' ')' ':' TYPE '(' expr ')' ';'''' - if len(p) == 11: - p[0] = FuncDeclarationNode(p[1], p[3], p[6], p[8]) - else: - p[0] = FuncDeclarationNode(p[1], [], p[5], p[7]) - - def p_param_list(p): - '''param_list : param - | param comma param_list''' - if len(p) == 2: - p[0] = [p[1]] - else: - p[0] = [p[1]] + p[3] - - def p_param(p): - '''param : ID ':' TYPE''' - p[0] = (p[1], p[3]) - - def p_expr_list(p): - '''expr_block : expr semi - | expr semi expr_block''' - if len(p) == 3: - p[0] = [p[1]] - else: - p[0] = [p[1]] + p[3] - - def p_let_list(p): - '''let_list : ID ':' TYPE - | ID ':' TYPE ACTION expr - | ID ':' TYPE comma let_list - | ID ':' TYPE ACTION expr comma let_list''' - if len(p) == 4: - p[0] = [LetVariableDeclaration(p[1], p[3], None)] - elif len(p) == 6 and p[4].lex == '=>': - p[0] = [LetVariableDeclaration(p[1], p[3], p[5])] - elif len(p) == 6: - p[0] = [LetVariableDeclaration(p[1], p[3], None)] + p[5] - else: - p[0] = [LetVariableDeclaration(p[1], p[3], p[5])] + p[7] - - def p_case_list(p): - '''case_list : ID ':' TYPE ACTION expr ';' - | ID ':' TYPE ACTION expr ';' case_list ''' - if len(p) == 7: - p[0] = [CaseVariableDeclaration(s[1], s[3], s[5])] - else: - p[0] = [CaseVariableDeclaration(s[1], s[3], s[5])] + p[7] - - def p_compar(p): - '''expr : expr LESSEQUAL expr - | expr LESS expr - | expr EQUAL expr''' - if p[2].lex == '<=': - p[0] = LessEqualNode(p[1], p[3]) - elif p[2] == '<': - p[0] = LessNode(p[1], p[3]) - else: - p[0] = EqualNode(p[1], p[3]) - - def p_unary(p): - ''' expr : '~' expr - | NOT expr - | ISVOID expr''' - if p[1].lex == '~': - p[0] = ComplementNode(p[2]) - elif p[1].lex == 'not': - p[0] = NotNode(p[2]) - else: - p[0] = IsVoidNode(p[2]) - - def p_arith(p): - '''expr : expr '+' expr - | expr '-' expr''' - if p[2].lex == '+': - p[0] = PlusNode(p[0], p[3]) - elif p[2].lex == '-': - p[0] = MinusNode(p[0], p[3]) - - def p_term(p): - '''expr : expr '*' expr - | expr '/' expr''' - elif p[2].lex == '*': - p[0] = StarNode(p[1], p[3]) - else: - p[0] = DivNode(p[1], p[3]) - - def p_sub_atomic(p): - '''expr : IF expr THEN expr ELSE expr FI - | WHILE expr LOOP expr POOL - | '(' expr_list ')' - | LET let_list IN expr - | LET let_list - | CASE expr of case_list ESAC - | ID ASSIGN expr''' - if p[1].lex == 'if': - p[0] = IfThenElseNode(p[2], p[4], p[6]) - elif p[1].lex == 'while': - p[0] = WhileLoopNode(p[2], p[4]) - elif p[1].lex == '(': - p[0] = BlockNode(p[2]) - elif len(p) == 5 and p[1].lex == 'let': - p[0] = LetInNode(p[2], p[4]) - elif p[1].lex == 'let': - p[0] = LetInNode(p[2], None) - elif p[1].lex == 'case': - p[0] = CaseOfNode(p[2], p[4]) - else: - p[0] = AssignNode(p[1], p[3]) - - def p_atomic(p): - '''expr : new0 TYPE - | '(' expr ')'''' - if p[0].lex == 'new': - p[0] = NewNode(p[2]) - elif p[0].lex == '(': - p[0] = p[2] - - def p_atomic_func_call(p): - '''expr : expr func_call''' - p[0] = FunctionCallNode(p[1], *p[2]) - - def p_static_call(p): - '''func_call : '.' ID '(' arg_list ')' - | '.' ID '(' ')'''' - if len(p) == 6: - p[0] = (p[2], p[4]) - else: - p[0] = (p[2], []) - - def p_dynamic_call(p): - '''func_call : '@' TYPE '.' ID '(' arg_list ')' - | '@' TYPE '.' ID '(' ')'''' - if len(p) == 6: - p[0] = (p[4], p[6], p[2]) - else: - p[0] = (p[4], [], p[2]) - def p_atomic_member_call(p): - '''expr : ID '(' arg_list ')' - | ID '(' ')'''' - - def p_arg_list(p): - ''' arg_list : expr - | expr ',' arg_list''' - if len(p) == 2: - p[0] = [p[1]] - else:`` - p[0] = [p[1]] + p[3] - - def p_atomic_id(p): - '''expr : ID''' - p[0] = IdNode(p[1]) - - def p_atomic_integer(p): - '''expr : INTEGER''' - p[0] = IntegerNode(p[1]) - - def p_atomic_string(p): - '''expr : STRING''' - p[0] = StringNode(p[1]) - - def p_atomic_bool(p): - '''expr : BOOL''' - p[0] = BoolNode(p[1]) - -parser = CoolParser(tokens, literals) - -if __name__ == '__main__': diff --git a/src/engine/parser/__init__.py b/src/engine/parser/__init__.py new file mode 100644 index 00000000..b4de894d --- /dev/null +++ b/src/engine/parser/__init__.py @@ -0,0 +1,2 @@ +from .cool_parser import CoolParser +from .ast_parser import * diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py new file mode 100644 index 00000000..5e202dfd --- /dev/null +++ b/src/engine/parser/ast_parser.py @@ -0,0 +1,235 @@ + +# AST Classes +class Node: + pass + + +class ErrorNode(Node): + pass + + +class ProgramNode(Node): + def __init__(self, declarations): + self.declarations = declarations + self.line = declarations[0].line + self.column = declarations[0].column + + +class DeclarationNode(Node): + pass + + +class LetVariableDeclaration(DeclarationNode): + def __init__(self, idx, typex, expression=None): + self.id = idx + self.type = typex + self.expression = expression + self.line = self.id.line + self.column = self.id.column + + def __iter__(self): + yield from (self.id, self.type, self.expression) + + +class CaseVariableDeclaration(DeclarationNode): + def __init__(self, idx, typex, expression=Node): + self.id = idx + self.type = typex + self.expression = expression + self.line = self.id.line + self.column = self.id.column + + def __iter__(self): + yield from (self.id, self.type, self.expression) + + +class ClassDeclarationNode(DeclarationNode): + def __init__(self, idx, features, parent=None): + self.id = idx + self.parent = parent + self.features = features + self.line = idx.line + self.column = idx.column + + +class AttrDeclarationNode(DeclarationNode): + def __init__(self, idx, typex, expression=None): + self.id = idx + self.type = typex + self.expression = expression + self.line = idx.line + self.column = idx.column + + +class FuncDeclarationNode(DeclarationNode): + def __init__(self, idx, params, return_type, body): + self.id = idx + self.params = params + self.type = return_type + self.body = body + self.line = idx.line + self.column = idx.column + + +class ExpressionNode(Node): + pass + + +class IfThenElseNode(ExpressionNode): + def __init__(self, condition, if_body, else_body): + self.condition = condition + self.if_body = if_body + self.else_body = else_body + self.line = condition.line + self.column = condition.column + + +class WhileLoopNode(ExpressionNode): + def __init__(self, condition, body): + self.condition = condition + self.body = body + self.line = condition.line + self.column = condition.column + + +class BlockNode(ExpressionNode): + def __init__(self, expressions): + self.expressions = expressions + self.line = expressions[-1].line + self.column = expressions[-1].column + + +class LetInNode(ExpressionNode): + def __init__(self, let_body, in_body=None): + self.let_body = let_body # [LetVariableDeclarations] + self.in_body = in_body + if in_body is None: + last = self.let_body[-1] + self.line = last.line + self.column = last.column + else: + self.line = in_body.line + self.column = in_body.column + + +class CaseOfNode(ExpressionNode): + def __init__(self, expression, branches): + self.expression = expression + self.branches = branches + self.line = expression.line + self.column = expression.column + + +class AssignNode(ExpressionNode): + def __init__(self, idx, expression): + self.id = idx + self.expression = expression + self.line = idx.line + self.column = idx.column + + +class UnaryNode(ExpressionNode): + def __init__(self, expression): + self.expression = expression + self.line = expression.line + self.column = expression.column + + +class NotNode(UnaryNode): + pass + + +class BinaryNode(ExpressionNode): + def __init__(self, left, right): + self.left = left + self.right = right + self.line = left.line + self.column = left.column + + +class LessEqualNode(BinaryNode): + pass + + +class LessNode(BinaryNode): + pass + + +class EqualNode(BinaryNode): + pass + + +class ArithmeticNode(BinaryNode): + pass + + +class PlusNode(ArithmeticNode): + pass + + +class MinusNode(ArithmeticNode): + pass + + +class StarNode(ArithmeticNode): + pass + + +class DivNode(ArithmeticNode): + pass + + +class IsVoidNode(UnaryNode): + pass + + +class ComplementNode(UnaryNode): + pass + + +class FunctionCallNode(ExpressionNode): + def __init__(self, obj, idx, args, typex=None): + self.obj = obj + self.id = idx + self.args = args + self.type = typex + self.line = idx.line + self.column = idx.column + + +class MemberCallNode(ExpressionNode): + def __init__(self, idx, args): + self.id = idx + self.args = args + self.line = idx.line + self.column = idx.column + + +class NewNode(ExpressionNode): + def __init__(self, typex): + self.type = typex + self.line = typex.line + self.column = typex.column + + +class AtomicNode(ExpressionNode): + def __init__(self, token): + self.token = token + self.line = token.line + self.column = token.column + + +class IntegerNode(AtomicNode): + pass + + +class IdNode(AtomicNode): + pass + + +class StringNode(AtomicNode): + pass + + +class BoolNode(AtomicNode): + pass diff --git a/src/engine/parser/cool_parser.py b/src/engine/parser/cool_parser.py new file mode 100644 index 00000000..ff6d66d5 --- /dev/null +++ b/src/engine/parser/cool_parser.py @@ -0,0 +1,410 @@ +from ply import yacc +from ..lexer import CoolLexer, find_column +from .ast_parser import * +from ..commons import terminals, keywords, tokens +from ..errors import SyntacticError +# Parser + + +class CoolParser: + """ + CoolParser class. + """ + + def __init__(self, lexer): + self.tokens = tokens + tuple(terminals.values()) + self.parser = yacc.yacc(module=self, start='program') + self.error_list = [] + self.lexer = lexer + + def parse(self, code): + result = self.parser.parse( + code, self.lexer.lexer, tokenfunc=self.lexer.token) + return result, self.error_list + + precedence = ( + ('right', 'ASSIGN'), + ('right', 'NOT'), + ('nonassoc', 'LESS', 'LESSEQUAL', 'EQUAL'), + ('left', 'PLUS', 'MINUS'), + ('left', 'STAR', 'DIV'), + ('right', 'ISVOID'), + ('right', 'INT_COMPLEMENT'), + ('left', 'AT'), + ('left', 'DOT'), + ) + + def p_epsilon(self, p): + 'epsilon :' + pass + + def p_program(self, p): + '''program : class_list''' + p[0] = ProgramNode(p[1]) + + def p_class_list(self, p): + '''class_list : def_class class_list + | def_class''' + if len(p) == 3: + p[0] = [p[1]] + p[2] + else: + p[0] = [p[1]] + + def p_class_list_error(self, p): + '''class_list : error class_list ''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[2] + + def p_def_class(self, p): + '''def_class : CLASS TYPE OCURL feature_list CCURL SEMI + | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI ''' + if len(p) == 7: + p[0] = ClassDeclarationNode(p.slice[2], p[4]) + else: + p[0] = ClassDeclarationNode( + p.slice[2], p[6], parent=p.slice[4]) + + def p_def_class_error(self, p): + '''def_class : CLASS error OCURL feature_list CCURL SEMI + | CLASS TYPE OCURL error CCURL SEMI + | CLASS error OCURL error CCURL SEMI + | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI + | CLASS TYPE INHERITS error OCURL error CCURL SEMI + | CLASS error INHERITS TYPE OCURL error CCURL SEMI + | CLASS error INHERITS error OCURL feature_list CCURL SEMI + | CLASS error INHERITS error OCURL error CCURL SEMI ''' + p[0] = ErrorNode() + + def p_feature_list(self, p): + '''feature_list : feature feature_list + | epsilon''' + if len(p) == 3: + p[0] = [p[1]] + p[2] + else: + p[0] = [] + + def p_feature_list_error(self, p): + 'feature_list : error feature_list' + p[0] = [p[1]] + p[2] + + def p_feature_attribute(self, p): + '''feature : ID COLON TYPE SEMI + | ID COLON TYPE ASSIGN expr SEMI ''' + if len(p) == 5: + p[0] = AttrDeclarationNode(p.slice[1], p.slice[3]) + else: + p[0] = AttrDeclarationNode( + p.slice[1], p.slice[3], p[5]) + + def p_def_attribute_error(self, p): + '''feature : error COLON TYPE + | ID COLON error + | error COLON error + | error COLON TYPE ASSIGN expr + | ID COLON error ASSIGN expr + | ID COLON TYPE ASSIGN error + | ID COLON error ASSIGN error + | error COLON TYPE ASSIGN error + | error COLON error ASSIGN expr + | error COLON error ASSIGN error''' + p[0] = ErrorNode() + + def p_feature_function(self, p): + '''feature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI + | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI ''' + if len(p) == 11: + p[0] = FuncDeclarationNode( + p.slice[1], p[3], p.slice[6], p[8]) + else: + p[0] = FuncDeclarationNode( + p.slice[1], [], p.slice[5], p[7]) + + def p_feature_function_error(self, p): + '''feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI + | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI + | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI + | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI + | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI + | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI + | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI + | ID OPAR error CPAR COLON error OCURL error CCURL SEMI + | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI + | error OPAR error CPAR COLON error OCURL error CCURL SEMI + | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI + | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI + | ID OPAR CPAR COLON error OCURL expr CCURL SEMI + | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI + | ID OPAR CPAR COLON error OCURL error CCURL SEMI + | ID error CPAR COLON TYPE OCURL error CCURL SEMI + | ID error CPAR COLON TYPE OCURL expr CCURL SEMI + | ID error CPAR COLON error OCURL error CCURL SEMI ''' + p[0] = ErrorNode() + + def p_param_list(self, p): + '''param_list : param + | param COMMA param_list''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[3] + + def p_param(self, p): + '''param : ID COLON TYPE''' + p[0] = (p.slice[1], p.slice[3]) + + def p_expr_block(self, p): + '''expr_block : expr SEMI + | expr SEMI expr_block''' + if len(p) == 3: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[3] + + def p_let_list(self, p): + '''let_list : ID COLON TYPE + | ID COLON TYPE ASSIGN expr + | ID COLON TYPE COMMA let_list + | ID COLON TYPE ASSIGN expr COMMA let_list''' + if len(p) == 4: + p[0] = [LetVariableDeclaration(p.slice[1], p.slice[3], None)] + elif len(p) == 6 and p.slice[4].lex == '<-': + p[0] = [LetVariableDeclaration( + p.slice[1], p.slice[3], p[5])] + elif len(p) == 6: + p[0] = [LetVariableDeclaration( + p.slice[1], p.slice[3], None)] + p[5] + else: + p[0] = [LetVariableDeclaration( + p.slice[1], p.slice[3], p[5])] + p[7] + + def p_case_list(self, p): + '''case_list : ID COLON TYPE ACTION expr SEMI + | ID COLON TYPE ACTION expr SEMI case_list ''' + if len(p) == 7: + p[0] = [CaseVariableDeclaration( + p.slice[1], p.slice[3], p[5])] + else: + p[0] = [CaseVariableDeclaration( + p.slice[1], p.slice[3], p[5])] + p[7] + + def p_case_list_error(self, p): + '''case_list : error COLON TYPE ACTION expr SEMI + | ID COLON error ACTION expr SEMI + | ID COLON TYPE ACTION error SEMI + | ID COLON TYPE error error SEMI + | error COLON error ACTION expr SEMI + | error COLON TYPE ACTION error SEMI + | error COLON error ACTION error SEMI + | error COLON TYPE ACTION expr SEMI case_list + | ID COLON error ACTION expr SEMI case_list + | ID COLON TYPE ACTION error SEMI case_list + | ID COLON TYPE error error SEMI case_list + | error COLON error ACTION expr SEMI case_list + | error COLON TYPE ACTION error SEMI case_list + | error COLON error ACTION error SEMI case_list''' + p[0] = ErrorNode() + + def p_func_call(self, p): + '''funccall : ID OPAR CPAR + | ID OPAR arg_list CPAR''' + if len(p) == 4: + p[0] = (p.slice[1], []) + else: + p[0] = (p.slice[1], p[3]) + + def p_func_call_error(self, p): + '''funccall : error OPAR CPAR + | ID OPAR error CPAR + | error OPAR arg_list CPAR + | error OPAR error CPAR''' + p[0] = ErrorNode() + + def p_arg_list(self, p): + ''' arg_list : expr + | expr COMMA arg_list''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1]] + p[3] + + def p_arg_list_error(self, p): + ''' arg_list : error + | error COMMA arg_list''' + p[0] = [ErrorNode()] + + def p_expr(self, p): + '''expr : ID ASSIGN expr + | operat ''' + if len(p) == 4: + p[0] = AssignNode(p.slice[1], p[3]) + else: + p[0] = p[1] + + def p_expr_error(self, p): + '''expr : ID ASSIGN error + | error ASSIGN expr ''' + p[0] = ErrorNode() + + def p_comp(self, p): + '''operat : operat LESSEQUAL operat + | operat LESS operat + | operat EQUAL operat''' + if p.slice[2].lex == '<=': + p[0] = LessEqualNode(p[1], p[3]) + elif p.slice[2].lex == '<': + p[0] = LessNode(p[1], p[3]) + else: + p[0] = EqualNode(p[1], p[3]) + + def p_arith(self, p): + '''operat : operat PLUS operat + | operat MINUS operat + | operat STAR operat + | operat DIV operat ''' + if p.slice[2].lex == '+': + p[0] = PlusNode(p[1], p[3]) + elif p.slice[2].lex == '-': + p[0] = MinusNode(p[1], p[3]) + elif p.slice[2].lex == '*': + p[0] = StarNode(p[1], p[3]) + else: + p[0] = DivNode(p[1], p[3]) + + def p_operat_error(self, p): + '''operat : operat LESSEQUAL error + | operat LESS error + | operat EQUAL error + | operat PLUS error + | operat MINUS error + | operat STAR error + | operat DIV error ''' + p[0] = ErrorNode() + + def p_base_operat(self, p): + '''operat : baseop''' + p[0] = p[1] + + def p_static_call(self, p): + '''baseop : subatom AT TYPE DOT funccall ''' + p[0] = FunctionCallNode(p[1], *p[5], p.slice[3]) + + def p_static_call_error(self, p): + '''baseop : error AT TYPE DOT funccall + | subatom AT error DOT funccall + | subatom AT TYPE DOT error + | error AT error DOT funccall + | error AT TYPE DOT error + | subatom AT error DOT error + | error AT error DOT error ''' + p[0] = ErrorNode() + + def p_sub_atom(self, p): + '''baseop : subatom''' + p[0] = p[1] + + def p_parent_expr(self, p): + '''subatom : OPAR expr CPAR''' + p[0] = p[1] + + def p_parent_expr_error(self, p): + '''subatom : error expr CPAR + | OPAR expr error''' + p[0] = ErrorNode() + + def p_dynamic_call(self, p): + '''subatom : subatom DOT funccall ''' + p[0] = FunctionCallNode(p[1], *p[3]) + + def p_dynamic_call_error(self, p): + '''subatom : subatom DOT error + | error DOT funccall + | error DOT error ''' + p[0] = ErrorNode() + + def p_member_call(self, p): + '''subatom : funccall ''' + p[0] = MemberCallNode(*p[1]) + + def p_unary_operations(self, p): + '''subatom : INT_COMPLEMENT baseop + | NOT baseop + | ISVOID baseop ''' + if p.slice[1].lex == '~': + p[0] = ComplementNode(p[2]) + elif p.slice[1].lex == 'not': + p[0] = NotNode(p[2]) + else: + p[0] = IsVoidNode(p[2]) + + # def p_unary_operations_error(self, p): + # '''subatom : INT_COMPLEMENT error + # | NOT error + # | ISVOID error ''' + # p[0] = ErrorNode() + + def p_complex_sub_atom(self, p): + '''subatom : IF expr THEN expr ELSE expr FI + | WHILE expr LOOP expr POOL + | LET let_list IN expr + | CASE expr OF case_list ESAC ''' + #| LET let_list + if p.slice[1].lex == 'if': + p[0] = IfThenElseNode(p[2], p[4], p[6]) + elif p.slice[1].lex == 'while': + p[0] = WhileLoopNode(p[2], p[4]) + elif p.slice[1].lex == 'let': + p[0] = LetInNode(p[2], p[4]) + # elif p.slice[1].lex == 'let': + # p[0] = LetInNode(p[2], None) + else: + p[0] = CaseOfNode(p[2], p[4]) + + def p_atom(self, p): + '''subatom : atom''' + p[0] = p[1] + + def p_new(self, p): + '''atom : NEW TYPE''' + p[0] = NewNode(p.slice[2]) + + def p_new_error(self, p): + '''atom : NEW error''' + p[0] = ErrorNode() + + def p_atom_expr_block(self, p): + '''atom : OCURL expr_block CCURL ''' + p[0] = BlockNode(p[2]) + + def p_atom_expr_block_error(self, p): + '''atom : OCURL error CCURL ''' + p[0] = ErrorNode() + + def p_atom_id(self, p): + '''expr : ID''' + p[0] = IdNode(p.slice[1]) + + def p_atom_integer(self, p): + '''atom : INTEGER''' + p[0] = IntegerNode(p.slice[1]) + + def p_atom_string(self, p): + '''atom : STRING''' + p[0] = StringNode(p.slice[1]) + + def p_atom_bool(self, p): + '''atom : BOOL''' + p[0] = BoolNode(p.slice[1]) + + def p_error(self, p): + if p is None: + colm = find_column(self.lexer.lexer, self.lexer.lexer) + line = self.lexer.lexer.lineno + error = SyntacticError( + line, colm, 'ERROR at or near "%s"' % 'EOF') + self.error_list.append(error) + else: + error = SyntacticError( + p.lineno, p.lexpos, 'ERROR at or near "%s"' % p.lex) + self.error_list.append(error) diff --git a/src/engine/parser/parsetab.py b/src/engine/parser/parsetab.py new file mode 100644 index 00000000..51f102fa --- /dev/null +++ b/src/engine/parser/parsetab.py @@ -0,0 +1,167 @@ + +# parsetab.py +# This file is automatically generated. Do not edit. +# pylint: disable=W,C,R +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'programrightASSIGNrightNOTnonassocLESSLESSEQUALEQUALleftPLUSMINUSleftSTARDIVrightISVOIDrightINT_COMPLEMENTleftATleftDOTACTION ASSIGN AT BOOL CASE CCURL CLASS COLON COMMA CPAR DIV DOT ELSE EQUAL ESAC FI ID IF IN INHERITS INTEGER INT_COMPLEMENT ISVOID LESS LESSEQUAL LET LOOP MINUS NEW NOT OCURL OF OPAR PLUS POOL SEMI STAR STRING THEN TYPE WHILEepsilon :program : class_listclass_list : def_class class_list\n | def_classclass_list : error class_list def_class : CLASS TYPE OCURL feature_list CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI def_class : CLASS error OCURL feature_list CCURL SEMI\n | CLASS TYPE OCURL error CCURL SEMI\n | CLASS error OCURL error CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI\n | CLASS TYPE INHERITS error OCURL error CCURL SEMI\n | CLASS error INHERITS TYPE OCURL error CCURL SEMI\n | CLASS error INHERITS error OCURL feature_list CCURL SEMI\n | CLASS error INHERITS error OCURL error CCURL SEMI feature_list : feature feature_list\n | epsilonfeature_list : error feature_listfeature : ID COLON TYPE SEMI\n | ID COLON TYPE ASSIGN expr SEMI feature : error COLON TYPE\n | ID COLON error\n | error COLON error\n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON error ASSIGN errorfeature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI\n | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR CPAR COLON error OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID error CPAR COLON error OCURL error CCURL SEMI param_list : param\n | param COMMA param_listparam : ID COLON TYPEexpr_block : expr SEMI\n | expr SEMI expr_blocklet_list : ID COLON TYPE\n | ID COLON TYPE ASSIGN expr\n | ID COLON TYPE COMMA let_list\n | ID COLON TYPE ASSIGN expr COMMA let_listcase_list : ID COLON TYPE ACTION expr SEMI\n | ID COLON TYPE ACTION expr SEMI case_list case_list : error COLON TYPE ACTION expr SEMI\n | ID COLON error ACTION expr SEMI\n | ID COLON TYPE ACTION error SEMI\n | ID COLON TYPE error error SEMI\n | error COLON error ACTION expr SEMI\n | error COLON TYPE ACTION error SEMI\n | error COLON error ACTION error SEMI\n | error COLON TYPE ACTION expr SEMI case_list\n | ID COLON error ACTION expr SEMI case_list\n | ID COLON TYPE ACTION error SEMI case_list\n | ID COLON TYPE error error SEMI case_list\n | error COLON error ACTION expr SEMI case_list\n | error COLON TYPE ACTION error SEMI case_list\n | error COLON error ACTION error SEMI case_listfunccall : ID OPAR CPAR\n | ID OPAR arg_list CPARfunccall : error OPAR CPAR\n | ID OPAR error CPAR\n | error OPAR arg_list CPAR\n | error OPAR error CPAR arg_list : expr\n | expr COMMA arg_list arg_list : error\n | error COMMA arg_listexpr : ID ASSIGN expr\n | operat expr : ID ASSIGN error \n | error ASSIGN expr operat : operat LESSEQUAL operat\n | operat LESS operat\n | operat EQUAL operatoperat : operat PLUS operat\n | operat MINUS operat\n | operat STAR operat\n | operat DIV operat operat : operat LESSEQUAL error\n | operat LESS error\n | operat EQUAL error\n | operat PLUS error\n | operat MINUS error\n | operat STAR error\n | operat DIV error operat : baseopbaseop : subatom AT TYPE DOT funccall baseop : error AT TYPE DOT funccall\n | subatom AT error DOT funccall\n | subatom AT TYPE DOT error\n | error AT error DOT funccall\n | error AT TYPE DOT error\n | subatom AT error DOT error\n | error AT error DOT error baseop : subatomsubatom : OPAR expr CPARsubatom : error expr CPAR\n | OPAR expr errorsubatom : subatom DOT funccall subatom : subatom DOT error \n | error DOT funccall\n | error DOT error subatom : funccall subatom : INT_COMPLEMENT baseop\n | NOT baseop\n | ISVOID baseop subatom : IF expr THEN expr ELSE expr FI\n | WHILE expr LOOP expr POOL\n | LET let_list IN expr \n | CASE expr OF case_list ESAC subatom : atomatom : NEW TYPEatom : NEW erroratom : OCURL expr_block CCURL atom : OCURL error CCURL expr : IDatom : INTEGERatom : STRINGatom : BOOL' + +_lr_action_items = {'error':([0,3,4,5,10,11,12,13,15,16,18,21,26,29,30,32,34,35,36,39,40,41,42,43,44,51,57,59,60,61,64,65,71,72,73,74,76,84,85,86,87,88,89,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,108,113,114,115,118,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,149,150,156,157,159,165,166,167,168,171,172,175,176,179,180,181,182,184,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,211,212,213,215,216,217,218,219,220,221,222,225,227,228,230,231,233,234,235,236,237,238,239,240,241,242,243,244,245,248,255,257,259,266,274,275,276,277,278,281,282,283,284,285,286,287,289,290,291,299,300,301,302,306,307,308,309,315,319,320,321,322,323,324,325,326,327,328,329,330,331,333,334,335,336,337,340,343,345,347,348,349,350,351,352,353,354,],[4,4,4,9,15,20,21,23,26,26,33,26,26,43,45,51,55,57,58,61,63,-6,-9,-23,-21,-22,26,-10,-8,26,84,105,-19,113,114,116,120,128,-29,-134,-87,-104,-113,-121,128,147,147,147,128,128,128,-129,157,159,-135,-136,-137,128,-24,161,163,128,128,-25,170,173,-7,-11,-12,-15,-14,-13,128,128,177,179,181,186,189,192,194,196,198,200,202,204,206,208,210,-122,128,-123,-124,-130,-131,128,128,-20,224,225,230,231,-89,-115,-120,-119,128,-78,210,-86,128,-76,128,-90,128,-91,128,-92,128,-93,128,-94,128,-95,128,-96,128,-117,-118,-114,-116,128,128,128,252,-132,-133,128,254,255,257,259,128,266,128,128,128,272,128,274,276,181,-81,278,-80,278,-77,-79,282,283,-127,128,128,128,128,-112,-109,-110,-106,128,-105,-108,-111,-107,128,-126,128,-128,316,317,-44,-50,-48,-49,-32,-46,-47,-45,334,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,340,341,128,343,345,128,128,128,252,252,252,252,252,252,252,252,]),'CLASS':([0,3,4,41,42,59,60,122,123,124,125,126,127,],[5,5,5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'$end':([1,2,3,6,7,41,42,59,60,122,123,124,125,126,127,],[0,-2,-4,-3,-5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'TYPE':([5,11,13,29,32,68,70,74,76,100,107,108,118,121,131,143,214,290,291,],[8,19,24,44,50,109,111,117,119,156,162,164,169,174,178,205,249,315,318,]),'OCURL':([8,9,19,20,23,24,64,65,72,73,84,91,92,93,94,95,96,98,101,105,109,113,114,116,117,119,120,128,129,133,134,135,136,137,138,139,140,141,142,147,159,161,162,163,164,165,168,169,170,171,172,173,174,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[10,12,35,36,39,40,101,101,101,101,101,101,101,101,101,101,101,101,101,101,165,101,101,167,168,171,172,101,101,101,101,101,101,101,101,101,101,101,101,101,101,219,220,221,222,101,101,227,228,101,101,233,234,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'INHERITS':([8,9,],[11,13,]),'ID':([10,12,15,16,21,26,30,34,35,39,43,44,51,57,61,64,65,69,71,72,73,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,101,102,103,104,105,106,113,114,115,128,129,132,133,134,135,136,137,138,139,140,141,142,144,146,147,149,150,156,157,159,165,166,168,171,172,175,176,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,211,212,213,215,216,217,218,220,221,222,225,227,228,230,231,234,235,236,237,238,239,240,241,242,243,244,245,248,255,257,259,266,274,275,276,277,278,281,282,283,284,285,286,287,288,289,299,300,301,302,306,307,308,309,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,335,336,337,340,343,345,347,348,349,350,351,352,353,354,],[18,18,18,18,18,18,49,49,18,18,-23,-21,-22,18,18,86,86,49,-19,86,86,86,-29,-134,-87,-104,-113,-121,86,148,148,148,86,86,154,86,-129,86,-135,-136,-137,86,-24,86,86,-25,86,86,148,86,86,86,148,148,148,148,148,148,148,148,-122,86,-123,-124,-130,-131,86,86,-20,86,86,86,-89,-115,-120,-119,86,-78,-86,86,-76,86,-90,86,-91,86,-92,86,-93,86,-94,86,-95,86,-96,86,-117,-118,-114,-116,86,86,86,251,-132,-133,86,86,86,86,86,86,86,86,86,86,148,148,86,-81,86,-80,86,-77,-79,148,148,-127,86,86,86,86,-112,-109,-110,-106,86,-105,-108,-111,-107,86,-126,86,154,-128,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,154,86,86,86,86,86,86,86,251,251,251,251,251,251,251,251,]),'CCURL':([10,12,14,15,16,17,21,22,26,28,31,35,39,43,44,51,56,57,58,61,62,63,71,84,85,86,87,88,89,90,99,102,103,104,105,106,113,114,115,146,149,150,156,157,158,159,166,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,218,223,224,225,226,229,230,231,232,238,240,242,243,248,253,254,255,256,257,258,259,260,265,266,267,272,273,274,275,276,277,281,282,283,284,286,289,299,300,301,302,306,307,308,309,319,320,321,322,323,324,325,326,327,328,329,330,331,],[-1,-1,25,27,-1,-17,37,38,-1,-18,-16,-1,-1,-23,-21,-22,78,79,80,81,82,83,-19,-30,-29,-134,-87,-104,-113,-121,-129,-135,-136,-137,-28,-24,-26,-27,-25,-122,-123,-124,-130,-131,216,217,-20,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-54,261,262,263,264,268,269,270,271,-81,-80,-77,-79,-127,-55,292,293,294,295,296,297,298,303,304,305,310,311,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,]),'COLON':([15,18,21,26,47,49,52,54,57,61,66,67,75,77,154,251,252,],[29,32,29,29,68,70,74,76,29,29,107,108,118,121,214,290,291,]),'OPAR':([15,18,21,26,57,61,64,65,72,73,84,86,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,148,159,165,168,171,172,179,181,186,189,192,194,196,198,200,202,204,208,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,274,276,278,282,283,285,287,333,335,336,337,340,343,345,],[30,34,30,30,30,30,91,91,91,91,133,135,91,91,91,91,91,91,91,91,133,133,133,133,91,91,91,91,91,91,91,91,91,91,91,133,135,133,91,91,91,91,237,133,133,133,133,133,133,133,133,133,133,237,91,91,91,91,91,91,91,133,91,91,133,133,91,91,91,91,133,133,133,133,237,237,133,237,237,91,91,91,91,91,91,133,133,133,]),'SEMI':([25,27,37,38,50,78,79,80,81,82,83,86,87,88,89,90,99,102,103,104,112,146,149,150,156,157,160,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,261,262,263,264,268,269,270,271,274,275,276,277,281,282,283,284,286,289,292,293,294,295,296,297,298,303,304,305,310,311,331,339,340,341,342,343,344,345,346,],[41,42,59,60,71,122,123,124,125,126,127,-134,-87,-104,-113,-121,-129,-135,-136,-137,166,-122,-123,-124,-130,-131,218,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,299,300,301,302,306,307,308,309,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,319,320,321,322,323,324,325,326,327,328,329,330,-125,347,348,349,350,351,352,353,354,]),'CPAR':([30,33,34,45,46,48,53,55,86,87,88,89,90,99,102,103,104,110,111,130,133,135,145,146,149,150,156,157,175,176,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,237,238,240,242,243,248,274,275,276,277,278,279,280,281,282,283,284,286,289,331,],[47,52,54,66,67,-51,75,77,-134,-87,-104,-113,-121,-129,-135,-136,-137,-52,-53,176,182,187,209,-122,-123,-124,-130,-131,-89,-115,-120,-119,238,-78,240,209,-86,-88,-76,242,243,-82,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,182,-81,-80,-77,-79,-127,-112,-109,-110,-106,-84,-85,-83,-105,-108,-111,-107,-126,-128,-125,]),'ASSIGN':([43,44,50,51,84,86,105,113,114,128,159,181,186,189,225,230,231,249,255,257,259,266,278,340,343,345,],[64,65,72,73,129,134,129,129,129,129,129,129,129,129,129,129,129,287,129,129,129,129,129,129,129,129,]),'COMMA':([48,86,87,88,89,90,99,102,103,104,111,146,149,150,156,157,175,176,179,180,181,182,184,185,186,187,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,249,274,275,276,277,278,281,282,283,284,286,289,313,331,],[69,-134,-87,-104,-113,-121,-129,-135,-136,-137,-53,-122,-123,-124,-130,-131,-89,-115,-120,-119,239,-78,241,-86,-88,-76,239,241,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,288,-112,-109,-110,-106,239,-105,-108,-111,-107,-126,-128,332,-125,]),'INT_COMPLEMENT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'NOT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,]),'ISVOID':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,]),'IF':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'WHILE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,]),'LET':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'CASE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'NEW':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'INTEGER':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,]),'STRING':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'BOOL':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'AT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,146,147,149,150,156,157,159,175,176,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,225,230,231,238,240,242,243,248,255,257,259,266,274,275,276,277,278,281,282,283,284,286,289,331,340,343,345,],[131,-134,-87,-104,143,-121,-129,-135,-136,-137,131,131,131,131,-122,131,-123,-124,-130,-131,131,-89,-115,-120,-119,131,-78,-86,131,-76,131,-90,131,-91,131,-92,131,-93,131,-94,131,-95,131,-96,131,-117,-118,-114,-116,-132,-133,131,131,131,-81,-80,-77,-79,-127,131,131,131,131,-112,-109,-110,-106,131,-105,-108,-111,-107,-126,-128,-125,131,131,131,]),'DOT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,146,147,149,150,156,157,159,175,176,177,178,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,216,217,225,230,231,238,240,242,243,248,255,257,259,266,274,275,276,277,278,281,282,283,284,286,289,331,340,343,345,],[132,-134,-87,-104,144,-121,-129,-135,-136,-137,132,132,132,132,-122,132,-123,-124,-130,-131,132,-89,-115,235,236,-120,-119,132,-78,-86,132,-76,132,-90,132,-91,132,-92,132,-93,132,-94,132,-95,132,-96,132,244,245,-117,-118,-114,-116,-132,-133,132,132,132,-81,-80,-77,-79,-127,132,132,132,132,-112,-109,-110,-106,132,-105,-108,-111,-107,-126,-128,-125,132,132,132,]),'THEN':([86,87,88,89,90,99,102,103,104,146,149,150,151,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,211,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LOOP':([86,87,88,89,90,99,102,103,104,146,149,150,152,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,212,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'OF':([86,87,88,89,90,99,102,103,104,146,149,150,155,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,215,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LESSEQUAL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,136,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,136,-97,136,-98,136,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LESS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,137,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,137,-97,137,-98,137,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'EQUAL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,138,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,138,-97,138,-98,138,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'PLUS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,139,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,139,-97,139,-98,139,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'MINUS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,140,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,140,-97,140,-98,140,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'STAR':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,141,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,141,-97,141,-98,141,-99,141,-100,141,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'DIV':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,142,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,142,-97,142,-98,142,-99,142,-100,142,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'ELSE':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,246,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,285,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'POOL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,247,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,286,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'FI':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,312,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,331,-125,]),'IN':([86,87,88,89,90,99,102,103,104,146,149,150,153,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,249,274,275,276,277,281,282,283,284,286,289,313,314,331,338,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,213,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-56,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-57,-58,-125,-59,]),'ESAC':([250,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,],[289,-60,-64,-65,-63,-68,-66,-67,-62,-61,-71,-72,-70,-75,-73,-74,-69,]),'ACTION':([315,316,317,318,],[333,335,336,337,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'program':([0,],[1,]),'class_list':([0,3,4,],[2,6,7,]),'def_class':([0,3,4,],[3,3,3,]),'feature_list':([10,12,15,16,21,26,35,39,57,61,],[14,22,28,31,28,28,56,62,28,28,]),'feature':([10,12,15,16,21,26,35,39,57,61,],[16,16,16,16,16,16,16,16,16,16,]),'epsilon':([10,12,15,16,21,26,35,39,57,61,],[17,17,17,17,17,17,17,17,17,17,]),'param_list':([30,34,69,],[46,53,110,]),'param':([30,34,69,],[48,48,48,]),'expr':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,133,134,135,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[85,106,112,115,130,145,151,152,155,160,130,130,130,130,175,184,185,190,130,130,223,226,229,232,130,130,130,130,130,130,130,130,130,130,246,247,248,160,256,258,260,130,265,267,130,130,273,190,190,190,130,130,130,130,130,312,313,339,342,344,346,130,130,130,]),'operat':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,191,193,195,197,199,201,203,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'baseop':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[88,88,88,88,88,88,146,149,150,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,]),'subatom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,]),'funccall':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,132,133,134,135,136,137,138,139,140,141,142,144,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,235,236,237,239,241,244,245,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,180,90,90,90,90,90,90,90,90,90,90,207,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,275,277,90,90,90,281,284,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'atom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'let_list':([97,288,332,],[153,314,338,]),'expr_block':([101,218,],[158,253,]),'arg_list':([133,135,237,239,241,],[183,188,183,279,280,]),'case_list':([215,347,348,349,350,351,352,353,354,],[250,355,356,357,358,359,360,361,362,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> program","S'",1,None,None,None), + ('epsilon -> ','epsilon',0,'p_epsilon','cool_parser.py',38), + ('program -> class_list','program',1,'p_program','cool_parser.py',42), + ('class_list -> def_class class_list','class_list',2,'p_class_list','cool_parser.py',46), + ('class_list -> def_class','class_list',1,'p_class_list','cool_parser.py',47), + ('class_list -> error class_list','class_list',2,'p_class_list_error','cool_parser.py',54), + ('def_class -> CLASS TYPE OCURL feature_list CCURL SEMI','def_class',6,'p_def_class','cool_parser.py',61), + ('def_class -> CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI','def_class',8,'p_def_class','cool_parser.py',62), + ('def_class -> CLASS error OCURL feature_list CCURL SEMI','def_class',6,'p_def_class_error','cool_parser.py',70), + ('def_class -> CLASS TYPE OCURL error CCURL SEMI','def_class',6,'p_def_class_error','cool_parser.py',71), + ('def_class -> CLASS error OCURL error CCURL SEMI','def_class',6,'p_def_class_error','cool_parser.py',72), + ('def_class -> CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI','def_class',8,'p_def_class_error','cool_parser.py',73), + ('def_class -> CLASS TYPE INHERITS error OCURL error CCURL SEMI','def_class',8,'p_def_class_error','cool_parser.py',74), + ('def_class -> CLASS error INHERITS TYPE OCURL error CCURL SEMI','def_class',8,'p_def_class_error','cool_parser.py',75), + ('def_class -> CLASS error INHERITS error OCURL feature_list CCURL SEMI','def_class',8,'p_def_class_error','cool_parser.py',76), + ('def_class -> CLASS error INHERITS error OCURL error CCURL SEMI','def_class',8,'p_def_class_error','cool_parser.py',77), + ('feature_list -> feature feature_list','feature_list',2,'p_feature_list','cool_parser.py',81), + ('feature_list -> epsilon','feature_list',1,'p_feature_list','cool_parser.py',82), + ('feature_list -> error feature_list','feature_list',2,'p_feature_list_error','cool_parser.py',89), + ('feature -> ID COLON TYPE SEMI','feature',4,'p_feature_attribute','cool_parser.py',93), + ('feature -> ID COLON TYPE ASSIGN expr SEMI','feature',6,'p_feature_attribute','cool_parser.py',94), + ('feature -> error COLON TYPE','feature',3,'p_def_attribute_error','cool_parser.py',102), + ('feature -> ID COLON error','feature',3,'p_def_attribute_error','cool_parser.py',103), + ('feature -> error COLON error','feature',3,'p_def_attribute_error','cool_parser.py',104), + ('feature -> error COLON TYPE ASSIGN expr','feature',5,'p_def_attribute_error','cool_parser.py',105), + ('feature -> ID COLON error ASSIGN expr','feature',5,'p_def_attribute_error','cool_parser.py',106), + ('feature -> ID COLON TYPE ASSIGN error','feature',5,'p_def_attribute_error','cool_parser.py',107), + ('feature -> ID COLON error ASSIGN error','feature',5,'p_def_attribute_error','cool_parser.py',108), + ('feature -> error COLON TYPE ASSIGN error','feature',5,'p_def_attribute_error','cool_parser.py',109), + ('feature -> error COLON error ASSIGN expr','feature',5,'p_def_attribute_error','cool_parser.py',110), + ('feature -> error COLON error ASSIGN error','feature',5,'p_def_attribute_error','cool_parser.py',111), + ('feature -> ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI','feature',10,'p_feature_function','cool_parser.py',115), + ('feature -> ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI','feature',9,'p_feature_function','cool_parser.py',116), + ('feature -> error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',125), + ('feature -> ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',126), + ('feature -> ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',127), + ('feature -> ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',128), + ('feature -> error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',129), + ('feature -> error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',130), + ('feature -> error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',131), + ('feature -> ID OPAR error CPAR COLON error OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',132), + ('feature -> error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',133), + ('feature -> error OPAR error CPAR COLON error OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',134), + ('feature -> error OPAR param_list CPAR COLON error OCURL error CCURL SEMI','feature',10,'p_feature_function_error','cool_parser.py',135), + ('feature -> error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',136), + ('feature -> ID OPAR CPAR COLON error OCURL expr CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',137), + ('feature -> ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',138), + ('feature -> ID OPAR CPAR COLON error OCURL error CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',139), + ('feature -> ID error CPAR COLON TYPE OCURL error CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',140), + ('feature -> ID error CPAR COLON TYPE OCURL expr CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',141), + ('feature -> ID error CPAR COLON error OCURL error CCURL SEMI','feature',9,'p_feature_function_error','cool_parser.py',142), + ('param_list -> param','param_list',1,'p_param_list','cool_parser.py',146), + ('param_list -> param COMMA param_list','param_list',3,'p_param_list','cool_parser.py',147), + ('param -> ID COLON TYPE','param',3,'p_param','cool_parser.py',154), + ('expr_block -> expr SEMI','expr_block',2,'p_expr_block','cool_parser.py',158), + ('expr_block -> expr SEMI expr_block','expr_block',3,'p_expr_block','cool_parser.py',159), + ('let_list -> ID COLON TYPE','let_list',3,'p_let_list','cool_parser.py',166), + ('let_list -> ID COLON TYPE ASSIGN expr','let_list',5,'p_let_list','cool_parser.py',167), + ('let_list -> ID COLON TYPE COMMA let_list','let_list',5,'p_let_list','cool_parser.py',168), + ('let_list -> ID COLON TYPE ASSIGN expr COMMA let_list','let_list',7,'p_let_list','cool_parser.py',169), + ('case_list -> ID COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list','cool_parser.py',183), + ('case_list -> ID COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list','cool_parser.py',184), + ('case_list -> error COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',193), + ('case_list -> ID COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',194), + ('case_list -> ID COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',195), + ('case_list -> ID COLON TYPE error error SEMI','case_list',6,'p_case_list_error','cool_parser.py',196), + ('case_list -> error COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',197), + ('case_list -> error COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',198), + ('case_list -> error COLON error ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',199), + ('case_list -> error COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',200), + ('case_list -> ID COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',201), + ('case_list -> ID COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',202), + ('case_list -> ID COLON TYPE error error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',203), + ('case_list -> error COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',204), + ('case_list -> error COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',205), + ('case_list -> error COLON error ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',206), + ('funccall -> ID OPAR CPAR','funccall',3,'p_func_call','cool_parser.py',210), + ('funccall -> ID OPAR arg_list CPAR','funccall',4,'p_func_call','cool_parser.py',211), + ('funccall -> error OPAR CPAR','funccall',3,'p_func_call_error','cool_parser.py',218), + ('funccall -> ID OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',219), + ('funccall -> error OPAR arg_list CPAR','funccall',4,'p_func_call_error','cool_parser.py',220), + ('funccall -> error OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',221), + ('arg_list -> expr','arg_list',1,'p_arg_list','cool_parser.py',225), + ('arg_list -> expr COMMA arg_list','arg_list',3,'p_arg_list','cool_parser.py',226), + ('arg_list -> error','arg_list',1,'p_arg_list_error','cool_parser.py',233), + ('arg_list -> error COMMA arg_list','arg_list',3,'p_arg_list_error','cool_parser.py',234), + ('expr -> ID ASSIGN expr','expr',3,'p_expr','cool_parser.py',238), + ('expr -> operat','expr',1,'p_expr','cool_parser.py',239), + ('expr -> ID ASSIGN error','expr',3,'p_expr_error','cool_parser.py',246), + ('expr -> error ASSIGN expr','expr',3,'p_expr_error','cool_parser.py',247), + ('operat -> operat LESSEQUAL operat','operat',3,'p_comp','cool_parser.py',251), + ('operat -> operat LESS operat','operat',3,'p_comp','cool_parser.py',252), + ('operat -> operat EQUAL operat','operat',3,'p_comp','cool_parser.py',253), + ('operat -> operat PLUS operat','operat',3,'p_arith','cool_parser.py',262), + ('operat -> operat MINUS operat','operat',3,'p_arith','cool_parser.py',263), + ('operat -> operat STAR operat','operat',3,'p_arith','cool_parser.py',264), + ('operat -> operat DIV operat','operat',3,'p_arith','cool_parser.py',265), + ('operat -> operat LESSEQUAL error','operat',3,'p_operat_error','cool_parser.py',276), + ('operat -> operat LESS error','operat',3,'p_operat_error','cool_parser.py',277), + ('operat -> operat EQUAL error','operat',3,'p_operat_error','cool_parser.py',278), + ('operat -> operat PLUS error','operat',3,'p_operat_error','cool_parser.py',279), + ('operat -> operat MINUS error','operat',3,'p_operat_error','cool_parser.py',280), + ('operat -> operat STAR error','operat',3,'p_operat_error','cool_parser.py',281), + ('operat -> operat DIV error','operat',3,'p_operat_error','cool_parser.py',282), + ('operat -> baseop','operat',1,'p_base_operat','cool_parser.py',286), + ('baseop -> subatom AT TYPE DOT funccall','baseop',5,'p_static_call','cool_parser.py',290), + ('baseop -> error AT TYPE DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',294), + ('baseop -> subatom AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',295), + ('baseop -> subatom AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',296), + ('baseop -> error AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',297), + ('baseop -> error AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',298), + ('baseop -> subatom AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',299), + ('baseop -> error AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',300), + ('baseop -> subatom','baseop',1,'p_sub_atom','cool_parser.py',304), + ('subatom -> OPAR expr CPAR','subatom',3,'p_parent_expr','cool_parser.py',308), + ('subatom -> error expr CPAR','subatom',3,'p_parent_expr_error','cool_parser.py',312), + ('subatom -> OPAR expr error','subatom',3,'p_parent_expr_error','cool_parser.py',313), + ('subatom -> subatom DOT funccall','subatom',3,'p_dynamic_call','cool_parser.py',317), + ('subatom -> subatom DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',321), + ('subatom -> error DOT funccall','subatom',3,'p_dynamic_call_error','cool_parser.py',322), + ('subatom -> error DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',323), + ('subatom -> funccall','subatom',1,'p_member_call','cool_parser.py',327), + ('subatom -> INT_COMPLEMENT baseop','subatom',2,'p_unary_operations','cool_parser.py',331), + ('subatom -> NOT baseop','subatom',2,'p_unary_operations','cool_parser.py',332), + ('subatom -> ISVOID baseop','subatom',2,'p_unary_operations','cool_parser.py',333), + ('subatom -> IF expr THEN expr ELSE expr FI','subatom',7,'p_complex_sub_atom','cool_parser.py',348), + ('subatom -> WHILE expr LOOP expr POOL','subatom',5,'p_complex_sub_atom','cool_parser.py',349), + ('subatom -> LET let_list IN expr','subatom',4,'p_complex_sub_atom','cool_parser.py',350), + ('subatom -> CASE expr OF case_list ESAC','subatom',5,'p_complex_sub_atom','cool_parser.py',351), + ('subatom -> atom','subatom',1,'p_atom','cool_parser.py',365), + ('atom -> NEW TYPE','atom',2,'p_new','cool_parser.py',369), + ('atom -> NEW error','atom',2,'p_new_error','cool_parser.py',373), + ('atom -> OCURL expr_block CCURL','atom',3,'p_atom_expr_block','cool_parser.py',377), + ('atom -> OCURL error CCURL','atom',3,'p_atom_expr_block_error','cool_parser.py',381), + ('expr -> ID','expr',1,'p_atom_id','cool_parser.py',385), + ('atom -> INTEGER','atom',1,'p_atom_integer','cool_parser.py',389), + ('atom -> STRING','atom',1,'p_atom_string','cool_parser.py',393), + ('atom -> BOOL','atom',1,'p_atom_bool','cool_parser.py',397), +] diff --git a/src/main.py b/src/main.py index 53433e3b..facdb309 100644 --- a/src/main.py +++ b/src/main.py @@ -5,17 +5,21 @@ args = sys.argv -if len(args) != 3: - exit(1) +# if len(args) != 3: +# exit(1) + +# input_file = open(args[1], "r") +# output_file = open(args[2], 'w') -input_file = open(args[1], "r") -output_file = open(args[2], 'w') +input_file = open('./src/test.cl', "r") +# output_file = open('./src/test.mips', 'w') t = input_file.read() # output_file = args[2] -tokens, errors = tokenizer(t) +lexer = CoolLexer() +tokens, errors = lexer.tokenize(t) # print(tokens) if len(errors): @@ -23,73 +27,77 @@ print(e) exit(1) +lexer.reset() +parser = CoolParser(lexer) +ast, errors = parser.parse(t) -parse, operations = CoolParser(tokens) -ast = evaluate_reverse_parse(parse, operations, tokens) - -#print(ast) +if errors: + for error in errors: + print(error) + exit(1) +# print(ast) fmatter = Format() tree = fmatter.visit(ast, 0) print(tree) -collect_errors = [] -collect = Collector(collect_errors) -collect.visit(ast) - -if len(collect_errors): - # print("coolector") - for e in collect_errors[::-1]: - print(e) - exit(1) - -context = collect.context -builder_errors = [] -builder = Builder(context, builder_errors) -builder.visit(ast) - -if len(builder_errors): - # print("builder") - for e in builder_errors[::-1]: - print(e) - exit(1) - -context = builder.context -checker_errors = [] -checker = Checker(context, checker_errors) -scope = checker.visit(ast) - -if len(checker_errors): - # print("checker") - for e in checker_errors[::-1]: - print(e) - exit(1) - - -cil = COOL_TO_CIL(checker.context) -# cil = COOL_TO_CIL_VISITOR(checker.context) -# sc = Scope() -cil_ast = cil.visit(ast) -# f_ast = Format().visit(ast) -emsamb = CIL_TO_MIPS() -emsamb.visit(cil_ast) -m_ast = emsamb.mips.compile() -# f_ast = CIL_FORMATTER().visit(cil_ast) -# string_formatted = str(f_ast) -output_file.write(m_ast) -output_file.write(str(collect_errors)) -# print(str(collect_errors)) -# output_file.write(str(builder_errors)) -# output_file.write(str(checker_errors)) -# output_file.write(collect_errors) +# collect_errors = [] +# collect = Collector(collect_errors) +# collect.visit(ast) + +# if len(collect_errors): +# # print("coolector") +# for e in collect_errors[::-1]: +# print(e) +# exit(1) + +# context = collect.context +# builder_errors = [] +# builder = Builder(context, builder_errors) +# builder.visit(ast) + +# if len(builder_errors): +# # print("builder") +# for e in builder_errors[::-1]: +# print(e) +# exit(1) + +# context = builder.context +# checker_errors = [] +# checker = Checker(context, checker_errors) +# scope = checker.visit(ast) + +# if len(checker_errors): +# # print("checker") +# for e in checker_errors[::-1]: +# print(e) +# exit(1) + + +# cil = COOL_TO_CIL(checker.context) +# # cil = COOL_TO_CIL_VISITOR(checker.context) +# # sc = Scope() +# cil_ast = cil.visit(ast) +# # f_ast = Format().visit(ast) +# emsamb = CIL_TO_MIPS() +# emsamb.visit(cil_ast) +# m_ast = emsamb.mips.compile() +# # f_ast = CIL_FORMATTER().visit(cil_ast) +# # string_formatted = str(f_ast) +# output_file.write(m_ast) +# output_file.write(str(collect_errors)) +# # print(str(collect_errors)) +# # output_file.write(str(builder_errors)) +# # output_file.write(str(checker_errors)) +# # output_file.write(collect_errors) output_file.close() -if not operations: - message = f'ERROR at or near "{parse.lex}"' - print(SyntacticError(parse.line, parse.column, message)) - exit(1) +# if not operations: +# message = f'ERROR at or near "{parse.lex}"' +# print(SyntacticError(parse.line, parse.column, message)) +# exit(1) # print(parse) diff --git a/src/test.cl b/src/test.cl index d0cba548..e179e479 100755 --- a/src/test.cl +++ b/src/test.cl @@ -1,27 +1,37 @@ -class Main inherits IO { +(* An assignment has the form <- *) - main () : Object { - "H" +class Main { + main(): Object { + (new Alpha).print() }; }; -class A { - m () : String { "A" }; - f () : A { new A }; -}; +class Test { + test1: Object; + + testing1(): Int { + 2 + 2 + }; -class B inherits A { - m () : String { "B" }; -}; + test2: Int <- 1; + test3: String <- "1"; -class C { - f () : String {"C"}; -}; + testing2(a: Alpha, b: Int): Int { + 2 + 2 + }; -class D inherits C { + testing3(): String { + "2 + 2" + }; + + testing4(): String { + Test1 <- "Hello World" -- Identifiers begin with a lower case letter + }; }; -class E inherits D { - f () : String {"E"}; +class Alpha inherits IO { + print() : Object { + out_string("reached!!\n") + }; }; From 85433d804348f7429d652c99db8b97e832c4214a Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 4 Dec 2020 10:32:15 -0500 Subject: [PATCH 077/191] label numeration fixed --- src/engine/codegen/cil.py | 4 +- src/engine/codegen/mips.py | 36 +- src/engine/codegen/to_cil.py | 38 +- src/engine/codegen/to_mips.py | 29 +- src/test.mips | 2957 ++++++++------------------------- 5 files changed, 733 insertions(+), 2331 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index a37eae7f..2d626dc9 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -10,6 +10,7 @@ def __init__(self, context): self.current_type = None self.current_method = None self.current_function = None + self.label_counter = 0 self.context = context self.define_object_type() self.define_string_type() @@ -49,9 +50,6 @@ def register_instruction(self, instruction): def to_function_name(self, method_name, type_name): return f'function_{method_name}_at_{type_name}' - def to_label_name(self, label_name): - return f'{label_name}' - def register_function(self, function_name): function_node = FunctionNode(function_name, [], [], []) self.dotcode.append(function_node) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index ab4fdfcd..46e6da31 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -97,26 +97,21 @@ def data_label(self, lname): def empty_line(self): self._write('') + def offset(self, r, offset: int = 0): + return f"{offset}({r})" + def asciiz(self, string): self._write_data(f'.asciiz "{string}"') - def push(self, register: Registers): - self.addi(Registers.sp, Registers.sp, -8) - self.store_memory(register, self.offset(Registers.sp)) + def push(self, register): + self.addi(reg.sp, reg.sp, -8) + self.store_memory(register, self.offset(reg.sp)) - def pop(self, register: Registers): - """ - First, load from to address `0($sp)` - and then write `addi $sp , $sp , 8` - to restore the stack pointer - """ + def pop(self, register): self.load_memory(register, self.offset(reg.sp)) self.addi(reg.sp, reg.sp, 8) - def load_memory(self, dst: Registers, address: str): - """ - Load from a specific address a 32 bits register - """ + def load_memory(self, dst, address: str): self.lw(reg.t8, address) self.sll(reg.t8, reg.t8, 16) self.la(reg.t7, address) @@ -125,9 +120,6 @@ def load_memory(self, dst: Registers, address: str): self.or_(dst, reg.t8, reg.t9) def store_memory(self, src: Registers, address: str): - """ - Write to a specific address a 32 bits register - """ self.la(reg.t8, address) self.srl(reg.t9, src, 16) @@ -138,12 +130,9 @@ def store_memory(self, src: Registers, address: str): # System Calls def syscall(self, code: int): - self.li(Registers.v0, code) + self.li(reg.v0, code) self._write('syscall') - def offset(self, r: Registers, offset: int = 0): - return f"{offset}({r})" - def comment(self, text: str): self._write(f"# {text}") @@ -297,6 +286,9 @@ def subu(self, rdest, rsrc1, src2): self._write(f'subu {rdest}, {rsrc1}, {src2}') def sll(self, dst, rl, value: int): + ''' + Shift Left Logical + ''' self._write(f"sll {dst}, {rl}, {value}") # Constant Manipulating @@ -440,12 +432,12 @@ def move(self, rdest, rsrc): def mfhi(self, rdest): ''' - Move from `hi` + Move from `high` ''' self._write(f'mfhi {rdest}') def mflo(self, rdest): ''' - Move from `lo` + Move from `low` ''' self._write(f'mflo {rdest}') diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 05ba7270..7ef04e0f 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -108,13 +108,22 @@ def visit(self, node: cool.AttrDeclarationNode, scope): self.register_instruction( SetAttribNode(self_inst, node.id.lex, result, self.current_type.name)) + @visitor.when(cool.BlockNode) + def visit(self, node: cool.BlockNode, scope): + result = self.define_internal_local() + for expr in node.expressions: + val = self.visit(expr, scope) + self.register_instruction(AssignNode(result, val)) + return result + @visitor.when(cool.AssignNode) def visit(self, node: cool.AssignNode, scope): expr = self.visit(node.expression, scope) attr_info = scope.find_variable(node.id.lex) if not attr_info: selfx = scope.find_variable('self').name - self.register_instruction(SetAttribNode(selfx, node.id.lex, expr)) + self.register_instruction(SetAttribNode( + selfx, node.id.lex, expr, self.current_type.name)) else: attr_info = attr_info.name self.register_instruction(AssignNode(attr_info, expr)) @@ -132,30 +141,31 @@ def visit(self, node: cool.NewNode, scope): def visit(self, node: cool.IfThenElseNode, scope): cond = self.visit(node.condition, scope) child_scope = Scope(parent=scope) - true_label = LabelNode('TRUE') - end_label = LabelNode('END') + true_label = LabelNode(f'TRUE_{self.label_counter}') + end_label = LabelNode(f'END_{self.label_counter}') result = self.define_internal_local() self.register_instruction(IfGotoNode( - cond, self.to_label_name(true_label.label))) - + cond, true_label.label)) + self.label_counter += 1 false_expr = self.visit(node.else_body, child_scope) self.register_instruction(AssignNode(result, false_expr)) self.register_instruction( - GotoNode(self.to_label_name(end_label.label))) + GotoNode(end_label.label)) self.register_instruction(true_label) true_expr = self.visit(node.if_body, child_scope) self.register_instruction(AssignNode(result, true_expr)) self.register_instruction(end_label) + self.label_counter = 0 return result @visitor.when(cool.WhileLoopNode) def visit(self, node: cool.WhileLoopNode, scope): while_scope = Scope(parent=scope) - start_label = LabelNode('START') - continue_label = LabelNode('CONTINUE') - end_label = LabelNode('END') + start_label = LabelNode(f'START_{self.label_counter}') + continue_label = LabelNode(f'CONTINUE_{self.label_counter}') + end_label = LabelNode(f'END_{self.label_counter}') self.register_instruction(start_label) @@ -164,9 +174,11 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) self.visit(node.body, while_scope) + self.label_counter += 1 self.register_instruction(GotoNode(start_label.label)) self.register_instruction(end_label) + self.label_counter = 0 return 0 @visitor.when(cool.CaseOfNode) @@ -199,14 +211,6 @@ def visit(self, node: cool.LetInNode, scope: Scope): self.register_instruction(AssignNode(result, expr)) return result - @visitor.when(cool.BlockNode) - def visit(self, node: cool.BlockNode, scope): - result = self.define_internal_local() - for expr in node.expressions: - val = self.visit(expr, scope) - self.register_instruction(AssignNode(result, val)) - return result - @visitor.when(cool.FunctionCallNode) def visit(self, node: cool.FunctionCallNode, scope): if not (node.type): diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 65d0d724..21a08871 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,6 +1,6 @@ from .cil_ast import * from ..cp import visitor -from .mips import MipsCode, TypeData +from .mips import MipsCode, TypeData, MipsLabel from .mips import Registers as reg from typing import Dict, List @@ -79,10 +79,6 @@ def store_memory(self, dst, arg: str): raise Exception( f"store_memory: The direction {arg} isn't an address") - def load_arithmetic(self, node: ArithmeticNode): - self.load_memory(reg.t0, node.left) - self.load_memory(reg.t1, node.right) - def store_registers(self): for reg in self.registers_to_save: self.mips.push(reg) @@ -195,46 +191,49 @@ def visit(self, node: SetAttribNode): @visitor.when(AssignNode) def visit(self, node: AssignNode): - self.mips.comment("AssignNode") self.load_memory(reg.t0, node.source) self.store_memory(reg.t0, node.dest) @visitor.when(ComplementNode) def visit(self, node: ComplementNode): - self.mips.comment("ComplementNode") self.load_memory(reg.t0, node.body) self.mips.nor(reg.t1, reg.t0, reg.t0) self.store_memory(reg.t1, node.dest) @visitor.when(PlusNode) def visit(self, node: PlusNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.add(reg.t2, reg.t0, reg.t1) self.store_memory(reg.t2, node.dest) @visitor.when(MinusNode) def visit(self, node: MinusNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.sub(reg.t2, reg.t0, reg.t1) self.store_memory(reg.t2, node.dest) @visitor.when(StarNode) def visit(self, node: StarNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.mult(reg.t2, reg.t0, reg.t1) self.mips.mflo(reg.t0) self.store_memory(reg.t0, node.dest) @visitor.when(DivNode) def visit(self, node: DivNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.div(reg.t2, reg.t0, reg.t1) self.mips.mflo(reg.t0) self.store_memory(reg.t0, node.dest) @visitor.when(EqualNode) def visit(self, node: EqualNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.slt(reg.t2, reg.t0, reg.t1) self.mips.slt(reg.t3, reg.t1, reg.t0) @@ -245,7 +244,8 @@ def visit(self, node: EqualNode): @visitor.when(LessEqNode) def visit(self, node: LessEqNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.slt(reg.t2, reg.t1, reg.t0) self.mips.li(reg.t3, 1) self.mips.sub(reg.t0, reg.t3, reg.t2) @@ -253,7 +253,8 @@ def visit(self, node: LessEqNode): @visitor.when(LessNode) def visit(self, node: LessNode): - self.load_arithmetic(node) + self.load_memory(reg.t0, node.left) + self.load_memory(reg.t1, node.right) self.mips.slt(reg.t2, reg.t0, reg.t1) self.store_memory(reg.t2, node.dest) diff --git a/src/test.mips b/src/test.mips index c38d7f33..6a353b55 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,2275 +1,682 @@ -.data -data_0 -.asciiz "H" -data_1 -.asciiz "A" -data_2 -.asciiz "B" -data_3 -.asciiz "C" -data_4 -.asciiz "E" -.text -main: -jal entry - -li $v0, 10 -syscall -function_abort_at_Object: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_copy_at_Object: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -li $s3, 0 -move $t0, $s0 -move $t1, $s1 -move $t3, $s3 -mip_label_0: -lb $t2, 0($t0) -sb $t2, 0($t1) -addi $t0, $t0, 2 -addi $t1, $t1, 2 -addi $t3, $t3, -1 -beqz $t3, mip_label_0 -j mip_label_0 -mip_label_0: -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_type_name_at_Object: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -# TypeOfNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, $s0 -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -# TypeNameNode -lw $t8, -8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 8($t0) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 -srl $t9, $t1, 16 -sw $t9, 0($t8) -sw $t1, 4($t8) -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_length_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -# LengthNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -move $t0, $s1 -li $t1, 0 -mip_label_0: -lb $t3, 0($t0) -beqz $t3, mip_label_0 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mip_label_0 -mip_label_0: -move $s0, $t1 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_concat_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -move $t0, $s0 -li $t1, 0 -mip_label_0: -lb $t3, 0($t0) -beqz $t3, mip_label_0 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mip_label_0 -mip_label_0: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mip_label_0: -lb $t3, 0($t0) -beqz $t3, mip_label_0 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mip_label_0 -mip_label_0: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mip_label_0: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mip_label_0 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mip_label_0 -mip_label_0: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mip_label_0: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mip_label_0 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mip_label_0 -mip_label_0: -move $v0, $t1 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_substr_at_String: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, 24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -add $s0, $s0, $s3 -move $a0, $s1 -li $v0, 9 -syscall -move $t0, $s0 -move $t1, $v0 -move $t3, $s1 -mip_label_0: -lb $t2, 0($t0) -sb $t2, 0($t1) -addi $t0, $t0, 1 -addi $t1, $t1, 1 -addi $t3, $t3, -1 -beqz $t3, mip_label_0 -j mip_label_0 -mip_label_0: -move $t2, $zero -sb $t2, 0($t1) -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_out_string_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_in_string_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_out_int_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 -li $v0, 4 -syscall - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_in_int_at_IO: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -li $a0, 1024 -li $v0, 9 -syscall -move $a0, $v0 -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -li $a1, 1024 -li $v0, 8 -syscall -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -entry: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -li $a0, 8 -li $v0, 9 -syscall -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -li $t0, 3 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -# ArgNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -# StaticCallNode -jal function_main_at_Main -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_main_at_Main: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_m_at_A: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_A: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -# ReturnNode -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_m_at_B: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_C: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra -function_f_at_E: -# Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) -# Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -# ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 - -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 -jr $ra \ No newline at end of file +.TYPES +type Object { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type String { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method length: function_length_at_String + method concat: function_concat_at_String + method substr: function_substr_at_String +} +type IO { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO +} +type A2I { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method c2i: function_c2i_at_A2I + method i2c: function_i2c_at_A2I + method a2i: function_a2i_at_A2I + method a2i_aux: function_a2i_aux_at_A2I + method i2a: function_i2a_at_A2I + method i2a_aux: function_i2a_aux_at_A2I +} +type Main { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method main: function_main_at_Main +} + +.DATA +data_0 = "0" +data_1 = "1" +data_2 = "2" +data_3 = "3" +data_4 = "4" +data_5 = "5" +data_6 = "6" +data_7 = "7" +data_8 = "8" +data_9 = "9" +data_10 = "" +data_11 = "9" +data_12 = "8" +data_13 = "7" +data_14 = "6" +data_15 = "5" +data_16 = "4" +data_17 = "3" +data_18 = "2" +data_19 = "1" +data_20 = "0" +data_21 = "-" +data_22 = "+" +data_23 = "-" +data_24 = "0" +data_25 = "" +data_26 = "678987" +data_27 = " == " +data_28 = "n" + +.CODE +function function_abort_at_Object { + PARAM self + + + + ERROR 0 +} +function function_copy_at_Object { + PARAM self + + LOCAL local_copy_at_Object_internal_0 + + local_copy_at_Object_internal_0 = COPY self + RETURN local_copy_at_Object_internal_0 +} +function function_type_name_at_Object { + PARAM self + + LOCAL local_type_name_at_Object_internal_0 + LOCAL local_type_name_at_Object_internal_1 + + local_type_name_at_Object_internal_1 = TYPEOF self + local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 + RETURN local_type_name_at_Object_internal_0 +} +function function_length_at_String { + PARAM self + + LOCAL local_length_at_String_internal_0 + + local_length_at_String_internal_0 = LENGTH self + RETURN local_length_at_String_internal_0 +} +function function_concat_at_String { + PARAM self + PARAM string + + LOCAL local_concat_at_String_internal_0 + + local_concat_at_String_internal_0 = CONCAT self string + RETURN local_concat_at_String_internal_0 +} +function function_substr_at_String { + PARAM self + PARAM start + PARAM length + + LOCAL local_substr_at_String_internal_0 + + local_substr_at_String_internal_0 = SUBSTRING self start length + RETURN local_substr_at_String_internal_0 +} +function function_out_string_at_IO { + + + LOCAL local_out_string_at_IO_internal_0 + + PRINTSTR local_out_string_at_IO_internal_0 +} +function function_in_string_at_IO { + + + LOCAL local_in_string_at_IO_internal_0 + + local_in_string_at_IO_internal_0 = READSTR + RETURN local_in_string_at_IO_internal_0 +} +function function_out_int_at_IO { + PARAM int_val + + + + PRINTINT int_val +} +function function_in_int_at_IO { + + + LOCAL local_in_int_at_IO_internal_0 + + local_in_int_at_IO_internal_0 = READINT + RETURN local_in_int_at_IO_internal_0 +} +function entry { + + + LOCAL local__internal_0 + LOCAL local__internal_1 + + local__internal_0 = ALLOCATE Main + ARG local__internal_0 + local__internal_1 = CALL function_main_at_Main +} +function function_c2i_at_A2I { + PARAM self + PARAM char + + LOCAL local_c2i_at_A2I_internal_0 + LOCAL local_c2i_at_A2I_internal_1 + LOCAL local_c2i_at_A2I_internal_2 + LOCAL local_c2i_at_A2I_internal_3 + LOCAL local_c2i_at_A2I_internal_4 + LOCAL local_c2i_at_A2I_internal_5 + LOCAL local_c2i_at_A2I_internal_6 + LOCAL local_c2i_at_A2I_internal_7 + LOCAL local_c2i_at_A2I_internal_8 + LOCAL local_c2i_at_A2I_internal_9 + LOCAL local_c2i_at_A2I_internal_10 + LOCAL local_c2i_at_A2I_internal_11 + LOCAL local_c2i_at_A2I_internal_12 + LOCAL local_c2i_at_A2I_internal_13 + LOCAL local_c2i_at_A2I_internal_14 + LOCAL local_c2i_at_A2I_internal_15 + LOCAL local_c2i_at_A2I_internal_16 + LOCAL local_c2i_at_A2I_internal_17 + LOCAL local_c2i_at_A2I_internal_18 + LOCAL local_c2i_at_A2I_internal_19 + LOCAL local_c2i_at_A2I_internal_20 + LOCAL local_c2i_at_A2I_internal_21 + LOCAL local_c2i_at_A2I_internal_22 + LOCAL local_c2i_at_A2I_internal_23 + LOCAL local_c2i_at_A2I_internal_24 + LOCAL local_c2i_at_A2I_internal_25 + LOCAL local_c2i_at_A2I_internal_26 + LOCAL local_c2i_at_A2I_internal_27 + LOCAL local_c2i_at_A2I_internal_28 + LOCAL local_c2i_at_A2I_internal_29 + LOCAL local_c2i_at_A2I_internal_30 + LOCAL local_c2i_at_A2I_internal_31 + + local_c2i_at_A2I_internal_0 = LOAD data_0 + local_c2i_at_A2I_internal_1 = STREQ char local_c2i_at_A2I_internal_0 + IF local_c2i_at_A2I_internal_1 GOTO TRUE_0 + local_c2i_at_A2I_internal_3 = LOAD data_1 + local_c2i_at_A2I_internal_4 = STREQ char local_c2i_at_A2I_internal_3 + IF local_c2i_at_A2I_internal_4 GOTO TRUE_1 + local_c2i_at_A2I_internal_6 = LOAD data_2 + local_c2i_at_A2I_internal_7 = STREQ char local_c2i_at_A2I_internal_6 + IF local_c2i_at_A2I_internal_7 GOTO TRUE_2 + local_c2i_at_A2I_internal_9 = LOAD data_3 + local_c2i_at_A2I_internal_10 = STREQ char local_c2i_at_A2I_internal_9 + IF local_c2i_at_A2I_internal_10 GOTO TRUE_3 + local_c2i_at_A2I_internal_12 = LOAD data_4 + local_c2i_at_A2I_internal_13 = STREQ char local_c2i_at_A2I_internal_12 + IF local_c2i_at_A2I_internal_13 GOTO TRUE_4 + local_c2i_at_A2I_internal_15 = LOAD data_5 + local_c2i_at_A2I_internal_16 = STREQ char local_c2i_at_A2I_internal_15 + IF local_c2i_at_A2I_internal_16 GOTO TRUE_5 + local_c2i_at_A2I_internal_18 = LOAD data_6 + local_c2i_at_A2I_internal_19 = STREQ char local_c2i_at_A2I_internal_18 + IF local_c2i_at_A2I_internal_19 GOTO TRUE_6 + local_c2i_at_A2I_internal_21 = LOAD data_7 + local_c2i_at_A2I_internal_22 = STREQ char local_c2i_at_A2I_internal_21 + IF local_c2i_at_A2I_internal_22 GOTO TRUE_7 + local_c2i_at_A2I_internal_24 = LOAD data_8 + local_c2i_at_A2I_internal_25 = STREQ char local_c2i_at_A2I_internal_24 + IF local_c2i_at_A2I_internal_25 GOTO TRUE_8 + local_c2i_at_A2I_internal_27 = LOAD data_9 + local_c2i_at_A2I_internal_28 = STREQ char local_c2i_at_A2I_internal_27 + IF local_c2i_at_A2I_internal_28 GOTO TRUE_9 + ARG self + local_c2i_at_A2I_internal_31 = VCALL A2I abort + local_c2i_at_A2I_internal_30 = 0 + local_c2i_at_A2I_internal_29 = local_c2i_at_A2I_internal_30 + GOTO END_9 + LABEL TRUE_9 + local_c2i_at_A2I_internal_29 = 9 + LABEL END_9 + local_c2i_at_A2I_internal_26 = local_c2i_at_A2I_internal_29 + GOTO END_8 + LABEL TRUE_8 + local_c2i_at_A2I_internal_26 = 8 + LABEL END_8 + local_c2i_at_A2I_internal_23 = local_c2i_at_A2I_internal_26 + GOTO END_7 + LABEL TRUE_7 + local_c2i_at_A2I_internal_23 = 7 + LABEL END_7 + local_c2i_at_A2I_internal_20 = local_c2i_at_A2I_internal_23 + GOTO END_6 + LABEL TRUE_6 + local_c2i_at_A2I_internal_20 = 6 + LABEL END_6 + local_c2i_at_A2I_internal_17 = local_c2i_at_A2I_internal_20 + GOTO END_5 + LABEL TRUE_5 + local_c2i_at_A2I_internal_17 = 5 + LABEL END_5 + local_c2i_at_A2I_internal_14 = local_c2i_at_A2I_internal_17 + GOTO END_4 + LABEL TRUE_4 + local_c2i_at_A2I_internal_14 = 4 + LABEL END_4 + local_c2i_at_A2I_internal_11 = local_c2i_at_A2I_internal_14 + GOTO END_3 + LABEL TRUE_3 + local_c2i_at_A2I_internal_11 = 3 + LABEL END_3 + local_c2i_at_A2I_internal_8 = local_c2i_at_A2I_internal_11 + GOTO END_2 + LABEL TRUE_2 + local_c2i_at_A2I_internal_8 = 2 + LABEL END_2 + local_c2i_at_A2I_internal_5 = local_c2i_at_A2I_internal_8 + GOTO END_1 + LABEL TRUE_1 + local_c2i_at_A2I_internal_5 = 1 + LABEL END_1 + local_c2i_at_A2I_internal_2 = local_c2i_at_A2I_internal_5 + GOTO END_0 + LABEL TRUE_0 + local_c2i_at_A2I_internal_2 = 0 + LABEL END_0 + RETURN local_c2i_at_A2I_internal_2 +} +function function_i2c_at_A2I { + PARAM self + PARAM i + + LOCAL local_i2c_at_A2I_internal_0 + LOCAL local_i2c_at_A2I_internal_1 + LOCAL local_i2c_at_A2I_internal_2 + LOCAL local_i2c_at_A2I_internal_3 + LOCAL local_i2c_at_A2I_internal_4 + LOCAL local_i2c_at_A2I_internal_5 + LOCAL local_i2c_at_A2I_internal_6 + LOCAL local_i2c_at_A2I_internal_7 + LOCAL local_i2c_at_A2I_internal_8 + LOCAL local_i2c_at_A2I_internal_9 + LOCAL local_i2c_at_A2I_internal_10 + LOCAL local_i2c_at_A2I_internal_11 + LOCAL local_i2c_at_A2I_internal_12 + LOCAL local_i2c_at_A2I_internal_13 + LOCAL local_i2c_at_A2I_internal_14 + LOCAL local_i2c_at_A2I_internal_15 + LOCAL local_i2c_at_A2I_internal_16 + LOCAL local_i2c_at_A2I_internal_17 + LOCAL local_i2c_at_A2I_internal_18 + LOCAL local_i2c_at_A2I_internal_19 + LOCAL local_i2c_at_A2I_internal_20 + LOCAL local_i2c_at_A2I_internal_21 + LOCAL local_i2c_at_A2I_internal_22 + LOCAL local_i2c_at_A2I_internal_23 + LOCAL local_i2c_at_A2I_internal_24 + LOCAL local_i2c_at_A2I_internal_25 + LOCAL local_i2c_at_A2I_internal_26 + LOCAL local_i2c_at_A2I_internal_27 + LOCAL local_i2c_at_A2I_internal_28 + LOCAL local_i2c_at_A2I_internal_29 + LOCAL local_i2c_at_A2I_internal_30 + LOCAL local_i2c_at_A2I_internal_31 + LOCAL local_i2c_at_A2I_internal_32 + + local_i2c_at_A2I_internal_0 = i == 0 + IF local_i2c_at_A2I_internal_0 GOTO TRUE_0 + local_i2c_at_A2I_internal_2 = i == 1 + IF local_i2c_at_A2I_internal_2 GOTO TRUE_1 + local_i2c_at_A2I_internal_4 = i == 2 + IF local_i2c_at_A2I_internal_4 GOTO TRUE_2 + local_i2c_at_A2I_internal_6 = i == 3 + IF local_i2c_at_A2I_internal_6 GOTO TRUE_3 + local_i2c_at_A2I_internal_8 = i == 4 + IF local_i2c_at_A2I_internal_8 GOTO TRUE_4 + local_i2c_at_A2I_internal_10 = i == 5 + IF local_i2c_at_A2I_internal_10 GOTO TRUE_5 + local_i2c_at_A2I_internal_12 = i == 6 + IF local_i2c_at_A2I_internal_12 GOTO TRUE_6 + local_i2c_at_A2I_internal_14 = i == 7 + IF local_i2c_at_A2I_internal_14 GOTO TRUE_7 + local_i2c_at_A2I_internal_16 = i == 8 + IF local_i2c_at_A2I_internal_16 GOTO TRUE_8 + local_i2c_at_A2I_internal_18 = i == 9 + IF local_i2c_at_A2I_internal_18 GOTO TRUE_9 + ARG self + local_i2c_at_A2I_internal_21 = VCALL A2I abort + local_i2c_at_A2I_internal_22 = LOAD data_10 + local_i2c_at_A2I_internal_20 = local_i2c_at_A2I_internal_22 + local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_20 + GOTO END_9 + LABEL TRUE_9 + local_i2c_at_A2I_internal_23 = LOAD data_11 + local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_23 + LABEL END_9 + local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_19 + GOTO END_8 + LABEL TRUE_8 + local_i2c_at_A2I_internal_24 = LOAD data_12 + local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_24 + LABEL END_8 + local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_17 + GOTO END_7 + LABEL TRUE_7 + local_i2c_at_A2I_internal_25 = LOAD data_13 + local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_25 + LABEL END_7 + local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_15 + GOTO END_6 + LABEL TRUE_6 + local_i2c_at_A2I_internal_26 = LOAD data_14 + local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_26 + LABEL END_6 + local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_13 + GOTO END_5 + LABEL TRUE_5 + local_i2c_at_A2I_internal_27 = LOAD data_15 + local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_27 + LABEL END_5 + local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_11 + GOTO END_4 + LABEL TRUE_4 + local_i2c_at_A2I_internal_28 = LOAD data_16 + local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_28 + LABEL END_4 + local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_9 + GOTO END_3 + LABEL TRUE_3 + local_i2c_at_A2I_internal_29 = LOAD data_17 + local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_29 + LABEL END_3 + local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_7 + GOTO END_2 + LABEL TRUE_2 + local_i2c_at_A2I_internal_30 = LOAD data_18 + local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_30 + LABEL END_2 + local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_5 + GOTO END_1 + LABEL TRUE_1 + local_i2c_at_A2I_internal_31 = LOAD data_19 + local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_31 + LABEL END_1 + local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_3 + GOTO END_0 + LABEL TRUE_0 + local_i2c_at_A2I_internal_32 = LOAD data_20 + local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_32 + LABEL END_0 + RETURN local_i2c_at_A2I_internal_1 +} +function function_a2i_at_A2I { + PARAM self + PARAM s + + LOCAL local_a2i_at_A2I_internal_0 + LOCAL local_a2i_at_A2I_internal_1 + LOCAL local_a2i_at_A2I_internal_2 + LOCAL local_a2i_at_A2I_internal_3 + LOCAL local_a2i_at_A2I_internal_4 + LOCAL local_a2i_at_A2I_internal_5 + LOCAL local_a2i_at_A2I_internal_6 + LOCAL local_a2i_at_A2I_internal_7 + LOCAL local_a2i_at_A2I_internal_8 + LOCAL local_a2i_at_A2I_internal_9 + LOCAL local_a2i_at_A2I_internal_10 + LOCAL local_a2i_at_A2I_internal_11 + LOCAL local_a2i_at_A2I_internal_12 + LOCAL local_a2i_at_A2I_internal_13 + LOCAL local_a2i_at_A2I_internal_14 + LOCAL local_a2i_at_A2I_internal_15 + LOCAL local_a2i_at_A2I_internal_16 + LOCAL local_a2i_at_A2I_internal_17 + LOCAL local_a2i_at_A2I_internal_18 + LOCAL local_a2i_at_A2I_internal_19 + LOCAL local_a2i_at_A2I_internal_20 + + ARG s + local_a2i_at_A2I_internal_0 = CALL function_length_at_String + local_a2i_at_A2I_internal_1 = local_a2i_at_A2I_internal_0 == 0 + IF local_a2i_at_A2I_internal_1 GOTO TRUE_0 + ARG 1 + ARG 0 + ARG s + local_a2i_at_A2I_internal_3 = CALL function_substr_at_String + local_a2i_at_A2I_internal_4 = LOAD data_21 + local_a2i_at_A2I_internal_5 = STREQ local_a2i_at_A2I_internal_3 local_a2i_at_A2I_internal_4 + IF local_a2i_at_A2I_internal_5 GOTO TRUE_1 + ARG 1 + ARG 0 + ARG s + local_a2i_at_A2I_internal_7 = CALL function_substr_at_String + local_a2i_at_A2I_internal_8 = LOAD data_22 + local_a2i_at_A2I_internal_9 = STREQ local_a2i_at_A2I_internal_7 local_a2i_at_A2I_internal_8 + IF local_a2i_at_A2I_internal_9 GOTO TRUE_2 + ARG s + ARG self + local_a2i_at_A2I_internal_11 = VCALL A2I a2i_aux + local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_11 + GOTO END_2 + LABEL TRUE_2 + ARG s + local_a2i_at_A2I_internal_15 = CALL function_length_at_String + local_a2i_at_A2I_internal_14 = local_a2i_at_A2I_internal_15 - 1 + ARG local_a2i_at_A2I_internal_14 + ARG 1 + ARG s + local_a2i_at_A2I_internal_13 = CALL function_substr_at_String + ARG local_a2i_at_A2I_internal_13 + ARG self + local_a2i_at_A2I_internal_12 = VCALL A2I a2i_aux + local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_12 + LABEL END_2 + local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_10 + GOTO END_1 + LABEL TRUE_1 + ARG s + local_a2i_at_A2I_internal_20 = CALL function_length_at_String + local_a2i_at_A2I_internal_19 = local_a2i_at_A2I_internal_20 - 1 + ARG local_a2i_at_A2I_internal_19 + ARG 1 + ARG s + local_a2i_at_A2I_internal_18 = CALL function_substr_at_String + ARG local_a2i_at_A2I_internal_18 + ARG self + local_a2i_at_A2I_internal_17 = VCALL A2I a2i_aux + local_a2i_at_A2I_internal_16 = COMPLEMENT local_a2i_at_A2I_internal_17 + local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_16 + LABEL END_1 + local_a2i_at_A2I_internal_2 = local_a2i_at_A2I_internal_6 + GOTO END_0 + LABEL TRUE_0 + local_a2i_at_A2I_internal_2 = 0 + LABEL END_0 + RETURN local_a2i_at_A2I_internal_2 +} +function function_a2i_aux_at_A2I { + PARAM self + PARAM s + + LOCAL local_a2i_aux_at_A2I_internal_0 + LOCAL local_a2i_aux_at_A2I_internal_1 + LOCAL local_a2i_aux_at_A2I_internal_2 + LOCAL local_a2i_aux_at_A2I_internal_3 + LOCAL local_a2i_aux_at_A2I_internal_4 + LOCAL local_a2i_aux_at_A2I_internal_5 + LOCAL local_a2i_aux_at_A2I_internal_6 + LOCAL local_a2i_aux_at_A2I_internal_7 + LOCAL local_a2i_aux_at_A2I_internal_8 + LOCAL local_a2i_aux_at_A2I_internal_9 + LOCAL local_a2i_aux_at_A2I_internal_10 + LOCAL local_a2i_aux_at_A2I_internal_11 + + ARG s + local_a2i_aux_at_A2I_internal_2 = CALL function_length_at_String + LABEL START_0 + local_a2i_aux_at_A2I_internal_5 = i < j + IF local_a2i_aux_at_A2I_internal_5 GOTO CONTINUE_0 + GOTO END_0 + LABEL CONTINUE_0 + local_a2i_aux_at_A2I_internal_8 = int * 10 + ARG 1 + ARG i + ARG s + local_a2i_aux_at_A2I_internal_10 = CALL function_substr_at_String + ARG local_a2i_aux_at_A2I_internal_10 + ARG self + local_a2i_aux_at_A2I_internal_9 = VCALL A2I c2i + local_a2i_aux_at_A2I_internal_7 = local_a2i_aux_at_A2I_internal_8 + local_a2i_aux_at_A2I_internal_9 + int = local_a2i_aux_at_A2I_internal_7 + local_a2i_aux_at_A2I_internal_11 = i + 1 + i = local_a2i_aux_at_A2I_internal_11 + local_a2i_aux_at_A2I_internal_6 = 0 + GOTO START_0 + LABEL END_0 + local_a2i_aux_at_A2I_internal_4 = 0 + local_a2i_aux_at_A2I_internal_3 = local_a2i_aux_at_A2I_internal_4 + local_a2i_aux_at_A2I_internal_1 = int + local_a2i_aux_at_A2I_internal_0 = local_a2i_aux_at_A2I_internal_1 + RETURN local_a2i_aux_at_A2I_internal_0 +} +function function_i2a_at_A2I { + PARAM self + PARAM i + + LOCAL local_i2a_at_A2I_internal_0 + LOCAL local_i2a_at_A2I_internal_1 + LOCAL local_i2a_at_A2I_internal_2 + LOCAL local_i2a_at_A2I_internal_3 + LOCAL local_i2a_at_A2I_internal_4 + LOCAL local_i2a_at_A2I_internal_5 + LOCAL local_i2a_at_A2I_internal_6 + LOCAL local_i2a_at_A2I_internal_7 + LOCAL local_i2a_at_A2I_internal_8 + LOCAL local_i2a_at_A2I_internal_9 + LOCAL local_i2a_at_A2I_internal_10 + + local_i2a_at_A2I_internal_0 = i == 0 + IF local_i2a_at_A2I_internal_0 GOTO TRUE_0 + local_i2a_at_A2I_internal_2 = 0 < i + IF local_i2a_at_A2I_internal_2 GOTO TRUE_1 + local_i2a_at_A2I_internal_7 = COMPLEMENT 1 + local_i2a_at_A2I_internal_6 = i * local_i2a_at_A2I_internal_7 + ARG local_i2a_at_A2I_internal_6 + ARG self + local_i2a_at_A2I_internal_5 = VCALL A2I i2a_aux + ARG local_i2a_at_A2I_internal_5 + local_i2a_at_A2I_internal_8 = LOAD data_23 + ARG local_i2a_at_A2I_internal_8 + local_i2a_at_A2I_internal_4 = CALL function_concat_at_String + local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_4 + GOTO END_1 + LABEL TRUE_1 + ARG i + ARG self + local_i2a_at_A2I_internal_9 = VCALL A2I i2a_aux + local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_9 + LABEL END_1 + local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_3 + GOTO END_0 + LABEL TRUE_0 + local_i2a_at_A2I_internal_10 = LOAD data_24 + local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_10 + LABEL END_0 + RETURN local_i2a_at_A2I_internal_1 +} +function function_i2a_aux_at_A2I { + PARAM self + PARAM i + + LOCAL local_i2a_aux_at_A2I_internal_0 + LOCAL local_i2a_aux_at_A2I_internal_1 + LOCAL local_i2a_aux_at_A2I_internal_2 + LOCAL local_i2a_aux_at_A2I_internal_3 + LOCAL local_i2a_aux_at_A2I_internal_4 + LOCAL local_i2a_aux_at_A2I_internal_5 + LOCAL local_i2a_aux_at_A2I_internal_6 + LOCAL local_i2a_aux_at_A2I_internal_7 + LOCAL local_i2a_aux_at_A2I_internal_8 + LOCAL local_i2a_aux_at_A2I_internal_9 + + local_i2a_aux_at_A2I_internal_0 = i == 0 + IF local_i2a_aux_at_A2I_internal_0 GOTO TRUE_0 + local_i2a_aux_at_A2I_internal_2 = i / 10 + local_i2a_aux_at_A2I_internal_7 = next * 10 + local_i2a_aux_at_A2I_internal_6 = i - local_i2a_aux_at_A2I_internal_7 + ARG local_i2a_aux_at_A2I_internal_6 + ARG self + local_i2a_aux_at_A2I_internal_5 = VCALL A2I i2c + ARG local_i2a_aux_at_A2I_internal_5 + ARG next + ARG self + local_i2a_aux_at_A2I_internal_8 = VCALL A2I i2a_aux + ARG local_i2a_aux_at_A2I_internal_8 + local_i2a_aux_at_A2I_internal_4 = CALL function_concat_at_String + local_i2a_aux_at_A2I_internal_3 = local_i2a_aux_at_A2I_internal_4 + local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_3 + GOTO END_0 + LABEL TRUE_0 + local_i2a_aux_at_A2I_internal_9 = LOAD data_25 + local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_9 + LABEL END_0 + RETURN local_i2a_aux_at_A2I_internal_1 +} +function function_main_at_Main { + PARAM self + + LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_internal_1 + LOCAL local_main_at_Main_internal_2 + LOCAL local_main_at_Main_internal_3 + LOCAL local_main_at_Main_internal_4 + LOCAL local_main_at_Main_internal_5 + LOCAL local_main_at_Main_internal_6 + LOCAL local_main_at_Main_internal_7 + LOCAL local_main_at_Main_internal_8 + LOCAL local_main_at_Main_internal_9 + LOCAL local_main_at_Main_internal_10 + LOCAL local_main_at_Main_internal_11 + LOCAL local_main_at_Main_internal_12 + + local_main_at_Main_internal_1 = LOAD data_26 + ARG local_main_at_Main_internal_1 + local_main_at_Main_internal_2 = ALLOCATE A2I + ARG local_main_at_Main_internal_2 + local_main_at_Main_internal_0 = CALL function_a2i_at_A2I + ARG 678987 + local_main_at_Main_internal_4 = ALLOCATE A2I + ARG local_main_at_Main_internal_4 + local_main_at_Main_internal_3 = CALL function_i2a_at_A2I + ARG a + ARG self + local_main_at_Main_internal_7 = VCALL Main out_int + local_main_at_Main_internal_9 = LOAD data_27 + ARG local_main_at_Main_internal_9 + ARG self + local_main_at_Main_internal_8 = VCALL Main out_string + ARG b + ARG self + local_main_at_Main_internal_10 = VCALL Main out_string + local_main_at_Main_internal_12 = LOAD data_28 + ARG local_main_at_Main_internal_12 + ARG self + local_main_at_Main_internal_11 = VCALL Main out_string + local_main_at_Main_internal_6 = local_main_at_Main_internal_11 + local_main_at_Main_internal_5 = local_main_at_Main_internal_6 + RETURN local_main_at_Main_internal_5 +} \ No newline at end of file From 29cc1d8788f7e28a6a1741ef1380273ecb49def9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Sat, 5 Dec 2020 14:59:11 -0500 Subject: [PATCH 078/191] fix read error --- src/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.py b/src/main.py index facdb309..a085b31b 100644 --- a/src/main.py +++ b/src/main.py @@ -8,10 +8,10 @@ # if len(args) != 3: # exit(1) -# input_file = open(args[1], "r") -# output_file = open(args[2], 'w') +input_file = open(args[1], "r") +output_file = open(args[2], 'w') -input_file = open('./src/test.cl', "r") +#input_file = open('./src/test.cl', "r") # output_file = open('./src/test.mips', 'w') t = input_file.read() From 1ebe1ff083ad45d337cd99f6ae7f68c31dbc1c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Sat, 5 Dec 2020 15:44:27 -0500 Subject: [PATCH 079/191] Fix double lexing error --- src/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.py b/src/main.py index a085b31b..f85961bb 100644 --- a/src/main.py +++ b/src/main.py @@ -27,7 +27,7 @@ print(e) exit(1) -lexer.reset() +lexer = CoolLexer() parser = CoolParser(lexer) ast, errors = parser.parse(t) From 74a6ef5fdcd787600a337349ed28466ae63ade93 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Sat, 5 Dec 2020 19:56:43 -0500 Subject: [PATCH 080/191] [trable-maker] program1.cl --- src/assignment1_error.txt | 1 - src/program1.cl | 1 + src/program1_error.txt | 1 + src/test.cl | 50 +++++++++++++-------------------------- 4 files changed, 19 insertions(+), 34 deletions(-) delete mode 100644 src/assignment1_error.txt create mode 100644 src/program1.cl create mode 100644 src/program1_error.txt mode change 100755 => 100644 src/test.cl diff --git a/src/assignment1_error.txt b/src/assignment1_error.txt deleted file mode 100644 index cef0d394..00000000 --- a/src/assignment1_error.txt +++ /dev/null @@ -1 +0,0 @@ -(29, 9) - SyntacticError: ERROR at or near "Test1" \ No newline at end of file diff --git a/src/program1.cl b/src/program1.cl new file mode 100644 index 00000000..33cbcd02 --- /dev/null +++ b/src/program1.cl @@ -0,0 +1 @@ +(* A Cool program can't be empty *) diff --git a/src/program1_error.txt b/src/program1_error.txt new file mode 100644 index 00000000..de00ac46 --- /dev/null +++ b/src/program1_error.txt @@ -0,0 +1 @@ +(0, 0) - SyntacticError: ERROR at or near EOF \ No newline at end of file diff --git a/src/test.cl b/src/test.cl old mode 100755 new mode 100644 index e179e479..e752253b --- a/src/test.cl +++ b/src/test.cl @@ -1,37 +1,21 @@ -(* An assignment has the form <- *) - -class Main { - main(): Object { - (new Alpha).print() - }; -}; - -class Test { - test1: Object; - - testing1(): Int { - 2 + 2 +class Main inherits IO { + main() : Object { + { + out_string("Enter number of numbers to multiply\n"); + out_int(prod(in_int())); + out_string("\n"); + } }; - test2: Int <- 1; - - test3: String <- "1"; - - testing2(a: Alpha, b: Int): Int { - 2 + 2 - }; - - testing3(): String { - "2 + 2" - }; - - testing4(): String { - Test1 <- "Hello World" -- Identifiers begin with a lower case letter - }; -}; - -class Alpha inherits IO { - print() : Object { - out_string("reached!!\n") + prod(i : Int) : Int { + let y : Int <- 1 in { + while (not (i = 0) ) loop { + out_string("Enter Number: "); + y <- y * in_int(Main : Int); -- the parser correctly catches the error here + i <- i - 1; + } + pool; + y; + } }; }; From d6b7cd865f933e962c996a684791aba7813d9a08 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Sat, 5 Dec 2020 19:57:50 -0500 Subject: [PATCH 081/191] [fix] parsing errors fix --- src/engine/parser/ast_parser.py | 9 +- src/engine/parser/cool_parser.py | 83 ++++++++++-- src/engine/parser/parsetab.py | 215 +++++++++++++++++++------------ src/main.py | 9 +- 4 files changed, 218 insertions(+), 98 deletions(-) diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py index 5e202dfd..2defa961 100644 --- a/src/engine/parser/ast_parser.py +++ b/src/engine/parser/ast_parser.py @@ -1,7 +1,9 @@ # AST Classes class Node: - pass + def __init__(self): + self.line = 0 + self.column = 0 class ErrorNode(Node): @@ -195,6 +197,11 @@ def __init__(self, obj, idx, args, typex=None): self.type = typex self.line = idx.line self.column = idx.column + + def __iter__(self): + yield from (self.id, self.type, self.expression) + + class MemberCallNode(ExpressionNode): diff --git a/src/engine/parser/cool_parser.py b/src/engine/parser/cool_parser.py index ff6d66d5..6d79feb2 100644 --- a/src/engine/parser/cool_parser.py +++ b/src/engine/parser/cool_parser.py @@ -179,6 +179,41 @@ def p_let_list(self, p): p[0] = [LetVariableDeclaration( p.slice[1], p.slice[3], p[5])] + p[7] + def p_let_list_error(self, p): + '''let_list : error COLON TYPE + | ID COLON error + | error COLON error + | error COLON TYPE ASSIGN expr + | ID COLON error ASSIGN expr + | ID COLON TYPE ASSIGN error + | ID COLON error ASSIGN error + | error COLON error ASSIGN expr + | error COLON TYPE ASSIGN error + | error COLON error ASSIGN error + | error COLON TYPE COMMA let_list + | ID COLON error COMMA let_list + | ID COLON TYPE COMMA error + | ID COLON error COMMA error + | error COLON error COMMA let_list + | error COLON TYPE COMMA error + | error COLON error COMMA error + | error COLON error ASSIGN error COMMA error + | ID COLON error ASSIGN error COMMA error + | error COLON TYPE ASSIGN error COMMA error + | ID COLON TYPE ASSIGN error COMMA error + | error COLON error ASSIGN expr COMMA error + | ID COLON error ASSIGN expr COMMA error + | error COLON TYPE ASSIGN expr COMMA error + | ID COLON TYPE ASSIGN expr COMMA error + | error COLON error ASSIGN error COMMA let_list + | ID COLON error ASSIGN error COMMA let_list + | error COLON TYPE ASSIGN error COMMA let_list + | ID COLON TYPE ASSIGN error COMMA let_list + | error COLON error ASSIGN expr COMMA let_list + | ID COLON error ASSIGN expr COMMA let_list + | error COLON TYPE ASSIGN expr COMMA let_list ''' + p[0] = [ErrorNode()] + def p_case_list(self, p): '''case_list : ID COLON TYPE ACTION expr SEMI | ID COLON TYPE ACTION expr SEMI case_list ''' @@ -187,7 +222,7 @@ def p_case_list(self, p): p.slice[1], p.slice[3], p[5])] else: p[0] = [CaseVariableDeclaration( - p.slice[1], p.slice[3], p[5])] + p[7] + p.slice[1], p.slice[3], p[5])] + p[7] def p_case_list_error(self, p): '''case_list : error COLON TYPE ACTION expr SEMI @@ -203,8 +238,15 @@ def p_case_list_error(self, p): | ID COLON TYPE error error SEMI case_list | error COLON error ACTION expr SEMI case_list | error COLON TYPE ACTION error SEMI case_list - | error COLON error ACTION error SEMI case_list''' - p[0] = ErrorNode() + | error COLON error ACTION error SEMI case_list + | error COLON TYPE ACTION expr SEMI error + | ID COLON TYPE ACTION expr SEMI error + | ID COLON error ACTION expr SEMI error + | ID COLON TYPE error error SEMI error + | error COLON error ACTION expr SEMI error + | error COLON TYPE ACTION error SEMI error + | error COLON error ACTION error SEMI error''' + p[0] = [ErrorNode()] def p_func_call(self, p): '''funccall : ID OPAR CPAR @@ -219,7 +261,7 @@ def p_func_call_error(self, p): | ID OPAR error CPAR | error OPAR arg_list CPAR | error OPAR error CPAR''' - p[0] = ErrorNode() + p[0] = (ErrorNode(), ErrorNode()) def p_arg_list(self, p): ''' arg_list : expr @@ -258,6 +300,18 @@ def p_comp(self, p): else: p[0] = EqualNode(p[1], p[3]) + def p_comp_error(self, p): + '''operat : error LESSEQUAL operat + | error LESSEQUAL error + | operat LESSEQUAL error + | error LESS operat + | error LESS error + | operat LESS error + | error EQUAL operat + | error EQUAL error + | operat EQUAL error''' + p[0] = ErrorNode() + def p_arith(self, p): '''operat : operat PLUS operat | operat MINUS operat @@ -273,13 +327,18 @@ def p_arith(self, p): p[0] = DivNode(p[1], p[3]) def p_operat_error(self, p): - '''operat : operat LESSEQUAL error - | operat LESS error - | operat EQUAL error - | operat PLUS error + '''operat : operat PLUS error + | error PLUS error + | error PLUS operat + | error MINUS operat + | error MINUS error | operat MINUS error | operat STAR error - | operat DIV error ''' + | error STAR error + | error STAR operat + | operat DIV error + | error DIV error + | error DIV operat ''' p[0] = ErrorNode() def p_base_operat(self, p): @@ -306,7 +365,7 @@ def p_sub_atom(self, p): def p_parent_expr(self, p): '''subatom : OPAR expr CPAR''' - p[0] = p[1] + p[0] = p[2] def p_parent_expr_error(self, p): '''subatom : error expr CPAR @@ -349,7 +408,7 @@ def p_complex_sub_atom(self, p): | WHILE expr LOOP expr POOL | LET let_list IN expr | CASE expr OF case_list ESAC ''' - #| LET let_list + # | LET let_list if p.slice[1].lex == 'if': p[0] = IfThenElseNode(p[2], p[4], p[6]) elif p.slice[1].lex == 'while': @@ -382,7 +441,7 @@ def p_atom_expr_block_error(self, p): p[0] = ErrorNode() def p_atom_id(self, p): - '''expr : ID''' + '''atom : ID''' p[0] = IdNode(p.slice[1]) def p_atom_integer(self, p): diff --git a/src/engine/parser/parsetab.py b/src/engine/parser/parsetab.py index 51f102fa..1e823fdc 100644 --- a/src/engine/parser/parsetab.py +++ b/src/engine/parser/parsetab.py @@ -6,9 +6,9 @@ _lr_method = 'LALR' -_lr_signature = 'programrightASSIGNrightNOTnonassocLESSLESSEQUALEQUALleftPLUSMINUSleftSTARDIVrightISVOIDrightINT_COMPLEMENTleftATleftDOTACTION ASSIGN AT BOOL CASE CCURL CLASS COLON COMMA CPAR DIV DOT ELSE EQUAL ESAC FI ID IF IN INHERITS INTEGER INT_COMPLEMENT ISVOID LESS LESSEQUAL LET LOOP MINUS NEW NOT OCURL OF OPAR PLUS POOL SEMI STAR STRING THEN TYPE WHILEepsilon :program : class_listclass_list : def_class class_list\n | def_classclass_list : error class_list def_class : CLASS TYPE OCURL feature_list CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI def_class : CLASS error OCURL feature_list CCURL SEMI\n | CLASS TYPE OCURL error CCURL SEMI\n | CLASS error OCURL error CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI\n | CLASS TYPE INHERITS error OCURL error CCURL SEMI\n | CLASS error INHERITS TYPE OCURL error CCURL SEMI\n | CLASS error INHERITS error OCURL feature_list CCURL SEMI\n | CLASS error INHERITS error OCURL error CCURL SEMI feature_list : feature feature_list\n | epsilonfeature_list : error feature_listfeature : ID COLON TYPE SEMI\n | ID COLON TYPE ASSIGN expr SEMI feature : error COLON TYPE\n | ID COLON error\n | error COLON error\n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON error ASSIGN errorfeature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI\n | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR CPAR COLON error OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID error CPAR COLON error OCURL error CCURL SEMI param_list : param\n | param COMMA param_listparam : ID COLON TYPEexpr_block : expr SEMI\n | expr SEMI expr_blocklet_list : ID COLON TYPE\n | ID COLON TYPE ASSIGN expr\n | ID COLON TYPE COMMA let_list\n | ID COLON TYPE ASSIGN expr COMMA let_listcase_list : ID COLON TYPE ACTION expr SEMI\n | ID COLON TYPE ACTION expr SEMI case_list case_list : error COLON TYPE ACTION expr SEMI\n | ID COLON error ACTION expr SEMI\n | ID COLON TYPE ACTION error SEMI\n | ID COLON TYPE error error SEMI\n | error COLON error ACTION expr SEMI\n | error COLON TYPE ACTION error SEMI\n | error COLON error ACTION error SEMI\n | error COLON TYPE ACTION expr SEMI case_list\n | ID COLON error ACTION expr SEMI case_list\n | ID COLON TYPE ACTION error SEMI case_list\n | ID COLON TYPE error error SEMI case_list\n | error COLON error ACTION expr SEMI case_list\n | error COLON TYPE ACTION error SEMI case_list\n | error COLON error ACTION error SEMI case_listfunccall : ID OPAR CPAR\n | ID OPAR arg_list CPARfunccall : error OPAR CPAR\n | ID OPAR error CPAR\n | error OPAR arg_list CPAR\n | error OPAR error CPAR arg_list : expr\n | expr COMMA arg_list arg_list : error\n | error COMMA arg_listexpr : ID ASSIGN expr\n | operat expr : ID ASSIGN error \n | error ASSIGN expr operat : operat LESSEQUAL operat\n | operat LESS operat\n | operat EQUAL operatoperat : operat PLUS operat\n | operat MINUS operat\n | operat STAR operat\n | operat DIV operat operat : operat LESSEQUAL error\n | operat LESS error\n | operat EQUAL error\n | operat PLUS error\n | operat MINUS error\n | operat STAR error\n | operat DIV error operat : baseopbaseop : subatom AT TYPE DOT funccall baseop : error AT TYPE DOT funccall\n | subatom AT error DOT funccall\n | subatom AT TYPE DOT error\n | error AT error DOT funccall\n | error AT TYPE DOT error\n | subatom AT error DOT error\n | error AT error DOT error baseop : subatomsubatom : OPAR expr CPARsubatom : error expr CPAR\n | OPAR expr errorsubatom : subatom DOT funccall subatom : subatom DOT error \n | error DOT funccall\n | error DOT error subatom : funccall subatom : INT_COMPLEMENT baseop\n | NOT baseop\n | ISVOID baseop subatom : IF expr THEN expr ELSE expr FI\n | WHILE expr LOOP expr POOL\n | LET let_list IN expr \n | CASE expr OF case_list ESAC subatom : atomatom : NEW TYPEatom : NEW erroratom : OCURL expr_block CCURL atom : OCURL error CCURL expr : IDatom : INTEGERatom : STRINGatom : BOOL' +_lr_signature = 'programrightASSIGNrightNOTnonassocLESSLESSEQUALEQUALleftPLUSMINUSleftSTARDIVrightISVOIDrightINT_COMPLEMENTleftATleftDOTACTION ASSIGN AT BOOL CASE CCURL CLASS COLON COMMA CPAR DIV DOT ELSE EQUAL ESAC FI ID IF IN INHERITS INTEGER INT_COMPLEMENT ISVOID LESS LESSEQUAL LET LOOP MINUS NEW NOT OCURL OF OPAR PLUS POOL SEMI STAR STRING THEN TYPE WHILEepsilon :program : class_listclass_list : def_class class_list\n | def_classclass_list : error class_list def_class : CLASS TYPE OCURL feature_list CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI def_class : CLASS error OCURL feature_list CCURL SEMI\n | CLASS TYPE OCURL error CCURL SEMI\n | CLASS error OCURL error CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI\n | CLASS TYPE INHERITS error OCURL error CCURL SEMI\n | CLASS error INHERITS TYPE OCURL error CCURL SEMI\n | CLASS error INHERITS error OCURL feature_list CCURL SEMI\n | CLASS error INHERITS error OCURL error CCURL SEMI feature_list : feature feature_list\n | epsilonfeature_list : error feature_listfeature : ID COLON TYPE SEMI\n | ID COLON TYPE ASSIGN expr SEMI feature : error COLON TYPE\n | ID COLON error\n | error COLON error\n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON error ASSIGN errorfeature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI\n | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR CPAR COLON error OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID error CPAR COLON error OCURL error CCURL SEMI param_list : param\n | param COMMA param_listparam : ID COLON TYPEexpr_block : expr SEMI\n | expr SEMI expr_blocklet_list : ID COLON TYPE\n | ID COLON TYPE ASSIGN expr\n | ID COLON TYPE COMMA let_list\n | ID COLON TYPE ASSIGN expr COMMA let_listlet_list : error COLON TYPE\n | ID COLON error\n | error COLON error \n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN error\n | error COLON TYPE COMMA let_list\n | ID COLON error COMMA let_list\n | ID COLON TYPE COMMA error\n | ID COLON error COMMA error\n | error COLON error COMMA let_list\n | error COLON TYPE COMMA error\n | error COLON error COMMA error\n | error COLON error ASSIGN error COMMA error\n | ID COLON error ASSIGN error COMMA error\n | error COLON TYPE ASSIGN error COMMA error\n | ID COLON TYPE ASSIGN error COMMA error\n | error COLON error ASSIGN expr COMMA error\n | ID COLON error ASSIGN expr COMMA error\n | error COLON TYPE ASSIGN expr COMMA error\n | ID COLON TYPE ASSIGN expr COMMA error\n | error COLON error ASSIGN error COMMA let_list\n | ID COLON error ASSIGN error COMMA let_list\n | error COLON TYPE ASSIGN error COMMA let_list\n | ID COLON TYPE ASSIGN error COMMA let_list\n | error COLON error ASSIGN expr COMMA let_list\n | ID COLON error ASSIGN expr COMMA let_list\n | error COLON TYPE ASSIGN expr COMMA let_list case_list : ID COLON TYPE ACTION expr SEMI\n | ID COLON TYPE ACTION expr SEMI case_list case_list : error COLON TYPE ACTION expr SEMI\n | ID COLON error ACTION expr SEMI\n | ID COLON TYPE ACTION error SEMI\n | ID COLON TYPE error error SEMI\n | error COLON error ACTION expr SEMI\n | error COLON TYPE ACTION error SEMI\n | error COLON error ACTION error SEMI\n | error COLON TYPE ACTION expr SEMI case_list\n | ID COLON error ACTION expr SEMI case_list\n | ID COLON TYPE ACTION error SEMI case_list\n | ID COLON TYPE error error SEMI case_list\n | error COLON error ACTION expr SEMI case_list\n | error COLON TYPE ACTION error SEMI case_list\n | error COLON error ACTION error SEMI case_list\n | error COLON TYPE ACTION expr SEMI error\n | ID COLON TYPE ACTION expr SEMI error\n | ID COLON error ACTION expr SEMI error\n | ID COLON TYPE error error SEMI error\n | error COLON error ACTION expr SEMI error\n | error COLON TYPE ACTION error SEMI error\n | error COLON error ACTION error SEMI errorfunccall : ID OPAR CPAR\n | ID OPAR arg_list CPARfunccall : error OPAR CPAR\n | ID OPAR error CPAR\n | error OPAR arg_list CPAR\n | error OPAR error CPAR arg_list : expr\n | expr COMMA arg_list arg_list : error\n | error COMMA arg_listexpr : ID ASSIGN expr\n | operat expr : ID ASSIGN error \n | error ASSIGN expr operat : operat LESSEQUAL operat\n | operat LESS operat\n | operat EQUAL operatoperat : error LESSEQUAL operat\n | error LESSEQUAL error\n | operat LESSEQUAL error\n | error LESS operat\n | error LESS error\n | operat LESS error\n | error EQUAL operat\n | error EQUAL error\n | operat EQUAL erroroperat : operat PLUS operat\n | operat MINUS operat\n | operat STAR operat\n | operat DIV operat operat : operat PLUS error\n | error PLUS error\n | error PLUS operat\n | error MINUS operat\n | error MINUS error\n | operat MINUS error\n | operat STAR error\n | error STAR error\n | error STAR operat\n | operat DIV error \n | error DIV error \n | error DIV operat operat : baseopbaseop : subatom AT TYPE DOT funccall baseop : error AT TYPE DOT funccall\n | subatom AT error DOT funccall\n | subatom AT TYPE DOT error\n | error AT error DOT funccall\n | error AT TYPE DOT error\n | subatom AT error DOT error\n | error AT error DOT error baseop : subatomsubatom : OPAR expr CPARsubatom : error expr CPAR\n | OPAR expr errorsubatom : subatom DOT funccall subatom : subatom DOT error \n | error DOT funccall\n | error DOT error subatom : funccall subatom : INT_COMPLEMENT baseop\n | NOT baseop\n | ISVOID baseop subatom : IF expr THEN expr ELSE expr FI\n | WHILE expr LOOP expr POOL\n | LET let_list IN expr \n | CASE expr OF case_list ESAC subatom : atomatom : NEW TYPEatom : NEW erroratom : OCURL expr_block CCURL atom : OCURL error CCURL atom : IDatom : INTEGERatom : STRINGatom : BOOL' -_lr_action_items = {'error':([0,3,4,5,10,11,12,13,15,16,18,21,26,29,30,32,34,35,36,39,40,41,42,43,44,51,57,59,60,61,64,65,71,72,73,74,76,84,85,86,87,88,89,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,108,113,114,115,118,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,149,150,156,157,159,165,166,167,168,171,172,175,176,179,180,181,182,184,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,211,212,213,215,216,217,218,219,220,221,222,225,227,228,230,231,233,234,235,236,237,238,239,240,241,242,243,244,245,248,255,257,259,266,274,275,276,277,278,281,282,283,284,285,286,287,289,290,291,299,300,301,302,306,307,308,309,315,319,320,321,322,323,324,325,326,327,328,329,330,331,333,334,335,336,337,340,343,345,347,348,349,350,351,352,353,354,],[4,4,4,9,15,20,21,23,26,26,33,26,26,43,45,51,55,57,58,61,63,-6,-9,-23,-21,-22,26,-10,-8,26,84,105,-19,113,114,116,120,128,-29,-134,-87,-104,-113,-121,128,147,147,147,128,128,128,-129,157,159,-135,-136,-137,128,-24,161,163,128,128,-25,170,173,-7,-11,-12,-15,-14,-13,128,128,177,179,181,186,189,192,194,196,198,200,202,204,206,208,210,-122,128,-123,-124,-130,-131,128,128,-20,224,225,230,231,-89,-115,-120,-119,128,-78,210,-86,128,-76,128,-90,128,-91,128,-92,128,-93,128,-94,128,-95,128,-96,128,-117,-118,-114,-116,128,128,128,252,-132,-133,128,254,255,257,259,128,266,128,128,128,272,128,274,276,181,-81,278,-80,278,-77,-79,282,283,-127,128,128,128,128,-112,-109,-110,-106,128,-105,-108,-111,-107,128,-126,128,-128,316,317,-44,-50,-48,-49,-32,-46,-47,-45,334,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,340,341,128,343,345,128,128,128,252,252,252,252,252,252,252,252,]),'CLASS':([0,3,4,41,42,59,60,122,123,124,125,126,127,],[5,5,5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'$end':([1,2,3,6,7,41,42,59,60,122,123,124,125,126,127,],[0,-2,-4,-3,-5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'TYPE':([5,11,13,29,32,68,70,74,76,100,107,108,118,121,131,143,214,290,291,],[8,19,24,44,50,109,111,117,119,156,162,164,169,174,178,205,249,315,318,]),'OCURL':([8,9,19,20,23,24,64,65,72,73,84,91,92,93,94,95,96,98,101,105,109,113,114,116,117,119,120,128,129,133,134,135,136,137,138,139,140,141,142,147,159,161,162,163,164,165,168,169,170,171,172,173,174,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[10,12,35,36,39,40,101,101,101,101,101,101,101,101,101,101,101,101,101,101,165,101,101,167,168,171,172,101,101,101,101,101,101,101,101,101,101,101,101,101,101,219,220,221,222,101,101,227,228,101,101,233,234,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'INHERITS':([8,9,],[11,13,]),'ID':([10,12,15,16,21,26,30,34,35,39,43,44,51,57,61,64,65,69,71,72,73,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,101,102,103,104,105,106,113,114,115,128,129,132,133,134,135,136,137,138,139,140,141,142,144,146,147,149,150,156,157,159,165,166,168,171,172,175,176,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,211,212,213,215,216,217,218,220,221,222,225,227,228,230,231,234,235,236,237,238,239,240,241,242,243,244,245,248,255,257,259,266,274,275,276,277,278,281,282,283,284,285,286,287,288,289,299,300,301,302,306,307,308,309,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,335,336,337,340,343,345,347,348,349,350,351,352,353,354,],[18,18,18,18,18,18,49,49,18,18,-23,-21,-22,18,18,86,86,49,-19,86,86,86,-29,-134,-87,-104,-113,-121,86,148,148,148,86,86,154,86,-129,86,-135,-136,-137,86,-24,86,86,-25,86,86,148,86,86,86,148,148,148,148,148,148,148,148,-122,86,-123,-124,-130,-131,86,86,-20,86,86,86,-89,-115,-120,-119,86,-78,-86,86,-76,86,-90,86,-91,86,-92,86,-93,86,-94,86,-95,86,-96,86,-117,-118,-114,-116,86,86,86,251,-132,-133,86,86,86,86,86,86,86,86,86,86,148,148,86,-81,86,-80,86,-77,-79,148,148,-127,86,86,86,86,-112,-109,-110,-106,86,-105,-108,-111,-107,86,-126,86,154,-128,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,154,86,86,86,86,86,86,86,251,251,251,251,251,251,251,251,]),'CCURL':([10,12,14,15,16,17,21,22,26,28,31,35,39,43,44,51,56,57,58,61,62,63,71,84,85,86,87,88,89,90,99,102,103,104,105,106,113,114,115,146,149,150,156,157,158,159,166,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,218,223,224,225,226,229,230,231,232,238,240,242,243,248,253,254,255,256,257,258,259,260,265,266,267,272,273,274,275,276,277,281,282,283,284,286,289,299,300,301,302,306,307,308,309,319,320,321,322,323,324,325,326,327,328,329,330,331,],[-1,-1,25,27,-1,-17,37,38,-1,-18,-16,-1,-1,-23,-21,-22,78,79,80,81,82,83,-19,-30,-29,-134,-87,-104,-113,-121,-129,-135,-136,-137,-28,-24,-26,-27,-25,-122,-123,-124,-130,-131,216,217,-20,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-54,261,262,263,264,268,269,270,271,-81,-80,-77,-79,-127,-55,292,293,294,295,296,297,298,303,304,305,310,311,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-125,]),'COLON':([15,18,21,26,47,49,52,54,57,61,66,67,75,77,154,251,252,],[29,32,29,29,68,70,74,76,29,29,107,108,118,121,214,290,291,]),'OPAR':([15,18,21,26,57,61,64,65,72,73,84,86,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,148,159,165,168,171,172,179,181,186,189,192,194,196,198,200,202,204,208,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,274,276,278,282,283,285,287,333,335,336,337,340,343,345,],[30,34,30,30,30,30,91,91,91,91,133,135,91,91,91,91,91,91,91,91,133,133,133,133,91,91,91,91,91,91,91,91,91,91,91,133,135,133,91,91,91,91,237,133,133,133,133,133,133,133,133,133,133,237,91,91,91,91,91,91,91,133,91,91,133,133,91,91,91,91,133,133,133,133,237,237,133,237,237,91,91,91,91,91,91,133,133,133,]),'SEMI':([25,27,37,38,50,78,79,80,81,82,83,86,87,88,89,90,99,102,103,104,112,146,149,150,156,157,160,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,261,262,263,264,268,269,270,271,274,275,276,277,281,282,283,284,286,289,292,293,294,295,296,297,298,303,304,305,310,311,331,339,340,341,342,343,344,345,346,],[41,42,59,60,71,122,123,124,125,126,127,-134,-87,-104,-113,-121,-129,-135,-136,-137,166,-122,-123,-124,-130,-131,218,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,299,300,301,302,306,307,308,309,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,319,320,321,322,323,324,325,326,327,328,329,330,-125,347,348,349,350,351,352,353,354,]),'CPAR':([30,33,34,45,46,48,53,55,86,87,88,89,90,99,102,103,104,110,111,130,133,135,145,146,149,150,156,157,175,176,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,237,238,240,242,243,248,274,275,276,277,278,279,280,281,282,283,284,286,289,331,],[47,52,54,66,67,-51,75,77,-134,-87,-104,-113,-121,-129,-135,-136,-137,-52,-53,176,182,187,209,-122,-123,-124,-130,-131,-89,-115,-120,-119,238,-78,240,209,-86,-88,-76,242,243,-82,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,182,-81,-80,-77,-79,-127,-112,-109,-110,-106,-84,-85,-83,-105,-108,-111,-107,-126,-128,-125,]),'ASSIGN':([43,44,50,51,84,86,105,113,114,128,159,181,186,189,225,230,231,249,255,257,259,266,278,340,343,345,],[64,65,72,73,129,134,129,129,129,129,129,129,129,129,129,129,129,287,129,129,129,129,129,129,129,129,]),'COMMA':([48,86,87,88,89,90,99,102,103,104,111,146,149,150,156,157,175,176,179,180,181,182,184,185,186,187,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,249,274,275,276,277,278,281,282,283,284,286,289,313,331,],[69,-134,-87,-104,-113,-121,-129,-135,-136,-137,-53,-122,-123,-124,-130,-131,-89,-115,-120,-119,239,-78,241,-86,-88,-76,239,241,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,288,-112,-109,-110,-106,239,-105,-108,-111,-107,-126,-128,332,-125,]),'INT_COMPLEMENT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'NOT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,]),'ISVOID':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,]),'IF':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'WHILE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,]),'LET':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'CASE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'NEW':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'INTEGER':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,]),'STRING':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'BOOL':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'AT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,146,147,149,150,156,157,159,175,176,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,225,230,231,238,240,242,243,248,255,257,259,266,274,275,276,277,278,281,282,283,284,286,289,331,340,343,345,],[131,-134,-87,-104,143,-121,-129,-135,-136,-137,131,131,131,131,-122,131,-123,-124,-130,-131,131,-89,-115,-120,-119,131,-78,-86,131,-76,131,-90,131,-91,131,-92,131,-93,131,-94,131,-95,131,-96,131,-117,-118,-114,-116,-132,-133,131,131,131,-81,-80,-77,-79,-127,131,131,131,131,-112,-109,-110,-106,131,-105,-108,-111,-107,-126,-128,-125,131,131,131,]),'DOT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,146,147,149,150,156,157,159,175,176,177,178,179,180,181,182,185,186,187,189,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,216,217,225,230,231,238,240,242,243,248,255,257,259,266,274,275,276,277,278,281,282,283,284,286,289,331,340,343,345,],[132,-134,-87,-104,144,-121,-129,-135,-136,-137,132,132,132,132,-122,132,-123,-124,-130,-131,132,-89,-115,235,236,-120,-119,132,-78,-86,132,-76,132,-90,132,-91,132,-92,132,-93,132,-94,132,-95,132,-96,132,244,245,-117,-118,-114,-116,-132,-133,132,132,132,-81,-80,-77,-79,-127,132,132,132,132,-112,-109,-110,-106,132,-105,-108,-111,-107,-126,-128,-125,132,132,132,]),'THEN':([86,87,88,89,90,99,102,103,104,146,149,150,151,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,211,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LOOP':([86,87,88,89,90,99,102,103,104,146,149,150,152,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,212,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'OF':([86,87,88,89,90,99,102,103,104,146,149,150,155,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,215,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LESSEQUAL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,136,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,136,-97,136,-98,136,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'LESS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,137,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,137,-97,137,-98,137,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'EQUAL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,138,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,138,-97,138,-98,138,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'PLUS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,139,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,139,-97,139,-98,139,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'MINUS':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,140,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,140,-97,140,-98,140,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'STAR':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,141,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,141,-97,141,-98,141,-99,141,-100,141,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'DIV':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,142,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,142,-97,142,-98,142,-99,142,-100,142,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'ELSE':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,246,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,285,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'POOL':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,247,248,274,275,276,277,281,282,283,284,286,289,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,286,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-125,]),'FI':([86,87,88,89,90,99,102,103,104,146,149,150,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,274,275,276,277,281,282,283,284,286,289,312,331,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,331,-125,]),'IN':([86,87,88,89,90,99,102,103,104,146,149,150,153,156,157,175,176,179,180,182,185,186,187,191,192,193,194,195,196,197,198,199,200,201,202,203,204,207,208,209,210,216,217,238,240,242,243,248,249,274,275,276,277,281,282,283,284,286,289,313,314,331,338,],[-134,-87,-104,-113,-121,-129,-135,-136,-137,-122,-123,-124,213,-130,-131,-89,-115,-120,-119,-78,-86,-88,-76,-90,-97,-91,-98,-92,-99,-93,-100,-94,-101,-95,-102,-96,-103,-117,-118,-114,-116,-132,-133,-81,-80,-77,-79,-127,-56,-112,-109,-110,-106,-105,-108,-111,-107,-126,-128,-57,-58,-125,-59,]),'ESAC':([250,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,],[289,-60,-64,-65,-63,-68,-66,-67,-62,-61,-71,-72,-70,-75,-73,-74,-69,]),'ACTION':([315,316,317,318,],[333,335,336,337,]),} +_lr_action_items = {'error':([0,3,4,5,10,11,12,13,15,16,18,21,26,29,30,32,34,35,36,39,40,41,42,43,44,51,57,59,60,61,64,65,71,72,73,74,76,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,113,114,115,118,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,164,165,167,173,174,175,176,179,180,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,207,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,249,251,252,254,255,257,258,259,260,261,262,263,264,265,266,267,268,269,272,282,284,286,293,301,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,332,333,334,335,339,340,341,342,347,350,354,358,362,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,409,412,414,416,417,418,419,420,421,422,423,],[4,4,4,9,15,20,21,23,26,26,33,26,26,43,45,51,55,57,58,61,63,-6,-9,-23,-21,-22,26,-10,-8,26,84,105,-19,113,114,116,120,128,-29,-187,-126,-157,-166,-174,128,154,154,154,128,128,162,128,-182,165,167,-188,-189,-190,128,-24,169,171,128,128,-25,178,181,-7,-11,-12,-15,-14,-13,128,128,185,187,189,191,193,195,197,199,201,204,209,212,215,217,219,221,223,225,227,229,231,233,-175,128,-187,-176,-177,-183,-184,128,128,-20,248,249,254,255,-128,-168,128,-132,128,-135,128,-138,128,-147,128,-148,128,-153,128,-156,-173,-172,128,-117,233,-125,128,-115,128,-129,128,-130,128,-131,128,-141,128,-142,128,-143,128,-144,128,-170,-171,-167,-169,128,128,128,274,275,279,-185,-186,128,281,282,284,286,128,293,128,128,128,299,128,301,303,204,-120,305,-119,305,-116,-118,309,310,-180,128,128,128,128,-165,-162,-163,-159,128,-158,-161,-164,-160,128,-179,347,349,350,352,354,356,358,360,-181,363,364,-44,-50,-48,-49,-32,-46,-47,-45,128,128,128,128,388,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,393,394,396,398,400,402,404,406,409,410,128,412,414,128,128,128,425,279,427,429,431,433,435,437,]),'CLASS':([0,3,4,41,42,59,60,122,123,124,125,126,127,],[5,5,5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'$end':([1,2,3,6,7,41,42,59,60,122,123,124,125,126,127,],[0,-2,-4,-3,-5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'TYPE':([5,11,13,29,32,68,70,74,76,100,107,108,118,121,138,150,237,238,323,324,],[8,19,24,44,50,109,111,117,119,164,170,172,177,182,200,228,273,276,362,365,]),'OCURL':([8,9,19,20,23,24,64,65,72,73,84,91,92,93,94,95,96,98,101,105,109,113,114,116,117,119,120,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,169,170,171,172,173,176,177,178,179,180,181,182,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[10,12,35,36,39,40,101,101,101,101,101,101,101,101,101,101,101,101,101,101,173,101,101,175,176,179,180,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,243,244,245,246,101,101,251,252,101,101,257,258,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'INHERITS':([8,9,],[11,13,]),'ID':([10,12,15,16,21,26,30,34,35,39,43,44,51,57,61,64,65,69,71,72,73,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,101,102,103,104,105,106,113,114,115,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,153,154,155,156,157,164,165,167,173,174,176,179,180,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,234,235,236,239,240,241,242,244,245,246,249,251,252,254,255,258,259,260,261,262,263,264,265,266,267,268,269,272,282,284,286,293,301,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,332,333,334,335,339,340,341,342,347,350,354,358,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,389,390,391,409,412,414,416,417,418,419,420,421,422,423,],[18,18,18,18,18,18,49,49,18,18,-23,-21,-22,18,18,86,86,49,-19,86,86,86,-29,-187,-126,-157,-166,-174,86,155,155,155,86,86,161,86,-182,86,-188,-189,-190,86,-24,86,86,-25,86,86,155,155,155,155,155,155,155,203,86,86,86,155,155,155,155,155,155,155,203,-175,86,-187,-176,-177,-183,-184,86,86,-20,86,86,86,-128,-168,86,-132,86,-135,86,-138,86,-147,86,-148,86,-153,86,-156,-173,-172,86,-117,-125,86,-115,86,-129,86,-130,86,-131,86,-141,86,-142,86,-143,86,-144,86,-170,-171,-167,-169,86,86,86,278,-185,-186,86,86,86,86,86,86,86,86,86,86,203,203,86,-120,86,-119,86,-116,-118,203,203,-180,86,86,86,86,-165,-162,-163,-159,86,-158,-161,-164,-160,86,-179,86,161,86,161,86,161,86,161,-181,-44,-50,-48,-49,-32,-46,-47,-45,86,86,86,86,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,161,161,161,161,161,161,161,161,86,86,86,86,86,86,86,278,278,278,278,278,278,278,278,]),'CCURL':([10,12,14,15,16,17,21,22,26,28,31,35,39,43,44,51,56,57,58,61,62,63,71,84,85,86,87,88,89,90,99,102,103,104,105,106,113,114,115,153,155,156,157,164,165,166,167,174,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,242,247,248,249,250,253,254,255,256,262,264,266,267,272,280,281,282,283,284,285,286,287,292,293,294,299,300,301,302,303,304,308,309,310,311,313,322,332,333,334,335,339,340,341,342,366,367,368,369,370,371,372,373,374,375,376,377,378,],[-1,-1,25,27,-1,-17,37,38,-1,-18,-16,-1,-1,-23,-21,-22,78,79,80,81,82,83,-19,-30,-29,-187,-126,-157,-166,-174,-182,-188,-189,-190,-28,-24,-26,-27,-25,-175,-187,-176,-177,-183,-184,240,241,-20,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-54,288,289,290,291,295,296,297,298,-120,-119,-116,-118,-180,-55,325,326,327,328,329,330,331,336,337,338,343,344,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,]),'COLON':([15,18,21,26,47,49,52,54,57,61,66,67,75,77,161,162,278,279,349,352,356,360,393,394,396,398,400,402,404,406,425,427,429,431,433,435,437,],[29,32,29,29,68,70,74,76,29,29,107,108,118,121,237,238,323,324,238,238,238,238,238,238,238,238,238,238,238,238,324,324,324,324,324,324,324,]),'OPAR':([15,18,21,26,57,61,64,65,72,73,84,86,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,155,167,173,176,179,180,185,187,189,191,193,195,197,201,203,204,209,212,215,217,219,221,223,225,227,231,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,301,303,305,309,310,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[30,34,30,30,30,30,91,91,91,91,140,142,91,91,91,91,91,91,91,91,140,140,140,140,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,140,142,140,91,91,91,91,140,140,140,140,140,140,140,261,142,140,140,140,140,140,140,140,140,140,140,261,91,91,91,91,91,91,91,140,91,91,140,140,91,91,91,91,140,140,140,140,261,261,140,261,261,91,91,91,91,91,140,140,140,140,91,91,91,91,140,140,140,]),'SEMI':([25,27,37,38,50,78,79,80,81,82,83,86,87,88,89,90,99,102,103,104,112,153,155,156,157,164,165,168,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,288,289,290,291,295,296,297,298,301,302,303,304,308,309,310,311,313,322,325,326,327,328,329,330,331,336,337,338,343,344,378,408,409,410,411,412,413,414,415,],[41,42,59,60,71,122,123,124,125,126,127,-187,-126,-157,-166,-174,-182,-188,-189,-190,174,-175,-187,-176,-177,-183,-184,242,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,332,333,334,335,339,340,341,342,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,366,367,368,369,370,371,372,373,374,375,376,377,-178,416,417,418,419,420,421,422,423,]),'CPAR':([30,33,34,45,46,48,53,55,86,87,88,89,90,99,102,103,104,110,111,130,140,142,152,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,261,262,264,266,267,272,301,302,303,304,305,306,307,308,309,310,311,313,322,378,],[47,52,54,66,67,-51,75,77,-187,-126,-157,-166,-174,-182,-188,-189,-190,-52,-53,184,205,210,232,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,262,-117,264,232,-125,-127,-115,266,267,-121,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,205,-120,-119,-116,-118,-180,-165,-162,-163,-159,-123,-124,-122,-158,-161,-164,-160,-179,-181,-178,]),'ASSIGN':([43,44,50,51,84,86,105,113,114,128,167,204,209,212,249,254,255,273,274,275,276,282,284,286,293,305,347,350,354,358,409,412,414,],[64,65,72,73,129,141,129,129,129,129,129,129,129,129,129,129,129,314,316,318,320,129,129,129,129,129,129,129,129,129,129,129,129,]),'COMMA':([48,86,87,88,89,90,99,102,103,104,111,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,207,208,209,210,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,273,274,275,276,301,302,303,304,305,308,309,310,311,313,322,346,347,350,351,354,355,358,359,378,],[69,-187,-126,-157,-166,-174,-182,-188,-189,-190,-53,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,263,-117,265,-125,-127,-115,263,265,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,315,317,319,321,-165,-162,-163,-159,263,-158,-161,-164,-160,-179,-181,379,380,381,382,383,384,385,386,-178,]),'INT_COMPLEMENT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'NOT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,]),'ISVOID':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,]),'IF':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'WHILE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,]),'LET':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'CASE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'NEW':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'INTEGER':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,]),'STRING':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'BOOL':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'LESSEQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[131,-187,143,-157,-166,-174,-182,-188,-189,-190,131,131,131,131,-175,-187,-176,-177,-183,-184,131,-128,-168,131,143,131,143,131,143,131,-147,131,-148,131,-153,131,-156,-173,-172,131,-117,-125,131,-115,131,143,131,143,131,143,131,-141,131,-142,131,-143,131,-144,131,-170,-171,-167,-169,-185,-186,131,131,131,-120,-119,-116,-118,-180,131,131,131,131,-165,-162,-163,-159,131,-158,-161,-164,-160,-179,-181,131,131,131,131,-178,131,131,131,]),'LESS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[132,-187,144,-157,-166,-174,-182,-188,-189,-190,132,132,132,132,-175,-187,-176,-177,-183,-184,132,-128,-168,132,144,132,144,132,144,132,-147,132,-148,132,-153,132,-156,-173,-172,132,-117,-125,132,-115,132,144,132,144,132,144,132,-141,132,-142,132,-143,132,-144,132,-170,-171,-167,-169,-185,-186,132,132,132,-120,-119,-116,-118,-180,132,132,132,132,-165,-162,-163,-159,132,-158,-161,-164,-160,-179,-181,132,132,132,132,-178,132,132,132,]),'EQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[133,-187,145,-157,-166,-174,-182,-188,-189,-190,133,133,133,133,-175,-187,-176,-177,-183,-184,133,-128,-168,133,145,133,145,133,145,133,-147,133,-148,133,-153,133,-156,-173,-172,133,-117,-125,133,-115,133,145,133,145,133,145,133,-141,133,-142,133,-143,133,-144,133,-170,-171,-167,-169,-185,-186,133,133,133,-120,-119,-116,-118,-180,133,133,133,133,-165,-162,-163,-159,133,-158,-161,-164,-160,-179,-181,133,133,133,133,-178,133,133,133,]),'PLUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[134,-187,146,-157,-166,-174,-182,-188,-189,-190,134,134,134,134,-175,-187,-176,-177,-183,-184,134,-128,-168,134,146,134,146,134,146,134,-147,134,-148,134,-153,134,-156,-173,-172,134,-117,-125,134,-115,134,146,134,146,134,146,134,-141,134,-142,134,-143,134,-144,134,-170,-171,-167,-169,-185,-186,134,134,134,-120,-119,-116,-118,-180,134,134,134,134,-165,-162,-163,-159,134,-158,-161,-164,-160,-179,-181,134,134,134,134,-178,134,134,134,]),'MINUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[135,-187,147,-157,-166,-174,-182,-188,-189,-190,135,135,135,135,-175,-187,-176,-177,-183,-184,135,-128,-168,135,147,135,147,135,147,135,-147,135,-148,135,-153,135,-156,-173,-172,135,-117,-125,135,-115,135,147,135,147,135,147,135,-141,135,-142,135,-143,135,-144,135,-170,-171,-167,-169,-185,-186,135,135,135,-120,-119,-116,-118,-180,135,135,135,135,-165,-162,-163,-159,135,-158,-161,-164,-160,-179,-181,135,135,135,135,-178,135,135,135,]),'STAR':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[136,-187,148,-157,-166,-174,-182,-188,-189,-190,136,136,136,136,-175,-187,-176,-177,-183,-184,136,-128,-168,136,148,136,148,136,148,136,148,136,148,136,-153,136,-156,-173,-172,136,-117,-125,136,-115,136,148,136,148,136,148,136,148,136,148,136,-143,136,-144,136,-170,-171,-167,-169,-185,-186,136,136,136,-120,-119,-116,-118,-180,136,136,136,136,-165,-162,-163,-159,136,-158,-161,-164,-160,-179,-181,136,136,136,136,-178,136,136,136,]),'DIV':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[137,-187,149,-157,-166,-174,-182,-188,-189,-190,137,137,137,137,-175,-187,-176,-177,-183,-184,137,-128,-168,137,149,137,149,137,149,137,149,137,149,137,-153,137,-156,-173,-172,137,-117,-125,137,-115,137,149,137,149,137,149,137,149,137,149,137,-143,137,-144,137,-170,-171,-167,-169,-185,-186,137,137,137,-120,-119,-116,-118,-180,137,137,137,137,-165,-162,-163,-159,137,-158,-161,-164,-160,-179,-181,137,137,137,137,-178,137,137,137,]),'AT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[138,-187,-126,-157,150,-174,-182,-188,-189,-190,138,138,138,138,-175,138,-187,-176,-177,-183,-184,138,-128,-168,138,-132,138,-135,138,-138,138,-147,138,-148,138,-153,138,-156,-173,-172,138,-117,-125,138,-115,138,-129,138,-130,138,-131,138,-141,138,-142,138,-143,138,-144,138,-170,-171,-167,-169,-185,-186,138,138,138,-120,-119,-116,-118,-180,138,138,138,138,-165,-162,-163,-159,138,-158,-161,-164,-160,-179,-181,138,138,138,138,-178,138,138,138,]),'DOT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[139,-187,-126,-157,151,-174,-182,-188,-189,-190,139,139,139,139,-175,139,-187,-176,-177,-183,-184,139,-128,-168,139,-132,139,-135,139,-138,139,-147,139,-148,139,-153,139,-156,259,260,-173,-172,139,-117,-125,139,-115,139,-129,139,-130,139,-131,139,-141,139,-142,139,-143,139,-144,139,268,269,-170,-171,-167,-169,-185,-186,139,139,139,-120,-119,-116,-118,-180,139,139,139,139,-165,-162,-163,-159,139,-158,-161,-164,-160,-179,-181,139,139,139,139,-178,139,139,139,]),'THEN':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,234,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'LOOP':([86,87,88,89,90,99,102,103,104,153,155,156,157,159,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,235,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'OF':([86,87,88,89,90,99,102,103,104,153,155,156,157,163,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,239,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'ELSE':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,270,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,312,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'POOL':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,271,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,313,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'FI':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,345,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,378,-178,]),'IN':([86,87,88,89,90,99,102,103,104,153,155,156,157,160,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,273,274,275,276,301,302,303,304,308,309,310,311,313,322,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,378,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,236,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-56,-61,-62,-60,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-57,-65,-58,-72,-66,-64,-73,-71,-69,-67,-76,-74,-68,-63,-75,-70,-178,-59,-84,-80,-88,-78,-86,-82,-90,-77,-85,-81,-89,-79,-87,-83,-91,]),'ESAC':([277,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,],[322,-92,-96,-97,-95,-100,-98,-99,-94,-93,-109,-103,-111,-104,-110,-102,-114,-107,-112,-105,-113,-106,-108,-101,]),'ACTION':([362,363,364,365,],[387,389,390,391,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): @@ -17,7 +17,7 @@ _lr_action[_x][_k] = _y del _lr_action_items -_lr_goto_items = {'program':([0,],[1,]),'class_list':([0,3,4,],[2,6,7,]),'def_class':([0,3,4,],[3,3,3,]),'feature_list':([10,12,15,16,21,26,35,39,57,61,],[14,22,28,31,28,28,56,62,28,28,]),'feature':([10,12,15,16,21,26,35,39,57,61,],[16,16,16,16,16,16,16,16,16,16,]),'epsilon':([10,12,15,16,21,26,35,39,57,61,],[17,17,17,17,17,17,17,17,17,17,]),'param_list':([30,34,69,],[46,53,110,]),'param':([30,34,69,],[48,48,48,]),'expr':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,133,134,135,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[85,106,112,115,130,145,151,152,155,160,130,130,130,130,175,184,185,190,130,130,223,226,229,232,130,130,130,130,130,130,130,130,130,130,246,247,248,160,256,258,260,130,265,267,130,130,273,190,190,190,130,130,130,130,130,312,313,339,342,344,346,130,130,130,]),'operat':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,191,193,195,197,199,201,203,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'baseop':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[88,88,88,88,88,88,146,149,150,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,]),'subatom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,]),'funccall':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,132,133,134,135,136,137,138,139,140,141,142,144,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,235,236,237,239,241,244,245,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,180,90,90,90,90,90,90,90,90,90,90,207,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,275,277,90,90,90,281,284,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'atom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,133,134,135,136,137,138,139,140,141,142,147,159,165,168,171,172,181,186,189,192,194,196,198,200,202,204,211,212,213,218,220,221,222,225,227,228,230,231,234,237,239,241,255,257,259,266,278,285,287,333,335,336,337,340,343,345,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'let_list':([97,288,332,],[153,314,338,]),'expr_block':([101,218,],[158,253,]),'arg_list':([133,135,237,239,241,],[183,188,183,279,280,]),'case_list':([215,347,348,349,350,351,352,353,354,],[250,355,356,357,358,359,360,361,362,]),} +_lr_goto_items = {'program':([0,],[1,]),'class_list':([0,3,4,],[2,6,7,]),'def_class':([0,3,4,],[3,3,3,]),'feature_list':([10,12,15,16,21,26,35,39,57,61,],[14,22,28,31,28,28,56,62,28,28,]),'feature':([10,12,15,16,21,26,35,39,57,61,],[16,16,16,16,16,16,16,16,16,16,]),'epsilon':([10,12,15,16,21,26,35,39,57,61,],[17,17,17,17,17,17,17,17,17,17,]),'param_list':([30,34,69,],[46,53,110,]),'param':([30,34,69,],[48,48,48,]),'expr':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,140,141,142,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[85,106,112,115,130,152,158,159,163,168,130,130,130,130,183,207,208,213,130,130,247,250,253,256,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,270,271,272,168,283,285,287,130,292,294,130,130,300,213,213,213,130,130,130,130,130,345,346,351,355,359,130,130,130,130,408,411,413,415,130,130,130,]),'operat':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,186,188,190,192,194,196,198,87,87,87,214,216,218,220,222,224,226,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'baseop':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[88,88,88,88,88,88,153,156,157,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,]),'subatom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,]),'funccall':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,259,260,261,263,265,268,269,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,202,90,90,90,90,90,90,90,90,90,90,230,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,302,304,90,90,90,308,311,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'atom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'let_list':([97,315,317,319,321,379,380,381,382,383,384,385,386,],[160,348,353,357,361,392,395,397,399,401,403,405,407,]),'expr_block':([101,242,],[166,280,]),'arg_list':([140,142,261,263,265,],[206,211,206,306,307,]),'case_list':([239,416,417,418,419,420,421,422,423,],[277,424,426,428,430,432,434,436,438,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): @@ -86,82 +86,135 @@ ('let_list -> ID COLON TYPE ASSIGN expr','let_list',5,'p_let_list','cool_parser.py',167), ('let_list -> ID COLON TYPE COMMA let_list','let_list',5,'p_let_list','cool_parser.py',168), ('let_list -> ID COLON TYPE ASSIGN expr COMMA let_list','let_list',7,'p_let_list','cool_parser.py',169), - ('case_list -> ID COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list','cool_parser.py',183), - ('case_list -> ID COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list','cool_parser.py',184), - ('case_list -> error COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',193), - ('case_list -> ID COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',194), - ('case_list -> ID COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',195), - ('case_list -> ID COLON TYPE error error SEMI','case_list',6,'p_case_list_error','cool_parser.py',196), - ('case_list -> error COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',197), - ('case_list -> error COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',198), - ('case_list -> error COLON error ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',199), - ('case_list -> error COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',200), - ('case_list -> ID COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',201), - ('case_list -> ID COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',202), - ('case_list -> ID COLON TYPE error error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',203), - ('case_list -> error COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',204), - ('case_list -> error COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',205), - ('case_list -> error COLON error ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',206), - ('funccall -> ID OPAR CPAR','funccall',3,'p_func_call','cool_parser.py',210), - ('funccall -> ID OPAR arg_list CPAR','funccall',4,'p_func_call','cool_parser.py',211), - ('funccall -> error OPAR CPAR','funccall',3,'p_func_call_error','cool_parser.py',218), - ('funccall -> ID OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',219), - ('funccall -> error OPAR arg_list CPAR','funccall',4,'p_func_call_error','cool_parser.py',220), - ('funccall -> error OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',221), - ('arg_list -> expr','arg_list',1,'p_arg_list','cool_parser.py',225), - ('arg_list -> expr COMMA arg_list','arg_list',3,'p_arg_list','cool_parser.py',226), - ('arg_list -> error','arg_list',1,'p_arg_list_error','cool_parser.py',233), - ('arg_list -> error COMMA arg_list','arg_list',3,'p_arg_list_error','cool_parser.py',234), - ('expr -> ID ASSIGN expr','expr',3,'p_expr','cool_parser.py',238), - ('expr -> operat','expr',1,'p_expr','cool_parser.py',239), - ('expr -> ID ASSIGN error','expr',3,'p_expr_error','cool_parser.py',246), - ('expr -> error ASSIGN expr','expr',3,'p_expr_error','cool_parser.py',247), - ('operat -> operat LESSEQUAL operat','operat',3,'p_comp','cool_parser.py',251), - ('operat -> operat LESS operat','operat',3,'p_comp','cool_parser.py',252), - ('operat -> operat EQUAL operat','operat',3,'p_comp','cool_parser.py',253), - ('operat -> operat PLUS operat','operat',3,'p_arith','cool_parser.py',262), - ('operat -> operat MINUS operat','operat',3,'p_arith','cool_parser.py',263), - ('operat -> operat STAR operat','operat',3,'p_arith','cool_parser.py',264), - ('operat -> operat DIV operat','operat',3,'p_arith','cool_parser.py',265), - ('operat -> operat LESSEQUAL error','operat',3,'p_operat_error','cool_parser.py',276), - ('operat -> operat LESS error','operat',3,'p_operat_error','cool_parser.py',277), - ('operat -> operat EQUAL error','operat',3,'p_operat_error','cool_parser.py',278), - ('operat -> operat PLUS error','operat',3,'p_operat_error','cool_parser.py',279), - ('operat -> operat MINUS error','operat',3,'p_operat_error','cool_parser.py',280), - ('operat -> operat STAR error','operat',3,'p_operat_error','cool_parser.py',281), - ('operat -> operat DIV error','operat',3,'p_operat_error','cool_parser.py',282), - ('operat -> baseop','operat',1,'p_base_operat','cool_parser.py',286), - ('baseop -> subatom AT TYPE DOT funccall','baseop',5,'p_static_call','cool_parser.py',290), - ('baseop -> error AT TYPE DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',294), - ('baseop -> subatom AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',295), - ('baseop -> subatom AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',296), - ('baseop -> error AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',297), - ('baseop -> error AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',298), - ('baseop -> subatom AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',299), - ('baseop -> error AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',300), - ('baseop -> subatom','baseop',1,'p_sub_atom','cool_parser.py',304), - ('subatom -> OPAR expr CPAR','subatom',3,'p_parent_expr','cool_parser.py',308), - ('subatom -> error expr CPAR','subatom',3,'p_parent_expr_error','cool_parser.py',312), - ('subatom -> OPAR expr error','subatom',3,'p_parent_expr_error','cool_parser.py',313), - ('subatom -> subatom DOT funccall','subatom',3,'p_dynamic_call','cool_parser.py',317), - ('subatom -> subatom DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',321), - ('subatom -> error DOT funccall','subatom',3,'p_dynamic_call_error','cool_parser.py',322), - ('subatom -> error DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',323), - ('subatom -> funccall','subatom',1,'p_member_call','cool_parser.py',327), - ('subatom -> INT_COMPLEMENT baseop','subatom',2,'p_unary_operations','cool_parser.py',331), - ('subatom -> NOT baseop','subatom',2,'p_unary_operations','cool_parser.py',332), - ('subatom -> ISVOID baseop','subatom',2,'p_unary_operations','cool_parser.py',333), - ('subatom -> IF expr THEN expr ELSE expr FI','subatom',7,'p_complex_sub_atom','cool_parser.py',348), - ('subatom -> WHILE expr LOOP expr POOL','subatom',5,'p_complex_sub_atom','cool_parser.py',349), - ('subatom -> LET let_list IN expr','subatom',4,'p_complex_sub_atom','cool_parser.py',350), - ('subatom -> CASE expr OF case_list ESAC','subatom',5,'p_complex_sub_atom','cool_parser.py',351), - ('subatom -> atom','subatom',1,'p_atom','cool_parser.py',365), - ('atom -> NEW TYPE','atom',2,'p_new','cool_parser.py',369), - ('atom -> NEW error','atom',2,'p_new_error','cool_parser.py',373), - ('atom -> OCURL expr_block CCURL','atom',3,'p_atom_expr_block','cool_parser.py',377), - ('atom -> OCURL error CCURL','atom',3,'p_atom_expr_block_error','cool_parser.py',381), - ('expr -> ID','expr',1,'p_atom_id','cool_parser.py',385), - ('atom -> INTEGER','atom',1,'p_atom_integer','cool_parser.py',389), - ('atom -> STRING','atom',1,'p_atom_string','cool_parser.py',393), - ('atom -> BOOL','atom',1,'p_atom_bool','cool_parser.py',397), + ('let_list -> error COLON TYPE','let_list',3,'p_let_list_error','cool_parser.py',183), + ('let_list -> ID COLON error','let_list',3,'p_let_list_error','cool_parser.py',184), + ('let_list -> error COLON error','let_list',3,'p_let_list_error','cool_parser.py',185), + ('let_list -> error COLON TYPE ASSIGN expr','let_list',5,'p_let_list_error','cool_parser.py',186), + ('let_list -> ID COLON error ASSIGN expr','let_list',5,'p_let_list_error','cool_parser.py',187), + ('let_list -> ID COLON TYPE ASSIGN error','let_list',5,'p_let_list_error','cool_parser.py',188), + ('let_list -> ID COLON error ASSIGN error','let_list',5,'p_let_list_error','cool_parser.py',189), + ('let_list -> error COLON error ASSIGN expr','let_list',5,'p_let_list_error','cool_parser.py',190), + ('let_list -> error COLON TYPE ASSIGN error','let_list',5,'p_let_list_error','cool_parser.py',191), + ('let_list -> error COLON error ASSIGN error','let_list',5,'p_let_list_error','cool_parser.py',192), + ('let_list -> error COLON TYPE COMMA let_list','let_list',5,'p_let_list_error','cool_parser.py',193), + ('let_list -> ID COLON error COMMA let_list','let_list',5,'p_let_list_error','cool_parser.py',194), + ('let_list -> ID COLON TYPE COMMA error','let_list',5,'p_let_list_error','cool_parser.py',195), + ('let_list -> ID COLON error COMMA error','let_list',5,'p_let_list_error','cool_parser.py',196), + ('let_list -> error COLON error COMMA let_list','let_list',5,'p_let_list_error','cool_parser.py',197), + ('let_list -> error COLON TYPE COMMA error','let_list',5,'p_let_list_error','cool_parser.py',198), + ('let_list -> error COLON error COMMA error','let_list',5,'p_let_list_error','cool_parser.py',199), + ('let_list -> error COLON error ASSIGN error COMMA error','let_list',7,'p_let_list_error','cool_parser.py',200), + ('let_list -> ID COLON error ASSIGN error COMMA error','let_list',7,'p_let_list_error','cool_parser.py',201), + ('let_list -> error COLON TYPE ASSIGN error COMMA error','let_list',7,'p_let_list_error','cool_parser.py',202), + ('let_list -> ID COLON TYPE ASSIGN error COMMA error','let_list',7,'p_let_list_error','cool_parser.py',203), + ('let_list -> error COLON error ASSIGN expr COMMA error','let_list',7,'p_let_list_error','cool_parser.py',204), + ('let_list -> ID COLON error ASSIGN expr COMMA error','let_list',7,'p_let_list_error','cool_parser.py',205), + ('let_list -> error COLON TYPE ASSIGN expr COMMA error','let_list',7,'p_let_list_error','cool_parser.py',206), + ('let_list -> ID COLON TYPE ASSIGN expr COMMA error','let_list',7,'p_let_list_error','cool_parser.py',207), + ('let_list -> error COLON error ASSIGN error COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',208), + ('let_list -> ID COLON error ASSIGN error COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',209), + ('let_list -> error COLON TYPE ASSIGN error COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',210), + ('let_list -> ID COLON TYPE ASSIGN error COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',211), + ('let_list -> error COLON error ASSIGN expr COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',212), + ('let_list -> ID COLON error ASSIGN expr COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',213), + ('let_list -> error COLON TYPE ASSIGN expr COMMA let_list','let_list',7,'p_let_list_error','cool_parser.py',214), + ('case_list -> ID COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list','cool_parser.py',218), + ('case_list -> ID COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list','cool_parser.py',219), + ('case_list -> error COLON TYPE ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',228), + ('case_list -> ID COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',229), + ('case_list -> ID COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',230), + ('case_list -> ID COLON TYPE error error SEMI','case_list',6,'p_case_list_error','cool_parser.py',231), + ('case_list -> error COLON error ACTION expr SEMI','case_list',6,'p_case_list_error','cool_parser.py',232), + ('case_list -> error COLON TYPE ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',233), + ('case_list -> error COLON error ACTION error SEMI','case_list',6,'p_case_list_error','cool_parser.py',234), + ('case_list -> error COLON TYPE ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',235), + ('case_list -> ID COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',236), + ('case_list -> ID COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',237), + ('case_list -> ID COLON TYPE error error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',238), + ('case_list -> error COLON error ACTION expr SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',239), + ('case_list -> error COLON TYPE ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',240), + ('case_list -> error COLON error ACTION error SEMI case_list','case_list',7,'p_case_list_error','cool_parser.py',241), + ('case_list -> error COLON TYPE ACTION expr SEMI error','case_list',7,'p_case_list_error','cool_parser.py',242), + ('case_list -> ID COLON TYPE ACTION expr SEMI error','case_list',7,'p_case_list_error','cool_parser.py',243), + ('case_list -> ID COLON error ACTION expr SEMI error','case_list',7,'p_case_list_error','cool_parser.py',244), + ('case_list -> ID COLON TYPE error error SEMI error','case_list',7,'p_case_list_error','cool_parser.py',245), + ('case_list -> error COLON error ACTION expr SEMI error','case_list',7,'p_case_list_error','cool_parser.py',246), + ('case_list -> error COLON TYPE ACTION error SEMI error','case_list',7,'p_case_list_error','cool_parser.py',247), + ('case_list -> error COLON error ACTION error SEMI error','case_list',7,'p_case_list_error','cool_parser.py',248), + ('funccall -> ID OPAR CPAR','funccall',3,'p_func_call','cool_parser.py',252), + ('funccall -> ID OPAR arg_list CPAR','funccall',4,'p_func_call','cool_parser.py',253), + ('funccall -> error OPAR CPAR','funccall',3,'p_func_call_error','cool_parser.py',260), + ('funccall -> ID OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',261), + ('funccall -> error OPAR arg_list CPAR','funccall',4,'p_func_call_error','cool_parser.py',262), + ('funccall -> error OPAR error CPAR','funccall',4,'p_func_call_error','cool_parser.py',263), + ('arg_list -> expr','arg_list',1,'p_arg_list','cool_parser.py',267), + ('arg_list -> expr COMMA arg_list','arg_list',3,'p_arg_list','cool_parser.py',268), + ('arg_list -> error','arg_list',1,'p_arg_list_error','cool_parser.py',275), + ('arg_list -> error COMMA arg_list','arg_list',3,'p_arg_list_error','cool_parser.py',276), + ('expr -> ID ASSIGN expr','expr',3,'p_expr','cool_parser.py',280), + ('expr -> operat','expr',1,'p_expr','cool_parser.py',281), + ('expr -> ID ASSIGN error','expr',3,'p_expr_error','cool_parser.py',288), + ('expr -> error ASSIGN expr','expr',3,'p_expr_error','cool_parser.py',289), + ('operat -> operat LESSEQUAL operat','operat',3,'p_comp','cool_parser.py',293), + ('operat -> operat LESS operat','operat',3,'p_comp','cool_parser.py',294), + ('operat -> operat EQUAL operat','operat',3,'p_comp','cool_parser.py',295), + ('operat -> error LESSEQUAL operat','operat',3,'p_comp_error','cool_parser.py',304), + ('operat -> error LESSEQUAL error','operat',3,'p_comp_error','cool_parser.py',305), + ('operat -> operat LESSEQUAL error','operat',3,'p_comp_error','cool_parser.py',306), + ('operat -> error LESS operat','operat',3,'p_comp_error','cool_parser.py',307), + ('operat -> error LESS error','operat',3,'p_comp_error','cool_parser.py',308), + ('operat -> operat LESS error','operat',3,'p_comp_error','cool_parser.py',309), + ('operat -> error EQUAL operat','operat',3,'p_comp_error','cool_parser.py',310), + ('operat -> error EQUAL error','operat',3,'p_comp_error','cool_parser.py',311), + ('operat -> operat EQUAL error','operat',3,'p_comp_error','cool_parser.py',312), + ('operat -> operat PLUS operat','operat',3,'p_arith','cool_parser.py',316), + ('operat -> operat MINUS operat','operat',3,'p_arith','cool_parser.py',317), + ('operat -> operat STAR operat','operat',3,'p_arith','cool_parser.py',318), + ('operat -> operat DIV operat','operat',3,'p_arith','cool_parser.py',319), + ('operat -> operat PLUS error','operat',3,'p_operat_error','cool_parser.py',330), + ('operat -> error PLUS error','operat',3,'p_operat_error','cool_parser.py',331), + ('operat -> error PLUS operat','operat',3,'p_operat_error','cool_parser.py',332), + ('operat -> error MINUS operat','operat',3,'p_operat_error','cool_parser.py',333), + ('operat -> error MINUS error','operat',3,'p_operat_error','cool_parser.py',334), + ('operat -> operat MINUS error','operat',3,'p_operat_error','cool_parser.py',335), + ('operat -> operat STAR error','operat',3,'p_operat_error','cool_parser.py',336), + ('operat -> error STAR error','operat',3,'p_operat_error','cool_parser.py',337), + ('operat -> error STAR operat','operat',3,'p_operat_error','cool_parser.py',338), + ('operat -> operat DIV error','operat',3,'p_operat_error','cool_parser.py',339), + ('operat -> error DIV error','operat',3,'p_operat_error','cool_parser.py',340), + ('operat -> error DIV operat','operat',3,'p_operat_error','cool_parser.py',341), + ('operat -> baseop','operat',1,'p_base_operat','cool_parser.py',345), + ('baseop -> subatom AT TYPE DOT funccall','baseop',5,'p_static_call','cool_parser.py',349), + ('baseop -> error AT TYPE DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',353), + ('baseop -> subatom AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',354), + ('baseop -> subatom AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',355), + ('baseop -> error AT error DOT funccall','baseop',5,'p_static_call_error','cool_parser.py',356), + ('baseop -> error AT TYPE DOT error','baseop',5,'p_static_call_error','cool_parser.py',357), + ('baseop -> subatom AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',358), + ('baseop -> error AT error DOT error','baseop',5,'p_static_call_error','cool_parser.py',359), + ('baseop -> subatom','baseop',1,'p_sub_atom','cool_parser.py',363), + ('subatom -> OPAR expr CPAR','subatom',3,'p_parent_expr','cool_parser.py',367), + ('subatom -> error expr CPAR','subatom',3,'p_parent_expr_error','cool_parser.py',371), + ('subatom -> OPAR expr error','subatom',3,'p_parent_expr_error','cool_parser.py',372), + ('subatom -> subatom DOT funccall','subatom',3,'p_dynamic_call','cool_parser.py',376), + ('subatom -> subatom DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',380), + ('subatom -> error DOT funccall','subatom',3,'p_dynamic_call_error','cool_parser.py',381), + ('subatom -> error DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',382), + ('subatom -> funccall','subatom',1,'p_member_call','cool_parser.py',386), + ('subatom -> INT_COMPLEMENT baseop','subatom',2,'p_unary_operations','cool_parser.py',390), + ('subatom -> NOT baseop','subatom',2,'p_unary_operations','cool_parser.py',391), + ('subatom -> ISVOID baseop','subatom',2,'p_unary_operations','cool_parser.py',392), + ('subatom -> IF expr THEN expr ELSE expr FI','subatom',7,'p_complex_sub_atom','cool_parser.py',407), + ('subatom -> WHILE expr LOOP expr POOL','subatom',5,'p_complex_sub_atom','cool_parser.py',408), + ('subatom -> LET let_list IN expr','subatom',4,'p_complex_sub_atom','cool_parser.py',409), + ('subatom -> CASE expr OF case_list ESAC','subatom',5,'p_complex_sub_atom','cool_parser.py',410), + ('subatom -> atom','subatom',1,'p_atom','cool_parser.py',424), + ('atom -> NEW TYPE','atom',2,'p_new','cool_parser.py',428), + ('atom -> NEW error','atom',2,'p_new_error','cool_parser.py',432), + ('atom -> OCURL expr_block CCURL','atom',3,'p_atom_expr_block','cool_parser.py',436), + ('atom -> OCURL error CCURL','atom',3,'p_atom_expr_block_error','cool_parser.py',440), + ('atom -> ID','atom',1,'p_atom_id','cool_parser.py',444), + ('atom -> INTEGER','atom',1,'p_atom_integer','cool_parser.py',448), + ('atom -> STRING','atom',1,'p_atom_string','cool_parser.py',452), + ('atom -> BOOL','atom',1,'p_atom_bool','cool_parser.py',456), ] diff --git a/src/main.py b/src/main.py index f85961bb..f7a7d6de 100644 --- a/src/main.py +++ b/src/main.py @@ -11,7 +11,7 @@ input_file = open(args[1], "r") output_file = open(args[2], 'w') -#input_file = open('./src/test.cl', "r") +# input_file = open('./src/test.cl', "r") # output_file = open('./src/test.mips', 'w') t = input_file.read() @@ -37,10 +37,10 @@ exit(1) # print(ast) -fmatter = Format() -tree = fmatter.visit(ast, 0) +# fmatter = Format() +# tree = fmatter.visit(ast, 0) -print(tree) +# print(tree) # collect_errors = [] # collect = Collector(collect_errors) @@ -91,6 +91,7 @@ # # output_file.write(str(builder_errors)) # # output_file.write(str(checker_errors)) # # output_file.write(collect_errors) +input_file.close() output_file.close() From 192f7f2ec7bbe1a8f8f083ceb25354cf292bd263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Sun, 6 Dec 2020 13:11:46 -0500 Subject: [PATCH 082/191] Fix empty file sysntactic error --- src/main.py | 57 ++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/main.py b/src/main.py index f7a7d6de..cb4c50b2 100644 --- a/src/main.py +++ b/src/main.py @@ -21,12 +21,15 @@ lexer = CoolLexer() tokens, errors = lexer.tokenize(t) -# print(tokens) if len(errors): for e in errors: print(e) exit(1) +if not tokens: + print(SyntacticError(0, 0, 'ERROR at or near "%s"' % 'EOF')) + exit(1) + lexer = CoolLexer() parser = CoolParser(lexer) ast, errors = parser.parse(t) @@ -42,37 +45,37 @@ # print(tree) -# collect_errors = [] -# collect = Collector(collect_errors) -# collect.visit(ast) +collect_errors = [] +collect = Collector(collect_errors) +collect.visit(ast) -# if len(collect_errors): -# # print("coolector") -# for e in collect_errors[::-1]: -# print(e) -# exit(1) +if len(collect_errors): + # print("coolector") + for e in collect_errors[::-1]: + print(e) + exit(1) -# context = collect.context -# builder_errors = [] -# builder = Builder(context, builder_errors) -# builder.visit(ast) +context = collect.context +builder_errors = [] +builder = Builder(context, builder_errors) +builder.visit(ast) -# if len(builder_errors): -# # print("builder") -# for e in builder_errors[::-1]: -# print(e) -# exit(1) +if len(builder_errors): + # print("builder") + for e in builder_errors[::-1]: + print(e) + exit(1) -# context = builder.context -# checker_errors = [] -# checker = Checker(context, checker_errors) -# scope = checker.visit(ast) +context = builder.context +checker_errors = [] +checker = Checker(context, checker_errors) +scope = checker.visit(ast) -# if len(checker_errors): -# # print("checker") -# for e in checker_errors[::-1]: -# print(e) -# exit(1) +if len(checker_errors): + # print("checker") + for e in checker_errors[::-1]: + print(e) + exit(1) # cil = COOL_TO_CIL(checker.context) From 34722024b4f4c22cdbfa833d399d7dd0e1f9afc2 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Sun, 6 Dec 2020 14:44:36 -0500 Subject: [PATCH 083/191] [fix] not derivation problem --- src/engine/parser/cool_parser.py | 10 ++++----- src/engine/parser/parsetab.py | 35 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/engine/parser/cool_parser.py b/src/engine/parser/cool_parser.py index 6d79feb2..34051a61 100644 --- a/src/engine/parser/cool_parser.py +++ b/src/engine/parser/cool_parser.py @@ -388,7 +388,7 @@ def p_member_call(self, p): def p_unary_operations(self, p): '''subatom : INT_COMPLEMENT baseop - | NOT baseop + | NOT operat | ISVOID baseop ''' if p.slice[1].lex == '~': p[0] = ComplementNode(p[2]) @@ -397,11 +397,9 @@ def p_unary_operations(self, p): else: p[0] = IsVoidNode(p[2]) - # def p_unary_operations_error(self, p): - # '''subatom : INT_COMPLEMENT error - # | NOT error - # | ISVOID error ''' - # p[0] = ErrorNode() + def p_unary_operations_error(self, p): + '''subatom : NOT error ''' + p[0] = ErrorNode() def p_complex_sub_atom(self, p): '''subatom : IF expr THEN expr ELSE expr FI diff --git a/src/engine/parser/parsetab.py b/src/engine/parser/parsetab.py index 1e823fdc..af4d7ac4 100644 --- a/src/engine/parser/parsetab.py +++ b/src/engine/parser/parsetab.py @@ -6,9 +6,9 @@ _lr_method = 'LALR' -_lr_signature = 'programrightASSIGNrightNOTnonassocLESSLESSEQUALEQUALleftPLUSMINUSleftSTARDIVrightISVOIDrightINT_COMPLEMENTleftATleftDOTACTION ASSIGN AT BOOL CASE CCURL CLASS COLON COMMA CPAR DIV DOT ELSE EQUAL ESAC FI ID IF IN INHERITS INTEGER INT_COMPLEMENT ISVOID LESS LESSEQUAL LET LOOP MINUS NEW NOT OCURL OF OPAR PLUS POOL SEMI STAR STRING THEN TYPE WHILEepsilon :program : class_listclass_list : def_class class_list\n | def_classclass_list : error class_list def_class : CLASS TYPE OCURL feature_list CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI def_class : CLASS error OCURL feature_list CCURL SEMI\n | CLASS TYPE OCURL error CCURL SEMI\n | CLASS error OCURL error CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI\n | CLASS TYPE INHERITS error OCURL error CCURL SEMI\n | CLASS error INHERITS TYPE OCURL error CCURL SEMI\n | CLASS error INHERITS error OCURL feature_list CCURL SEMI\n | CLASS error INHERITS error OCURL error CCURL SEMI feature_list : feature feature_list\n | epsilonfeature_list : error feature_listfeature : ID COLON TYPE SEMI\n | ID COLON TYPE ASSIGN expr SEMI feature : error COLON TYPE\n | ID COLON error\n | error COLON error\n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON error ASSIGN errorfeature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI\n | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR CPAR COLON error OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID error CPAR COLON error OCURL error CCURL SEMI param_list : param\n | param COMMA param_listparam : ID COLON TYPEexpr_block : expr SEMI\n | expr SEMI expr_blocklet_list : ID COLON TYPE\n | ID COLON TYPE ASSIGN expr\n | ID COLON TYPE COMMA let_list\n | ID COLON TYPE ASSIGN expr COMMA let_listlet_list : error COLON TYPE\n | ID COLON error\n | error COLON error \n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN error\n | error COLON TYPE COMMA let_list\n | ID COLON error COMMA let_list\n | ID COLON TYPE COMMA error\n | ID COLON error COMMA error\n | error COLON error COMMA let_list\n | error COLON TYPE COMMA error\n | error COLON error COMMA error\n | error COLON error ASSIGN error COMMA error\n | ID COLON error ASSIGN error COMMA error\n | error COLON TYPE ASSIGN error COMMA error\n | ID COLON TYPE ASSIGN error COMMA error\n | error COLON error ASSIGN expr COMMA error\n | ID COLON error ASSIGN expr COMMA error\n | error COLON TYPE ASSIGN expr COMMA error\n | ID COLON TYPE ASSIGN expr COMMA error\n | error COLON error ASSIGN error COMMA let_list\n | ID COLON error ASSIGN error COMMA let_list\n | error COLON TYPE ASSIGN error COMMA let_list\n | ID COLON TYPE ASSIGN error COMMA let_list\n | error COLON error ASSIGN expr COMMA let_list\n | ID COLON error ASSIGN expr COMMA let_list\n | error COLON TYPE ASSIGN expr COMMA let_list case_list : ID COLON TYPE ACTION expr SEMI\n | ID COLON TYPE ACTION expr SEMI case_list case_list : error COLON TYPE ACTION expr SEMI\n | ID COLON error ACTION expr SEMI\n | ID COLON TYPE ACTION error SEMI\n | ID COLON TYPE error error SEMI\n | error COLON error ACTION expr SEMI\n | error COLON TYPE ACTION error SEMI\n | error COLON error ACTION error SEMI\n | error COLON TYPE ACTION expr SEMI case_list\n | ID COLON error ACTION expr SEMI case_list\n | ID COLON TYPE ACTION error SEMI case_list\n | ID COLON TYPE error error SEMI case_list\n | error COLON error ACTION expr SEMI case_list\n | error COLON TYPE ACTION error SEMI case_list\n | error COLON error ACTION error SEMI case_list\n | error COLON TYPE ACTION expr SEMI error\n | ID COLON TYPE ACTION expr SEMI error\n | ID COLON error ACTION expr SEMI error\n | ID COLON TYPE error error SEMI error\n | error COLON error ACTION expr SEMI error\n | error COLON TYPE ACTION error SEMI error\n | error COLON error ACTION error SEMI errorfunccall : ID OPAR CPAR\n | ID OPAR arg_list CPARfunccall : error OPAR CPAR\n | ID OPAR error CPAR\n | error OPAR arg_list CPAR\n | error OPAR error CPAR arg_list : expr\n | expr COMMA arg_list arg_list : error\n | error COMMA arg_listexpr : ID ASSIGN expr\n | operat expr : ID ASSIGN error \n | error ASSIGN expr operat : operat LESSEQUAL operat\n | operat LESS operat\n | operat EQUAL operatoperat : error LESSEQUAL operat\n | error LESSEQUAL error\n | operat LESSEQUAL error\n | error LESS operat\n | error LESS error\n | operat LESS error\n | error EQUAL operat\n | error EQUAL error\n | operat EQUAL erroroperat : operat PLUS operat\n | operat MINUS operat\n | operat STAR operat\n | operat DIV operat operat : operat PLUS error\n | error PLUS error\n | error PLUS operat\n | error MINUS operat\n | error MINUS error\n | operat MINUS error\n | operat STAR error\n | error STAR error\n | error STAR operat\n | operat DIV error \n | error DIV error \n | error DIV operat operat : baseopbaseop : subatom AT TYPE DOT funccall baseop : error AT TYPE DOT funccall\n | subatom AT error DOT funccall\n | subatom AT TYPE DOT error\n | error AT error DOT funccall\n | error AT TYPE DOT error\n | subatom AT error DOT error\n | error AT error DOT error baseop : subatomsubatom : OPAR expr CPARsubatom : error expr CPAR\n | OPAR expr errorsubatom : subatom DOT funccall subatom : subatom DOT error \n | error DOT funccall\n | error DOT error subatom : funccall subatom : INT_COMPLEMENT baseop\n | NOT baseop\n | ISVOID baseop subatom : IF expr THEN expr ELSE expr FI\n | WHILE expr LOOP expr POOL\n | LET let_list IN expr \n | CASE expr OF case_list ESAC subatom : atomatom : NEW TYPEatom : NEW erroratom : OCURL expr_block CCURL atom : OCURL error CCURL atom : IDatom : INTEGERatom : STRINGatom : BOOL' +_lr_signature = 'programrightASSIGNrightNOTnonassocLESSLESSEQUALEQUALleftPLUSMINUSleftSTARDIVrightISVOIDrightINT_COMPLEMENTleftATleftDOTACTION ASSIGN AT BOOL CASE CCURL CLASS COLON COMMA CPAR DIV DOT ELSE EQUAL ESAC FI ID IF IN INHERITS INTEGER INT_COMPLEMENT ISVOID LESS LESSEQUAL LET LOOP MINUS NEW NOT OCURL OF OPAR PLUS POOL SEMI STAR STRING THEN TYPE WHILEepsilon :program : class_listclass_list : def_class class_list\n | def_classclass_list : error class_list def_class : CLASS TYPE OCURL feature_list CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL feature_list CCURL SEMI def_class : CLASS error OCURL feature_list CCURL SEMI\n | CLASS TYPE OCURL error CCURL SEMI\n | CLASS error OCURL error CCURL SEMI\n | CLASS TYPE INHERITS TYPE OCURL error CCURL SEMI\n | CLASS TYPE INHERITS error OCURL error CCURL SEMI\n | CLASS error INHERITS TYPE OCURL error CCURL SEMI\n | CLASS error INHERITS error OCURL feature_list CCURL SEMI\n | CLASS error INHERITS error OCURL error CCURL SEMI feature_list : feature feature_list\n | epsilonfeature_list : error feature_listfeature : ID COLON TYPE SEMI\n | ID COLON TYPE ASSIGN expr SEMI feature : error COLON TYPE\n | ID COLON error\n | error COLON error\n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON error ASSIGN errorfeature : ID OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL expr CCURL SEMI feature : error OPAR param_list CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL expr CCURL SEMI\n | error OPAR param_list CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR error CPAR COLON TYPE OCURL error CCURL SEMI\n | error OPAR error CPAR COLON error OCURL error CCURL SEMI\n | error OPAR param_list CPAR COLON error OCURL error CCURL SEMI\n | error OPAR CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON error OCURL expr CCURL SEMI\n | ID OPAR CPAR COLON TYPE OCURL error CCURL SEMI\n | ID OPAR CPAR COLON error OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL error CCURL SEMI\n | ID error CPAR COLON TYPE OCURL expr CCURL SEMI\n | ID error CPAR COLON error OCURL error CCURL SEMI param_list : param\n | param COMMA param_listparam : ID COLON TYPEexpr_block : expr SEMI\n | expr SEMI expr_blocklet_list : ID COLON TYPE\n | ID COLON TYPE ASSIGN expr\n | ID COLON TYPE COMMA let_list\n | ID COLON TYPE ASSIGN expr COMMA let_listlet_list : error COLON TYPE\n | ID COLON error\n | error COLON error \n | error COLON TYPE ASSIGN expr\n | ID COLON error ASSIGN expr\n | ID COLON TYPE ASSIGN error\n | ID COLON error ASSIGN error\n | error COLON error ASSIGN expr\n | error COLON TYPE ASSIGN error\n | error COLON error ASSIGN error\n | error COLON TYPE COMMA let_list\n | ID COLON error COMMA let_list\n | ID COLON TYPE COMMA error\n | ID COLON error COMMA error\n | error COLON error COMMA let_list\n | error COLON TYPE COMMA error\n | error COLON error COMMA error\n | error COLON error ASSIGN error COMMA error\n | ID COLON error ASSIGN error COMMA error\n | error COLON TYPE ASSIGN error COMMA error\n | ID COLON TYPE ASSIGN error COMMA error\n | error COLON error ASSIGN expr COMMA error\n | ID COLON error ASSIGN expr COMMA error\n | error COLON TYPE ASSIGN expr COMMA error\n | ID COLON TYPE ASSIGN expr COMMA error\n | error COLON error ASSIGN error COMMA let_list\n | ID COLON error ASSIGN error COMMA let_list\n | error COLON TYPE ASSIGN error COMMA let_list\n | ID COLON TYPE ASSIGN error COMMA let_list\n | error COLON error ASSIGN expr COMMA let_list\n | ID COLON error ASSIGN expr COMMA let_list\n | error COLON TYPE ASSIGN expr COMMA let_list case_list : ID COLON TYPE ACTION expr SEMI\n | ID COLON TYPE ACTION expr SEMI case_list case_list : error COLON TYPE ACTION expr SEMI\n | ID COLON error ACTION expr SEMI\n | ID COLON TYPE ACTION error SEMI\n | ID COLON TYPE error error SEMI\n | error COLON error ACTION expr SEMI\n | error COLON TYPE ACTION error SEMI\n | error COLON error ACTION error SEMI\n | error COLON TYPE ACTION expr SEMI case_list\n | ID COLON error ACTION expr SEMI case_list\n | ID COLON TYPE ACTION error SEMI case_list\n | ID COLON TYPE error error SEMI case_list\n | error COLON error ACTION expr SEMI case_list\n | error COLON TYPE ACTION error SEMI case_list\n | error COLON error ACTION error SEMI case_list\n | error COLON TYPE ACTION expr SEMI error\n | ID COLON TYPE ACTION expr SEMI error\n | ID COLON error ACTION expr SEMI error\n | ID COLON TYPE error error SEMI error\n | error COLON error ACTION expr SEMI error\n | error COLON TYPE ACTION error SEMI error\n | error COLON error ACTION error SEMI errorfunccall : ID OPAR CPAR\n | ID OPAR arg_list CPARfunccall : error OPAR CPAR\n | ID OPAR error CPAR\n | error OPAR arg_list CPAR\n | error OPAR error CPAR arg_list : expr\n | expr COMMA arg_list arg_list : error\n | error COMMA arg_listexpr : ID ASSIGN expr\n | operat expr : ID ASSIGN error \n | error ASSIGN expr operat : operat LESSEQUAL operat\n | operat LESS operat\n | operat EQUAL operatoperat : error LESSEQUAL operat\n | error LESSEQUAL error\n | operat LESSEQUAL error\n | error LESS operat\n | error LESS error\n | operat LESS error\n | error EQUAL operat\n | error EQUAL error\n | operat EQUAL erroroperat : operat PLUS operat\n | operat MINUS operat\n | operat STAR operat\n | operat DIV operat operat : operat PLUS error\n | error PLUS error\n | error PLUS operat\n | error MINUS operat\n | error MINUS error\n | operat MINUS error\n | operat STAR error\n | error STAR error\n | error STAR operat\n | operat DIV error \n | error DIV error \n | error DIV operat operat : baseopbaseop : subatom AT TYPE DOT funccall baseop : error AT TYPE DOT funccall\n | subatom AT error DOT funccall\n | subatom AT TYPE DOT error\n | error AT error DOT funccall\n | error AT TYPE DOT error\n | subatom AT error DOT error\n | error AT error DOT error baseop : subatomsubatom : OPAR expr CPARsubatom : error expr CPAR\n | OPAR expr errorsubatom : subatom DOT funccall subatom : subatom DOT error \n | error DOT funccall\n | error DOT error subatom : funccall subatom : INT_COMPLEMENT baseop\n | NOT operat\n | ISVOID baseop subatom : NOT error subatom : IF expr THEN expr ELSE expr FI\n | WHILE expr LOOP expr POOL\n | LET let_list IN expr \n | CASE expr OF case_list ESAC subatom : atomatom : NEW TYPEatom : NEW erroratom : OCURL expr_block CCURL atom : OCURL error CCURL atom : IDatom : INTEGERatom : STRINGatom : BOOL' -_lr_action_items = {'error':([0,3,4,5,10,11,12,13,15,16,18,21,26,29,30,32,34,35,36,39,40,41,42,43,44,51,57,59,60,61,64,65,71,72,73,74,76,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,113,114,115,118,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,164,165,167,173,174,175,176,179,180,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,207,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,249,251,252,254,255,257,258,259,260,261,262,263,264,265,266,267,268,269,272,282,284,286,293,301,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,332,333,334,335,339,340,341,342,347,350,354,358,362,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,409,412,414,416,417,418,419,420,421,422,423,],[4,4,4,9,15,20,21,23,26,26,33,26,26,43,45,51,55,57,58,61,63,-6,-9,-23,-21,-22,26,-10,-8,26,84,105,-19,113,114,116,120,128,-29,-187,-126,-157,-166,-174,128,154,154,154,128,128,162,128,-182,165,167,-188,-189,-190,128,-24,169,171,128,128,-25,178,181,-7,-11,-12,-15,-14,-13,128,128,185,187,189,191,193,195,197,199,201,204,209,212,215,217,219,221,223,225,227,229,231,233,-175,128,-187,-176,-177,-183,-184,128,128,-20,248,249,254,255,-128,-168,128,-132,128,-135,128,-138,128,-147,128,-148,128,-153,128,-156,-173,-172,128,-117,233,-125,128,-115,128,-129,128,-130,128,-131,128,-141,128,-142,128,-143,128,-144,128,-170,-171,-167,-169,128,128,128,274,275,279,-185,-186,128,281,282,284,286,128,293,128,128,128,299,128,301,303,204,-120,305,-119,305,-116,-118,309,310,-180,128,128,128,128,-165,-162,-163,-159,128,-158,-161,-164,-160,128,-179,347,349,350,352,354,356,358,360,-181,363,364,-44,-50,-48,-49,-32,-46,-47,-45,128,128,128,128,388,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,393,394,396,398,400,402,404,406,409,410,128,412,414,128,128,128,425,279,427,429,431,433,435,437,]),'CLASS':([0,3,4,41,42,59,60,122,123,124,125,126,127,],[5,5,5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'$end':([1,2,3,6,7,41,42,59,60,122,123,124,125,126,127,],[0,-2,-4,-3,-5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'TYPE':([5,11,13,29,32,68,70,74,76,100,107,108,118,121,138,150,237,238,323,324,],[8,19,24,44,50,109,111,117,119,164,170,172,177,182,200,228,273,276,362,365,]),'OCURL':([8,9,19,20,23,24,64,65,72,73,84,91,92,93,94,95,96,98,101,105,109,113,114,116,117,119,120,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,169,170,171,172,173,176,177,178,179,180,181,182,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[10,12,35,36,39,40,101,101,101,101,101,101,101,101,101,101,101,101,101,101,173,101,101,175,176,179,180,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,243,244,245,246,101,101,251,252,101,101,257,258,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'INHERITS':([8,9,],[11,13,]),'ID':([10,12,15,16,21,26,30,34,35,39,43,44,51,57,61,64,65,69,71,72,73,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,101,102,103,104,105,106,113,114,115,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,153,154,155,156,157,164,165,167,173,174,176,179,180,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,234,235,236,239,240,241,242,244,245,246,249,251,252,254,255,258,259,260,261,262,263,264,265,266,267,268,269,272,282,284,286,293,301,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,332,333,334,335,339,340,341,342,347,350,354,358,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,389,390,391,409,412,414,416,417,418,419,420,421,422,423,],[18,18,18,18,18,18,49,49,18,18,-23,-21,-22,18,18,86,86,49,-19,86,86,86,-29,-187,-126,-157,-166,-174,86,155,155,155,86,86,161,86,-182,86,-188,-189,-190,86,-24,86,86,-25,86,86,155,155,155,155,155,155,155,203,86,86,86,155,155,155,155,155,155,155,203,-175,86,-187,-176,-177,-183,-184,86,86,-20,86,86,86,-128,-168,86,-132,86,-135,86,-138,86,-147,86,-148,86,-153,86,-156,-173,-172,86,-117,-125,86,-115,86,-129,86,-130,86,-131,86,-141,86,-142,86,-143,86,-144,86,-170,-171,-167,-169,86,86,86,278,-185,-186,86,86,86,86,86,86,86,86,86,86,203,203,86,-120,86,-119,86,-116,-118,203,203,-180,86,86,86,86,-165,-162,-163,-159,86,-158,-161,-164,-160,86,-179,86,161,86,161,86,161,86,161,-181,-44,-50,-48,-49,-32,-46,-47,-45,86,86,86,86,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,161,161,161,161,161,161,161,161,86,86,86,86,86,86,86,278,278,278,278,278,278,278,278,]),'CCURL':([10,12,14,15,16,17,21,22,26,28,31,35,39,43,44,51,56,57,58,61,62,63,71,84,85,86,87,88,89,90,99,102,103,104,105,106,113,114,115,153,155,156,157,164,165,166,167,174,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,242,247,248,249,250,253,254,255,256,262,264,266,267,272,280,281,282,283,284,285,286,287,292,293,294,299,300,301,302,303,304,308,309,310,311,313,322,332,333,334,335,339,340,341,342,366,367,368,369,370,371,372,373,374,375,376,377,378,],[-1,-1,25,27,-1,-17,37,38,-1,-18,-16,-1,-1,-23,-21,-22,78,79,80,81,82,83,-19,-30,-29,-187,-126,-157,-166,-174,-182,-188,-189,-190,-28,-24,-26,-27,-25,-175,-187,-176,-177,-183,-184,240,241,-20,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-54,288,289,290,291,295,296,297,298,-120,-119,-116,-118,-180,-55,325,326,327,328,329,330,331,336,337,338,343,344,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-178,]),'COLON':([15,18,21,26,47,49,52,54,57,61,66,67,75,77,161,162,278,279,349,352,356,360,393,394,396,398,400,402,404,406,425,427,429,431,433,435,437,],[29,32,29,29,68,70,74,76,29,29,107,108,118,121,237,238,323,324,238,238,238,238,238,238,238,238,238,238,238,238,324,324,324,324,324,324,324,]),'OPAR':([15,18,21,26,57,61,64,65,72,73,84,86,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,155,167,173,176,179,180,185,187,189,191,193,195,197,201,203,204,209,212,215,217,219,221,223,225,227,231,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,301,303,305,309,310,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[30,34,30,30,30,30,91,91,91,91,140,142,91,91,91,91,91,91,91,91,140,140,140,140,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,140,142,140,91,91,91,91,140,140,140,140,140,140,140,261,142,140,140,140,140,140,140,140,140,140,140,261,91,91,91,91,91,91,91,140,91,91,140,140,91,91,91,91,140,140,140,140,261,261,140,261,261,91,91,91,91,91,140,140,140,140,91,91,91,91,140,140,140,]),'SEMI':([25,27,37,38,50,78,79,80,81,82,83,86,87,88,89,90,99,102,103,104,112,153,155,156,157,164,165,168,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,288,289,290,291,295,296,297,298,301,302,303,304,308,309,310,311,313,322,325,326,327,328,329,330,331,336,337,338,343,344,378,408,409,410,411,412,413,414,415,],[41,42,59,60,71,122,123,124,125,126,127,-187,-126,-157,-166,-174,-182,-188,-189,-190,174,-175,-187,-176,-177,-183,-184,242,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,332,333,334,335,339,340,341,342,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,366,367,368,369,370,371,372,373,374,375,376,377,-178,416,417,418,419,420,421,422,423,]),'CPAR':([30,33,34,45,46,48,53,55,86,87,88,89,90,99,102,103,104,110,111,130,140,142,152,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,261,262,264,266,267,272,301,302,303,304,305,306,307,308,309,310,311,313,322,378,],[47,52,54,66,67,-51,75,77,-187,-126,-157,-166,-174,-182,-188,-189,-190,-52,-53,184,205,210,232,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,262,-117,264,232,-125,-127,-115,266,267,-121,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,205,-120,-119,-116,-118,-180,-165,-162,-163,-159,-123,-124,-122,-158,-161,-164,-160,-179,-181,-178,]),'ASSIGN':([43,44,50,51,84,86,105,113,114,128,167,204,209,212,249,254,255,273,274,275,276,282,284,286,293,305,347,350,354,358,409,412,414,],[64,65,72,73,129,141,129,129,129,129,129,129,129,129,129,129,129,314,316,318,320,129,129,129,129,129,129,129,129,129,129,129,129,]),'COMMA':([48,86,87,88,89,90,99,102,103,104,111,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,207,208,209,210,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,273,274,275,276,301,302,303,304,305,308,309,310,311,313,322,346,347,350,351,354,355,358,359,378,],[69,-187,-126,-157,-166,-174,-182,-188,-189,-190,-53,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,263,-117,265,-125,-127,-115,263,265,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,315,317,319,321,-165,-162,-163,-159,263,-158,-161,-164,-160,-179,-181,379,380,381,382,383,384,385,386,-178,]),'INT_COMPLEMENT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'NOT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,]),'ISVOID':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,]),'IF':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'WHILE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,]),'LET':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'CASE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'NEW':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'INTEGER':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,]),'STRING':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'BOOL':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'LESSEQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[131,-187,143,-157,-166,-174,-182,-188,-189,-190,131,131,131,131,-175,-187,-176,-177,-183,-184,131,-128,-168,131,143,131,143,131,143,131,-147,131,-148,131,-153,131,-156,-173,-172,131,-117,-125,131,-115,131,143,131,143,131,143,131,-141,131,-142,131,-143,131,-144,131,-170,-171,-167,-169,-185,-186,131,131,131,-120,-119,-116,-118,-180,131,131,131,131,-165,-162,-163,-159,131,-158,-161,-164,-160,-179,-181,131,131,131,131,-178,131,131,131,]),'LESS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[132,-187,144,-157,-166,-174,-182,-188,-189,-190,132,132,132,132,-175,-187,-176,-177,-183,-184,132,-128,-168,132,144,132,144,132,144,132,-147,132,-148,132,-153,132,-156,-173,-172,132,-117,-125,132,-115,132,144,132,144,132,144,132,-141,132,-142,132,-143,132,-144,132,-170,-171,-167,-169,-185,-186,132,132,132,-120,-119,-116,-118,-180,132,132,132,132,-165,-162,-163,-159,132,-158,-161,-164,-160,-179,-181,132,132,132,132,-178,132,132,132,]),'EQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[133,-187,145,-157,-166,-174,-182,-188,-189,-190,133,133,133,133,-175,-187,-176,-177,-183,-184,133,-128,-168,133,145,133,145,133,145,133,-147,133,-148,133,-153,133,-156,-173,-172,133,-117,-125,133,-115,133,145,133,145,133,145,133,-141,133,-142,133,-143,133,-144,133,-170,-171,-167,-169,-185,-186,133,133,133,-120,-119,-116,-118,-180,133,133,133,133,-165,-162,-163,-159,133,-158,-161,-164,-160,-179,-181,133,133,133,133,-178,133,133,133,]),'PLUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[134,-187,146,-157,-166,-174,-182,-188,-189,-190,134,134,134,134,-175,-187,-176,-177,-183,-184,134,-128,-168,134,146,134,146,134,146,134,-147,134,-148,134,-153,134,-156,-173,-172,134,-117,-125,134,-115,134,146,134,146,134,146,134,-141,134,-142,134,-143,134,-144,134,-170,-171,-167,-169,-185,-186,134,134,134,-120,-119,-116,-118,-180,134,134,134,134,-165,-162,-163,-159,134,-158,-161,-164,-160,-179,-181,134,134,134,134,-178,134,134,134,]),'MINUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[135,-187,147,-157,-166,-174,-182,-188,-189,-190,135,135,135,135,-175,-187,-176,-177,-183,-184,135,-128,-168,135,147,135,147,135,147,135,-147,135,-148,135,-153,135,-156,-173,-172,135,-117,-125,135,-115,135,147,135,147,135,147,135,-141,135,-142,135,-143,135,-144,135,-170,-171,-167,-169,-185,-186,135,135,135,-120,-119,-116,-118,-180,135,135,135,135,-165,-162,-163,-159,135,-158,-161,-164,-160,-179,-181,135,135,135,135,-178,135,135,135,]),'STAR':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[136,-187,148,-157,-166,-174,-182,-188,-189,-190,136,136,136,136,-175,-187,-176,-177,-183,-184,136,-128,-168,136,148,136,148,136,148,136,148,136,148,136,-153,136,-156,-173,-172,136,-117,-125,136,-115,136,148,136,148,136,148,136,148,136,148,136,-143,136,-144,136,-170,-171,-167,-169,-185,-186,136,136,136,-120,-119,-116,-118,-180,136,136,136,136,-165,-162,-163,-159,136,-158,-161,-164,-160,-179,-181,136,136,136,136,-178,136,136,136,]),'DIV':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[137,-187,149,-157,-166,-174,-182,-188,-189,-190,137,137,137,137,-175,-187,-176,-177,-183,-184,137,-128,-168,137,149,137,149,137,149,137,149,137,149,137,-153,137,-156,-173,-172,137,-117,-125,137,-115,137,149,137,149,137,149,137,149,137,149,137,-143,137,-144,137,-170,-171,-167,-169,-185,-186,137,137,137,-120,-119,-116,-118,-180,137,137,137,137,-165,-162,-163,-159,137,-158,-161,-164,-160,-179,-181,137,137,137,137,-178,137,137,137,]),'AT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[138,-187,-126,-157,150,-174,-182,-188,-189,-190,138,138,138,138,-175,138,-187,-176,-177,-183,-184,138,-128,-168,138,-132,138,-135,138,-138,138,-147,138,-148,138,-153,138,-156,-173,-172,138,-117,-125,138,-115,138,-129,138,-130,138,-131,138,-141,138,-142,138,-143,138,-144,138,-170,-171,-167,-169,-185,-186,138,138,138,-120,-119,-116,-118,-180,138,138,138,138,-165,-162,-163,-159,138,-158,-161,-164,-160,-179,-181,138,138,138,138,-178,138,138,138,]),'DOT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,164,165,167,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,204,205,208,209,210,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,240,241,249,254,255,262,264,266,267,272,282,284,286,293,301,302,303,304,305,308,309,310,311,313,322,347,350,354,358,378,409,412,414,],[139,-187,-126,-157,151,-174,-182,-188,-189,-190,139,139,139,139,-175,139,-187,-176,-177,-183,-184,139,-128,-168,139,-132,139,-135,139,-138,139,-147,139,-148,139,-153,139,-156,259,260,-173,-172,139,-117,-125,139,-115,139,-129,139,-130,139,-131,139,-141,139,-142,139,-143,139,-144,139,268,269,-170,-171,-167,-169,-185,-186,139,139,139,-120,-119,-116,-118,-180,139,139,139,139,-165,-162,-163,-159,139,-158,-161,-164,-160,-179,-181,139,139,139,139,-178,139,139,139,]),'THEN':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,234,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'LOOP':([86,87,88,89,90,99,102,103,104,153,155,156,157,159,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,235,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'OF':([86,87,88,89,90,99,102,103,104,153,155,156,157,163,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,239,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'ELSE':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,270,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,312,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'POOL':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,271,272,301,302,303,304,308,309,310,311,313,322,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,313,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-178,]),'FI':([86,87,88,89,90,99,102,103,104,153,155,156,157,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,301,302,303,304,308,309,310,311,313,322,345,378,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,378,-178,]),'IN':([86,87,88,89,90,99,102,103,104,153,155,156,157,160,164,165,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,201,202,205,208,209,210,214,215,216,217,218,219,220,221,222,223,224,225,226,227,230,231,232,233,240,241,262,264,266,267,272,273,274,275,276,301,302,303,304,308,309,310,311,313,322,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,378,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,],[-187,-126,-157,-166,-174,-182,-188,-189,-190,-175,-187,-176,-177,236,-183,-184,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-185,-186,-120,-119,-116,-118,-180,-56,-61,-62,-60,-165,-162,-163,-159,-158,-161,-164,-160,-179,-181,-57,-65,-58,-72,-66,-64,-73,-71,-69,-67,-76,-74,-68,-63,-75,-70,-178,-59,-84,-80,-88,-78,-86,-82,-90,-77,-85,-81,-89,-79,-87,-83,-91,]),'ESAC':([277,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,],[322,-92,-96,-97,-95,-100,-98,-99,-94,-93,-109,-103,-111,-104,-110,-102,-114,-107,-112,-105,-113,-106,-108,-101,]),'ACTION':([362,363,364,365,],[387,389,390,391,]),} +_lr_action_items = {'error':([0,3,4,5,10,11,12,13,15,16,18,21,26,29,30,32,34,35,36,39,40,41,42,43,44,51,57,59,60,61,64,65,71,72,73,74,76,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,113,114,115,118,121,122,123,124,125,126,127,128,129,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,165,166,168,174,175,176,177,180,181,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,208,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,250,252,253,255,256,258,259,260,261,262,263,264,265,266,267,268,269,270,273,283,285,287,294,302,303,304,305,306,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,333,334,335,336,340,341,342,343,348,351,355,359,363,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,410,413,415,417,418,419,420,421,422,423,424,],[4,4,4,9,15,20,21,23,26,26,33,26,26,43,45,51,55,57,58,61,63,-6,-9,-23,-21,-22,26,-10,-8,26,84,105,-19,113,114,116,120,128,-29,-188,-126,-157,-166,-174,128,154,157,154,128,128,163,128,-183,166,168,-189,-190,-191,128,-24,170,172,128,128,-25,179,182,-7,-11,-12,-15,-14,-13,128,128,186,188,190,192,194,196,198,200,202,205,210,213,216,218,220,222,224,226,228,230,232,234,-175,128,-188,-176,128,-177,-184,-185,128,128,-20,249,250,255,256,-128,-168,128,-132,128,-135,128,-138,128,-147,128,-148,128,-153,128,-156,-173,-172,128,-117,234,-125,128,-115,128,-129,128,-130,128,-131,128,-141,128,-142,128,-143,128,-144,128,-170,-171,-167,-169,128,128,128,275,276,280,-186,-187,128,282,283,285,287,128,294,128,128,128,300,128,302,304,205,-120,306,-119,306,-116,-118,310,311,-181,128,128,128,128,-165,-162,-163,-159,128,-158,-161,-164,-160,128,-180,348,350,351,353,355,357,359,361,-182,364,365,-44,-50,-48,-49,-32,-46,-47,-45,128,128,128,128,389,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-179,394,395,397,399,401,403,405,407,410,411,128,413,415,128,128,128,426,280,428,430,432,434,436,438,]),'CLASS':([0,3,4,41,42,59,60,122,123,124,125,126,127,],[5,5,5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'$end':([1,2,3,6,7,41,42,59,60,122,123,124,125,126,127,],[0,-2,-4,-3,-5,-6,-9,-10,-8,-7,-11,-12,-15,-14,-13,]),'TYPE':([5,11,13,29,32,68,70,74,76,100,107,108,118,121,138,150,238,239,324,325,],[8,19,24,44,50,109,111,117,119,165,171,173,178,183,201,229,274,277,363,366,]),'OCURL':([8,9,19,20,23,24,64,65,72,73,84,91,92,93,94,95,96,98,101,105,109,113,114,116,117,119,120,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,170,171,172,173,174,177,178,179,180,181,182,183,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[10,12,35,36,39,40,101,101,101,101,101,101,101,101,101,101,101,101,101,101,174,101,101,176,177,180,181,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,244,245,246,247,101,101,252,253,101,101,258,259,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,]),'INHERITS':([8,9,],[11,13,]),'ID':([10,12,15,16,21,26,30,34,35,39,43,44,51,57,61,64,65,69,71,72,73,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,101,102,103,104,105,106,113,114,115,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,153,154,155,156,157,158,165,166,168,174,175,177,180,181,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,235,236,237,240,241,242,243,245,246,247,250,252,253,255,256,259,260,261,262,263,264,265,266,267,268,269,270,273,283,285,287,294,302,303,304,305,306,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,333,334,335,336,340,341,342,343,348,351,355,359,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,390,391,392,410,413,415,417,418,419,420,421,422,423,424,],[18,18,18,18,18,18,49,49,18,18,-23,-21,-22,18,18,86,86,49,-19,86,86,86,-29,-188,-126,-157,-166,-174,86,155,155,155,86,86,162,86,-183,86,-189,-190,-191,86,-24,86,86,-25,86,86,155,155,155,155,155,155,155,204,86,86,86,155,155,155,155,155,155,155,204,-175,86,-188,-176,86,-177,-184,-185,86,86,-20,86,86,86,-128,-168,86,-132,86,-135,86,-138,86,-147,86,-148,86,-153,86,-156,-173,-172,86,-117,-125,86,-115,86,-129,86,-130,86,-131,86,-141,86,-142,86,-143,86,-144,86,-170,-171,-167,-169,86,86,86,279,-186,-187,86,86,86,86,86,86,86,86,86,86,204,204,86,-120,86,-119,86,-116,-118,204,204,-181,86,86,86,86,-165,-162,-163,-159,86,-158,-161,-164,-160,86,-180,86,162,86,162,86,162,86,162,-182,-44,-50,-48,-49,-32,-46,-47,-45,86,86,86,86,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-179,162,162,162,162,162,162,162,162,86,86,86,86,86,86,86,279,279,279,279,279,279,279,279,]),'CCURL':([10,12,14,15,16,17,21,22,26,28,31,35,39,43,44,51,56,57,58,61,62,63,71,84,85,86,87,88,89,90,99,102,103,104,105,106,113,114,115,153,155,156,157,158,165,166,167,168,175,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,243,248,249,250,251,254,255,256,257,263,265,267,268,273,281,282,283,284,285,286,287,288,293,294,295,300,301,302,303,304,305,309,310,311,312,314,323,333,334,335,336,340,341,342,343,367,368,369,370,371,372,373,374,375,376,377,378,379,],[-1,-1,25,27,-1,-17,37,38,-1,-18,-16,-1,-1,-23,-21,-22,78,79,80,81,82,83,-19,-30,-29,-188,-126,-157,-166,-174,-183,-189,-190,-191,-28,-24,-26,-27,-25,-175,-188,-176,-178,-177,-184,-185,241,242,-20,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-54,289,290,291,292,296,297,298,299,-120,-119,-116,-118,-181,-55,326,327,328,329,330,331,332,337,338,339,344,345,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-44,-50,-48,-49,-32,-46,-47,-45,-42,-41,-37,-43,-38,-39,-33,-31,-36,-35,-40,-34,-179,]),'COLON':([15,18,21,26,47,49,52,54,57,61,66,67,75,77,162,163,279,280,350,353,357,361,394,395,397,399,401,403,405,407,426,428,430,432,434,436,438,],[29,32,29,29,68,70,74,76,29,29,107,108,118,121,238,239,324,325,239,239,239,239,239,239,239,239,239,239,239,239,325,325,325,325,325,325,325,]),'OPAR':([15,18,21,26,57,61,64,65,72,73,84,86,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,155,157,168,174,177,180,181,186,188,190,192,194,196,198,202,204,205,210,213,216,218,220,222,224,226,228,232,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,302,304,306,310,311,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[30,34,30,30,30,30,91,91,91,91,140,142,91,91,91,91,91,91,91,91,140,140,140,140,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,140,142,140,140,91,91,91,91,140,140,140,140,140,140,140,262,142,140,140,140,140,140,140,140,140,140,140,262,91,91,91,91,91,91,91,140,91,91,140,140,91,91,91,91,140,140,140,140,262,262,140,262,262,91,91,91,91,91,140,140,140,140,91,91,91,91,140,140,140,]),'SEMI':([25,27,37,38,50,78,79,80,81,82,83,86,87,88,89,90,99,102,103,104,112,153,155,156,157,158,165,166,169,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,289,290,291,292,296,297,298,299,302,303,304,305,309,310,311,312,314,323,326,327,328,329,330,331,332,337,338,339,344,345,379,409,410,411,412,413,414,415,416,],[41,42,59,60,71,122,123,124,125,126,127,-188,-126,-157,-166,-174,-183,-189,-190,-191,175,-175,-188,-176,-178,-177,-184,-185,243,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,333,334,335,336,340,341,342,343,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,367,368,369,370,371,372,373,374,375,376,377,378,-179,417,418,419,420,421,422,423,424,]),'CPAR':([30,33,34,45,46,48,53,55,86,87,88,89,90,99,102,103,104,110,111,130,140,142,152,153,155,156,157,158,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,262,263,265,267,268,273,302,303,304,305,306,307,308,309,310,311,312,314,323,379,],[47,52,54,66,67,-51,75,77,-188,-126,-157,-166,-174,-183,-189,-190,-191,-52,-53,185,206,211,233,-175,-188,-176,-178,-177,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,263,-117,265,233,-125,-127,-115,267,268,-121,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,206,-120,-119,-116,-118,-181,-165,-162,-163,-159,-123,-124,-122,-158,-161,-164,-160,-180,-182,-179,]),'ASSIGN':([43,44,50,51,84,86,105,113,114,128,168,205,210,213,250,255,256,274,275,276,277,283,285,287,294,306,348,351,355,359,410,413,415,],[64,65,72,73,129,141,129,129,129,129,129,129,129,129,129,129,129,315,317,319,321,129,129,129,129,129,129,129,129,129,129,129,129,]),'COMMA':([48,86,87,88,89,90,99,102,103,104,111,153,155,156,157,158,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,208,209,210,211,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,274,275,276,277,302,303,304,305,306,309,310,311,312,314,323,347,348,351,352,355,356,359,360,379,],[69,-188,-126,-157,-166,-174,-183,-189,-190,-191,-53,-175,-188,-176,-178,-177,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,264,-117,266,-125,-127,-115,264,266,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,316,318,320,322,-165,-162,-163,-159,264,-158,-161,-164,-160,-180,-182,380,381,382,383,384,385,386,387,-179,]),'INT_COMPLEMENT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'NOT':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,]),'ISVOID':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,]),'IF':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,]),'WHILE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,]),'LET':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'CASE':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,]),'NEW':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,]),'INTEGER':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,]),'STRING':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,]),'BOOL':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'LESSEQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[131,-188,143,-157,-166,-174,-183,-189,-190,-191,131,131,131,131,-175,-188,143,131,-177,-184,-185,131,-128,-168,131,143,131,143,131,143,131,-147,131,-148,131,-153,131,-156,-173,-172,131,-117,-125,131,-115,131,143,131,143,131,143,131,-141,131,-142,131,-143,131,-144,131,-170,-171,-167,-169,-186,-187,131,131,131,-120,-119,-116,-118,-181,131,131,131,131,-165,-162,-163,-159,131,-158,-161,-164,-160,-180,-182,131,131,131,131,-179,131,131,131,]),'LESS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[132,-188,144,-157,-166,-174,-183,-189,-190,-191,132,132,132,132,-175,-188,144,132,-177,-184,-185,132,-128,-168,132,144,132,144,132,144,132,-147,132,-148,132,-153,132,-156,-173,-172,132,-117,-125,132,-115,132,144,132,144,132,144,132,-141,132,-142,132,-143,132,-144,132,-170,-171,-167,-169,-186,-187,132,132,132,-120,-119,-116,-118,-181,132,132,132,132,-165,-162,-163,-159,132,-158,-161,-164,-160,-180,-182,132,132,132,132,-179,132,132,132,]),'EQUAL':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[133,-188,145,-157,-166,-174,-183,-189,-190,-191,133,133,133,133,-175,-188,145,133,-177,-184,-185,133,-128,-168,133,145,133,145,133,145,133,-147,133,-148,133,-153,133,-156,-173,-172,133,-117,-125,133,-115,133,145,133,145,133,145,133,-141,133,-142,133,-143,133,-144,133,-170,-171,-167,-169,-186,-187,133,133,133,-120,-119,-116,-118,-181,133,133,133,133,-165,-162,-163,-159,133,-158,-161,-164,-160,-180,-182,133,133,133,133,-179,133,133,133,]),'PLUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[134,-188,146,-157,-166,-174,-183,-189,-190,-191,134,134,134,134,-175,-188,146,134,-177,-184,-185,134,-128,-168,134,146,134,146,134,146,134,-147,134,-148,134,-153,134,-156,-173,-172,134,-117,-125,134,-115,134,146,134,146,134,146,134,-141,134,-142,134,-143,134,-144,134,-170,-171,-167,-169,-186,-187,134,134,134,-120,-119,-116,-118,-181,134,134,134,134,-165,-162,-163,-159,134,-158,-161,-164,-160,-180,-182,134,134,134,134,-179,134,134,134,]),'MINUS':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[135,-188,147,-157,-166,-174,-183,-189,-190,-191,135,135,135,135,-175,-188,147,135,-177,-184,-185,135,-128,-168,135,147,135,147,135,147,135,-147,135,-148,135,-153,135,-156,-173,-172,135,-117,-125,135,-115,135,147,135,147,135,147,135,-141,135,-142,135,-143,135,-144,135,-170,-171,-167,-169,-186,-187,135,135,135,-120,-119,-116,-118,-181,135,135,135,135,-165,-162,-163,-159,135,-158,-161,-164,-160,-180,-182,135,135,135,135,-179,135,135,135,]),'STAR':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[136,-188,148,-157,-166,-174,-183,-189,-190,-191,136,136,136,136,-175,-188,148,136,-177,-184,-185,136,-128,-168,136,148,136,148,136,148,136,148,136,148,136,-153,136,-156,-173,-172,136,-117,-125,136,-115,136,148,136,148,136,148,136,148,136,148,136,-143,136,-144,136,-170,-171,-167,-169,-186,-187,136,136,136,-120,-119,-116,-118,-181,136,136,136,136,-165,-162,-163,-159,136,-158,-161,-164,-160,-180,-182,136,136,136,136,-179,136,136,136,]),'DIV':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[137,-188,149,-157,-166,-174,-183,-189,-190,-191,137,137,137,137,-175,-188,149,137,-177,-184,-185,137,-128,-168,137,149,137,149,137,149,137,149,137,149,137,-153,137,-156,-173,-172,137,-117,-125,137,-115,137,149,137,149,137,149,137,149,137,149,137,-143,137,-144,137,-170,-171,-167,-169,-186,-187,137,137,137,-120,-119,-116,-118,-181,137,137,137,137,-165,-162,-163,-159,137,-158,-161,-164,-160,-180,-182,137,137,137,137,-179,137,137,137,]),'AT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[138,-188,-126,-157,150,-174,-183,-189,-190,-191,138,138,138,138,-175,138,-188,-176,138,-177,-184,-185,138,-128,-168,138,-132,138,-135,138,-138,138,-147,138,-148,138,-153,138,-156,-173,-172,138,-117,-125,138,-115,138,-129,138,-130,138,-131,138,-141,138,-142,138,-143,138,-144,138,-170,-171,-167,-169,-186,-187,138,138,138,-120,-119,-116,-118,-181,138,138,138,138,-165,-162,-163,-159,138,-158,-161,-164,-160,-180,-182,138,138,138,138,-179,138,138,138,]),'DOT':([84,86,87,88,89,90,99,102,103,104,105,113,114,128,153,154,155,156,157,158,165,166,168,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,209,210,211,213,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,241,242,250,255,256,263,265,267,268,273,283,285,287,294,302,303,304,305,306,309,310,311,312,314,323,348,351,355,359,379,410,413,415,],[139,-188,-126,-157,151,-174,-183,-189,-190,-191,139,139,139,139,-175,139,-188,-176,139,-177,-184,-185,139,-128,-168,139,-132,139,-135,139,-138,139,-147,139,-148,139,-153,139,-156,260,261,-173,-172,139,-117,-125,139,-115,139,-129,139,-130,139,-131,139,-141,139,-142,139,-143,139,-144,139,269,270,-170,-171,-167,-169,-186,-187,139,139,139,-120,-119,-116,-118,-181,139,139,139,139,-165,-162,-163,-159,139,-158,-161,-164,-160,-180,-182,139,139,139,139,-179,139,139,139,]),'THEN':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,159,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,302,303,304,305,309,310,311,312,314,323,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,235,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-179,]),'LOOP':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,160,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,302,303,304,305,309,310,311,312,314,323,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,236,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-179,]),'OF':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,164,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,302,303,304,305,309,310,311,312,314,323,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,240,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-179,]),'ELSE':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,271,273,302,303,304,305,309,310,311,312,314,323,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,313,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-179,]),'POOL':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,272,273,302,303,304,305,309,310,311,312,314,323,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,314,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-179,]),'FI':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,302,303,304,305,309,310,311,312,314,323,346,379,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,379,-179,]),'IN':([86,87,88,89,90,99,102,103,104,153,155,156,157,158,161,165,166,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,202,203,206,209,210,211,215,216,217,218,219,220,221,222,223,224,225,226,227,228,231,232,233,234,241,242,263,265,267,268,273,274,275,276,277,302,303,304,305,309,310,311,312,314,323,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,379,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,],[-188,-126,-157,-166,-174,-183,-189,-190,-191,-175,-188,-176,-178,-177,237,-184,-185,-128,-168,-133,-132,-136,-135,-139,-138,-146,-147,-149,-148,-152,-153,-155,-156,-173,-172,-117,-125,-127,-115,-129,-134,-130,-137,-131,-140,-141,-145,-142,-150,-143,-151,-144,-154,-170,-171,-167,-169,-186,-187,-120,-119,-116,-118,-181,-56,-61,-62,-60,-165,-162,-163,-159,-158,-161,-164,-160,-180,-182,-57,-65,-58,-72,-66,-64,-73,-71,-69,-67,-76,-74,-68,-63,-75,-70,-179,-59,-84,-80,-88,-78,-86,-82,-90,-77,-85,-81,-89,-79,-87,-83,-91,]),'ESAC':([278,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,],[323,-92,-96,-97,-95,-100,-98,-99,-94,-93,-109,-103,-111,-104,-110,-102,-114,-107,-112,-105,-113,-106,-108,-101,]),'ACTION':([363,364,365,366,],[388,390,391,392,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): @@ -17,7 +17,7 @@ _lr_action[_x][_k] = _y del _lr_action_items -_lr_goto_items = {'program':([0,],[1,]),'class_list':([0,3,4,],[2,6,7,]),'def_class':([0,3,4,],[3,3,3,]),'feature_list':([10,12,15,16,21,26,35,39,57,61,],[14,22,28,31,28,28,56,62,28,28,]),'feature':([10,12,15,16,21,26,35,39,57,61,],[16,16,16,16,16,16,16,16,16,16,]),'epsilon':([10,12,15,16,21,26,35,39,57,61,],[17,17,17,17,17,17,17,17,17,17,]),'param_list':([30,34,69,],[46,53,110,]),'param':([30,34,69,],[48,48,48,]),'expr':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,140,141,142,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[85,106,112,115,130,152,158,159,163,168,130,130,130,130,183,207,208,213,130,130,247,250,253,256,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,270,271,272,168,283,285,287,130,292,294,130,130,300,213,213,213,130,130,130,130,130,345,346,351,355,359,130,130,130,130,408,411,413,415,130,130,130,]),'operat':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,186,188,190,192,194,196,198,87,87,87,214,216,218,220,222,224,226,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'baseop':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[88,88,88,88,88,88,153,156,157,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,]),'subatom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,]),'funccall':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,259,260,261,263,265,268,269,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,202,90,90,90,90,90,90,90,90,90,90,230,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,302,304,90,90,90,308,311,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'atom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,167,173,176,179,180,185,187,189,191,193,195,197,204,209,212,215,217,219,221,223,225,227,234,235,236,242,244,245,246,249,251,252,254,255,258,261,263,265,282,284,286,293,305,312,314,316,318,320,347,350,354,358,387,389,390,391,409,412,414,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'let_list':([97,315,317,319,321,379,380,381,382,383,384,385,386,],[160,348,353,357,361,392,395,397,399,401,403,405,407,]),'expr_block':([101,242,],[166,280,]),'arg_list':([140,142,261,263,265,],[206,211,206,306,307,]),'case_list':([239,416,417,418,419,420,421,422,423,],[277,424,426,428,430,432,434,436,438,]),} +_lr_goto_items = {'program':([0,],[1,]),'class_list':([0,3,4,],[2,6,7,]),'def_class':([0,3,4,],[3,3,3,]),'feature_list':([10,12,15,16,21,26,35,39,57,61,],[14,22,28,31,28,28,56,62,28,28,]),'feature':([10,12,15,16,21,26,35,39,57,61,],[16,16,16,16,16,16,16,16,16,16,]),'epsilon':([10,12,15,16,21,26,35,39,57,61,],[17,17,17,17,17,17,17,17,17,17,]),'param_list':([30,34,69,],[46,53,110,]),'param':([30,34,69,],[48,48,48,]),'expr':([64,65,72,73,84,91,95,96,98,101,105,113,114,128,129,140,141,142,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[85,106,112,115,130,152,159,160,164,169,130,130,130,130,184,208,209,214,130,130,130,248,251,254,257,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,271,272,273,169,284,286,288,130,293,295,130,130,301,214,214,214,130,130,130,130,130,346,347,352,356,360,130,130,130,130,409,412,414,416,130,130,130,]),'operat':([64,65,72,73,84,91,93,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[87,87,87,87,87,87,156,87,87,87,87,87,87,87,87,87,187,189,191,193,195,197,199,87,87,87,215,217,219,221,223,225,227,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'baseop':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[88,88,88,88,88,88,153,88,158,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,]),'subatom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,]),'funccall':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,139,140,141,142,143,144,145,146,147,148,149,151,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,260,261,262,264,266,269,270,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,203,90,90,90,90,90,90,90,90,90,90,231,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,303,305,90,90,90,309,312,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'atom':([64,65,72,73,84,91,92,93,94,95,96,98,101,105,113,114,128,129,131,132,133,134,135,136,137,140,141,142,143,144,145,146,147,148,149,154,157,168,174,177,180,181,186,188,190,192,194,196,198,205,210,213,216,218,220,222,224,226,228,235,236,237,243,245,246,247,250,252,253,255,256,259,262,264,266,283,285,287,294,306,313,315,317,319,321,348,351,355,359,388,390,391,392,410,413,415,],[99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'let_list':([97,316,318,320,322,380,381,382,383,384,385,386,387,],[161,349,354,358,362,393,396,398,400,402,404,406,408,]),'expr_block':([101,243,],[167,281,]),'arg_list':([140,142,262,264,266,],[207,212,207,307,308,]),'case_list':([240,417,418,419,420,421,422,423,424,],[278,425,427,429,431,433,435,437,439,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): @@ -202,19 +202,20 @@ ('subatom -> error DOT error','subatom',3,'p_dynamic_call_error','cool_parser.py',382), ('subatom -> funccall','subatom',1,'p_member_call','cool_parser.py',386), ('subatom -> INT_COMPLEMENT baseop','subatom',2,'p_unary_operations','cool_parser.py',390), - ('subatom -> NOT baseop','subatom',2,'p_unary_operations','cool_parser.py',391), + ('subatom -> NOT operat','subatom',2,'p_unary_operations','cool_parser.py',391), ('subatom -> ISVOID baseop','subatom',2,'p_unary_operations','cool_parser.py',392), - ('subatom -> IF expr THEN expr ELSE expr FI','subatom',7,'p_complex_sub_atom','cool_parser.py',407), - ('subatom -> WHILE expr LOOP expr POOL','subatom',5,'p_complex_sub_atom','cool_parser.py',408), - ('subatom -> LET let_list IN expr','subatom',4,'p_complex_sub_atom','cool_parser.py',409), - ('subatom -> CASE expr OF case_list ESAC','subatom',5,'p_complex_sub_atom','cool_parser.py',410), - ('subatom -> atom','subatom',1,'p_atom','cool_parser.py',424), - ('atom -> NEW TYPE','atom',2,'p_new','cool_parser.py',428), - ('atom -> NEW error','atom',2,'p_new_error','cool_parser.py',432), - ('atom -> OCURL expr_block CCURL','atom',3,'p_atom_expr_block','cool_parser.py',436), - ('atom -> OCURL error CCURL','atom',3,'p_atom_expr_block_error','cool_parser.py',440), - ('atom -> ID','atom',1,'p_atom_id','cool_parser.py',444), - ('atom -> INTEGER','atom',1,'p_atom_integer','cool_parser.py',448), - ('atom -> STRING','atom',1,'p_atom_string','cool_parser.py',452), - ('atom -> BOOL','atom',1,'p_atom_bool','cool_parser.py',456), + ('subatom -> NOT error','subatom',2,'p_unary_operations_error','cool_parser.py',401), + ('subatom -> IF expr THEN expr ELSE expr FI','subatom',7,'p_complex_sub_atom','cool_parser.py',405), + ('subatom -> WHILE expr LOOP expr POOL','subatom',5,'p_complex_sub_atom','cool_parser.py',406), + ('subatom -> LET let_list IN expr','subatom',4,'p_complex_sub_atom','cool_parser.py',407), + ('subatom -> CASE expr OF case_list ESAC','subatom',5,'p_complex_sub_atom','cool_parser.py',408), + ('subatom -> atom','subatom',1,'p_atom','cool_parser.py',422), + ('atom -> NEW TYPE','atom',2,'p_new','cool_parser.py',426), + ('atom -> NEW error','atom',2,'p_new_error','cool_parser.py',430), + ('atom -> OCURL expr_block CCURL','atom',3,'p_atom_expr_block','cool_parser.py',434), + ('atom -> OCURL error CCURL','atom',3,'p_atom_expr_block_error','cool_parser.py',438), + ('atom -> ID','atom',1,'p_atom_id','cool_parser.py',442), + ('atom -> INTEGER','atom',1,'p_atom_integer','cool_parser.py',446), + ('atom -> STRING','atom',1,'p_atom_string','cool_parser.py',450), + ('atom -> BOOL','atom',1,'p_atom_bool','cool_parser.py',454), ] From 90c00a3f1b0ef47a3d33b301c63139e5501dbf16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 7 Dec 2020 16:20:43 -0500 Subject: [PATCH 084/191] clean main file --- src/main.py | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/main.py b/src/main.py index a1f96345..a76a59ce 100644 --- a/src/main.py +++ b/src/main.py @@ -5,19 +5,11 @@ args = sys.argv -# if len(args) != 3: -# exit(1) - input_file = open(args[1], "r") output_file = open(args[2], 'w') -# input_file = open('./src/test.cl', "r") -# output_file = open('./src/test.mips', 'w') - t = input_file.read() -# output_file = args[2] - lexer = CoolLexer() tokens, errors = lexer.tokenize(t) @@ -50,7 +42,6 @@ collect.visit(ast) if len(collect_errors): - # print("coolector") for e in collect_errors[::-1]: print(e) exit(1) @@ -61,7 +52,6 @@ builder.visit(ast) if len(builder_errors): - # print("builder") for e in builder_errors[::-1]: print(e) exit(1) @@ -72,37 +62,23 @@ scope = checker.visit(ast) if len(checker_errors): - # print("checker") for e in checker_errors[::-1]: print(e) exit(1) cil = COOL_TO_CIL(checker.context) -# cil = COOL_TO_CIL_VISITOR(checker.context) -# sc = Scope() cil_ast = cil.visit(ast) -# f_ast = Format().visit(ast) + emsamb = CIL_TO_MIPS() emsamb.visit(cil_ast) + m_ast = emsamb.mips.compile() -# f_ast = CIL_FORMATTER().visit(cil_ast) + string_formatted = str(m_ast) output_file.write(string_formatted) -# output_file.write(str(collect_errors)) -# print(str(collect_errors)) -# output_file.write(str(builder_errors)) -# output_file.write(str(checker_errors)) -# output_file.write(collect_errors) + input_file.close() output_file.close() - -# if not operations: -# message = f'ERROR at or near "{parse.lex}"' -# print(SyntacticError(parse.line, parse.column, message)) -# exit(1) -# print(parse) - - exit(0) From b74b7a0b1613b4e7d24ae6738425215d3bdba36d Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 7 Dec 2020 16:26:25 -0500 Subject: [PATCH 085/191] empty args node --- src/engine/codegen/cil.py | 40 +++++++++++++++++++++++++++++++++++ src/engine/codegen/cil_ast.py | 5 +++++ src/engine/codegen/to_cil.py | 3 +-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 2d626dc9..61419dea 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -105,6 +105,45 @@ def define_string_type(self): start = self.register_param(VariableInfo('start', None)) length = self.register_param(VariableInfo('length', None)) dest = self.define_internal_local() + result_msg = self.define_internal_local() + length_var = self.define_internal_local() + zero = self.define_internal_local() + sum_var = self.define_internal_local() + cmp_var1 = self.define_internal_local() + cmp_var2 = self.define_internal_local() + cmp_var3 = self.define_internal_local() + no_error_label1 = LabelNode("error1") + no_error_label2 = LabelNode("error2") + no_error_label3 = LabelNode("error3") + self.register_instruction(AssignNode(zero, 0)) + self.register_instruction(LengthNode(length_var, self_param)) + eol = self.register_data('\n').name + msg_eol = self.define_internal_local() + + self.register_instruction(LessEqNode(cmp_var1, zero, start)) + self.register_instruction(IfGotoNode(cmp_var1, no_error_label1.label)) + error_msg = self.register_data("Invalid substring start").name + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + self.register_instruction(PrintStrNode(msg_eol)) + self.register_instruction(ErrorNode()) + self.register_instruction(no_error_label1) + + self.register_instruction(LessEqNode(cmp_var2, zero, length)) + self.register_instruction(IfGotoNode(cmp_var2, no_error_label2.label)) + error_msg = self.register_data("Invalid substring length").name + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + self.register_instruction(PrintStrNode(msg_eol)) + self.register_instruction(ErrorNode()) + self.register_instruction(no_error_label2) + + self.register_instruction(PlusNode(sum_var, start, length)) + self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) + self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) + error_msg = self.register_data("Invalid substring").name + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + self.register_instruction(PrintStrNode(msg_eol)) + self.register_instruction(ErrorNode()) + self.register_instruction(no_error_label3) self.register_instruction(SubstringNode( dest, self_param, start, length)) self.register_instruction(ReturnNode(dest)) @@ -170,6 +209,7 @@ def define_object_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) + self.register_instruction(PrintStrNode('abort with type')) self.register_instruction(ErrorNode()) # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 5a9e73cd..1cf0a8d4 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -70,6 +70,11 @@ def __init__(self, dest, source): self.source = source +class EmptyArgs(InstructionNode): + def __init__(self, args): + self.args = args + + class ArithmeticNode(InstructionNode): def __init__(self, dest, left, right): self.dest = dest diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 7ef04e0f..efc7b7f5 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -50,13 +50,12 @@ def visit(self, node: cool.ProgramNode, scope=None): self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() - self.current_type = 'Main' + self.current_type = self.context.get_type('Main') self.register_instruction(AllocateNode(instance, 'Main')) self.init_class_attr(scope, 'Main', instance) self.register_instruction(ArgNode(instance)) name = self.to_function_name('main', 'Main') self.register_instruction(StaticCallNode(name, result)) - # self.register_instruction(ReturnNode(0)) self.current_function = None classes = [declaration for declaration in node.declarations if isinstance( From b078628bab50a13f05d7a3758737278e58eb3b43 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 9 Dec 2020 10:06:42 -0500 Subject: [PATCH 086/191] start passing codegen test --- src/engine/codegen/cil.py | 17 +- src/engine/codegen/cil_ast.py | 9 +- src/engine/codegen/cil_format.py | 12 +- src/engine/codegen/mips.py | 8 +- src/engine/codegen/to_cil.py | 22 +- src/engine/codegen/to_mips.py | 17 +- src/test.cl | 22 +- src/test.mips | 2731 +++++++++++++++++++++++------- 8 files changed, 2140 insertions(+), 698 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 61419dea..17ace480 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -75,6 +75,7 @@ def define_string_type(self): for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name( method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + type_node.features = type_node.attributes + type_node.methods self.current_method = self.current_type.get_method('length') type_name = self.current_type.name @@ -115,15 +116,19 @@ def define_string_type(self): no_error_label1 = LabelNode("error1") no_error_label2 = LabelNode("error2") no_error_label3 = LabelNode("error3") - self.register_instruction(AssignNode(zero, 0)) + self.register_instruction(BoxNode(zero, 0)) self.register_instruction(LengthNode(length_var, self_param)) eol = self.register_data('\n').name + eol_dest = self.define_internal_local() + self.register_instruction(LoadNode(eol_dest, eol)) msg_eol = self.define_internal_local() self.register_instruction(LessEqNode(cmp_var1, zero, start)) self.register_instruction(IfGotoNode(cmp_var1, no_error_label1.label)) error_msg = self.register_data("Invalid substring start").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + error_dest = self.define_internal_local() + self.register_instruction(LoadNode(error_dest, error_msg)) + self.register_instruction(ConcatNode(msg_eol, error_dest, eol_dest)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label1) @@ -131,7 +136,7 @@ def define_string_type(self): self.register_instruction(LessEqNode(cmp_var2, zero, length)) self.register_instruction(IfGotoNode(cmp_var2, no_error_label2.label)) error_msg = self.register_data("Invalid substring length").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + self.register_instruction(ConcatNode(msg_eol, error_msg, eol_dest)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label2) @@ -140,7 +145,7 @@ def define_string_type(self): self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) error_msg = self.register_data("Invalid substring").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + self.register_instruction(ConcatNode(msg_eol, error_msg, eol_dest)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label3) @@ -158,6 +163,7 @@ def define_io_type(self): for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name( method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + type_node.features = type_node.attributes + type_node.methods self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name @@ -203,13 +209,14 @@ def define_object_type(self): for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name( method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + type_node.features = type_node.attributes + type_node.methods self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) - self.register_instruction(PrintStrNode('abort with type')) + # self.register_instruction(PrintStrNode('abort with type')) self.register_instruction(ErrorNode()) # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 1cf0a8d4..37715191 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -128,6 +128,12 @@ class LessEqNode(ArithmeticNode): pass +class BoxNode(InstructionNode): + def __init__(self, dest, value): + self.dest = dest + self.value = value + + class AllocateNode(InstructionNode): def __init__(self, dest, itype): self.dest = dest @@ -163,7 +169,8 @@ def __init__(self, function, dest): class DynamicCallNode(InstructionNode): - def __init__(self, xtype, method, dest): + def __init__(self, obj, xtype, method, dest): + self.obj = obj self.type = xtype self.method = method self.dest = dest diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index e5c03f40..bf7c4d43 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -107,9 +107,9 @@ def visit(self, node: LengthNode): def visit(self, node: ConcatNode): return f'{node.dest} = CONCAT {node.msg1} {node.msg2}' - # @visitor.when(PrefixNode) - # def visit(self, node: PrefixNode): - # return f'{node.dest} = PREFIX {node.msg1} {node.msg2}' + @visitor.when(EmptyArgs) + def visit(self, node: EmptyArgs): + return f'CLEAR {node.args} ARGS' @visitor.when(SubstringNode) def visit(self, node: SubstringNode): @@ -169,9 +169,9 @@ def visit(self, node: EqualNode): def visit(self, node: ErrorNode): return f'ERROR {node.error}' - # @visitor.when(ConformNode) - # def visit(self, node: ConformNode): - # return f'{node.dest} = COMFORM {node.obj} {node.type}' + @visitor.when(BoxNode) + def visit(self, node: BoxNode): + return f'{node.dest} = {node.value}' @visitor.when(NotNode) def visit(self, node: NotNode): diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 46e6da31..1c1845cf 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -40,14 +40,16 @@ class Registers: class TypeData: def __init__(self, type_number: int, typex: TypeNode): - self.type: int = type_number + self.pos = type_number + self.type = typex self.str: str = typex.name_dir self.attr_offsets: Dict[str, int] = dict() self.func_offsets: Dict[str, int] = dict() self.func_names: Dict[str, str] = dict() + self.set_type() - # Calculate offsets for attributes and functions - for idx, feature in enumerate(typex.features): + def set_type(self): + for idx, feature in enumerate(self.type.features): if isinstance(feature, str): # The plus 2 is because the two first elementes # in the instance are the type_int and the type_str_dir. diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index efc7b7f5..8aa108c7 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -29,6 +29,8 @@ def init_class_attr(self, scope: Scope, class_id, self_inst): def save_attr_init(self, node: cool.ProgramNode): self.attr_init = dict() + self.attr_init['Object'] = [] + self.attr_init['IO'] = [] classes = [declaration for declaration in node.declarations if isinstance( declaration, cool.ClassDeclarationNode)] for declaration in classes: @@ -56,6 +58,7 @@ def visit(self, node: cool.ProgramNode, scope=None): self.register_instruction(ArgNode(instance)) name = self.to_function_name('main', 'Main') self.register_instruction(StaticCallNode(name, result)) + self.register_instruction(EmptyArgs(1)) self.current_function = None classes = [declaration for declaration in node.declarations if isinstance( @@ -73,7 +76,7 @@ def visit(self, node: cool.ClassDeclarationNode, scope): for attr in self.current_type.all_attributes()] type_node.methods = [(method.name, self.to_function_name( method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] - + type_node.features = type_node.attributes + type_node.methods fun_declarations = (f for f in node.features if isinstance( f, cool.FuncDeclarationNode)) for feature in fun_declarations: @@ -228,7 +231,9 @@ def visit(self, node: cool.FunctionCallNode, scope): self.register_instruction(ArgNode(obj)) self.register_instruction(StaticCallNode(name, result)) if name else \ self.register_instruction( - DynamicCallNode(typex, node.id.lex, result)) + DynamicCallNode(obj, typex, node.id.lex, result)) + + self.register_instruction(EmptyArgs(len(node.args) + 1)) return result @@ -245,8 +250,9 @@ def visit(self, node: cool.MemberCallNode, scope: Scope): self_inst = scope.find_variable('self').name self.register_instruction(ArgNode(self_inst)) self.register_instruction( - DynamicCallNode(type_name, node.id.lex, result)) + DynamicCallNode(self_inst, type_name, node.id.lex, result)) + self.register_instruction(EmptyArgs(len(node.args) + 1)) return result @visitor.when(cool.PlusNode) @@ -311,11 +317,17 @@ def visit(self, node: cool.IdNode, scope: Scope): @visitor.when(cool.BoolNode) def visit(self, node: cool.BoolNode, scope): - return 1 if node.token.lex else 0 + value = 1 if node.token.lex else 0 + bool_inst = self.define_internal_local() + self.register_instruction(BoxNode(bool_inst, value)) + return bool_inst @visitor.when(cool.IntegerNode) def visit(self, node: cool.IntegerNode, scope): - return int(node.token.lex) + value = int(node.token.lex) + int_inst = self.define_internal_local() + self.register_instruction(BoxNode(int_inst, value)) + return int_inst @visitor.when(cool.StringNode) def visit(self, node: cool.StringNode, scope): diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 21a08871..8c26df3d 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -12,6 +12,7 @@ def __init__(self, data_size=8): self.types_offsets: Dict[str, TypeData] = dict() self.arguments = {} self.local_vars = {} + self.data_segment = [] self.data_size = data_size self.registers_to_save = [ reg.ra, @@ -67,6 +68,8 @@ def load_memory(self, dst, arg: str): ) * self.data_size self.mips.load_memory(dst, self.mips.offset(reg.fp, offset)) + elif arg in self.data_segment: + self.mips.la(dst, arg) else: raise Exception( f"load_memory: The direction {arg} isn't an address") @@ -99,6 +102,7 @@ def visit(self, node: ProgramNode): for data in node.dotdata: self.visit(data) + self.data_segment.append(data.name) self.mips.label('main') self.mips.jal('entry') @@ -280,7 +284,7 @@ def visit(self, node: AllocateNode): self.mips.li(reg.a0, length) self.mips.sbrk() self.store_memory(reg.v0, node.dest) - self.mips.li(reg.t0, type_data.type) + self.mips.li(reg.t0, type_data.pos) self.mips.store_memory(reg.t0, reg.v0) self.mips.la(reg.t0, type_data.str) self.mips.store_memory( @@ -336,7 +340,7 @@ def visit(self, node: DynamicCallNode): label_get_pc = self.get_pc(reg.t2) self.mips.jal(label_get_pc) self.mips.move(reg.ra, reg.t2) - self.mips.addi(reg.ra, 12) + self.mips.addi(reg.ra, reg.ra, 12) self.mips.jr(reg.t1) @visitor.when(ArgNode) @@ -351,6 +355,11 @@ def visit(self, node: ErrorNode): self.mips.li(reg.a0, 1) self.mips.syscall(17) + @visitor.when(BoxNode) + def visit(self, node: BoxNode): + self.mips.li(reg.s0, node.value) + self.store_memory(reg.s0, node.dest) + def copy_data(self, src, dst, length): """ length: fixed in bytes size. @@ -583,6 +592,10 @@ def visit(self, node: PrintIntNode): self.load_memory(reg.a0, node.str_addr) self.mips.print_int(node.str_addr) + @visitor.when(EmptyArgs) + def visit(self, node: EmptyArgs): + self.mips.addi(reg.sp, reg.sp, node.args * self.data_size) + @visitor.when(ReturnNode) def visit(self, node: ReturnNode): self.mips.comment("ReturnNode") diff --git a/src/test.cl b/src/test.cl index e752253b..0c818f90 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,21 +1,5 @@ class Main inherits IO { - main() : Object { - { - out_string("Enter number of numbers to multiply\n"); - out_int(prod(in_int())); - out_string("\n"); - } - }; - - prod(i : Int) : Int { - let y : Int <- 1 in { - while (not (i = 0) ) loop { - out_string("Enter Number: "); - y <- y * in_int(Main : Int); -- the parser correctly catches the error here - i <- i - 1; - } - pool; - y; - } - }; + main(): IO { + out_string("Hello, World.\n") + }; }; diff --git a/src/test.mips b/src/test.mips index 6a353b55..3182e6d6 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,682 +1,2099 @@ -.TYPES -type Object { - +.data +data_0 +.asciiz " +" +data_1 +.asciiz "Invalid substring start" +data_2 +.asciiz "Invalid substring length" +data_3 +.asciiz "Invalid substring" +data_4 +.asciiz "Hello, World.n" +.text +main: +jal entry - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type String { - +li $v0, 10 +syscall +function_abort_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method length: function_length_at_String - method concat: function_concat_at_String - method substr: function_substr_at_String -} -type IO { - +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO -} -type A2I { - +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_copy_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method c2i: function_c2i_at_A2I - method i2c: function_i2c_at_A2I - method a2i: function_a2i_at_A2I - method a2i_aux: function_a2i_aux_at_A2I - method i2a: function_i2a_at_A2I - method i2a_aux: function_i2a_aux_at_A2I -} -type Main { - +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $s3, 0 +move $t0, $s0 +move $t1, $s1 +move $t3, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 2 +addi $t1, $t1, 2 +addi $t3, $t3, -1 +beqz $t3, mip_label_0 +j mip_label_0 +mip_label_0: +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method main: function_main_at_Main -} +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_type_name_at_Object: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp -.DATA -data_0 = "0" -data_1 = "1" -data_2 = "2" -data_3 = "3" -data_4 = "4" -data_5 = "5" -data_6 = "6" -data_7 = "7" -data_8 = "8" -data_9 = "9" -data_10 = "" -data_11 = "9" -data_12 = "8" -data_13 = "7" -data_14 = "6" -data_15 = "5" -data_16 = "4" -data_17 = "3" -data_18 = "2" -data_19 = "1" -data_20 = "0" -data_21 = "-" -data_22 = "+" -data_23 = "-" -data_24 = "0" -data_25 = "" -data_26 = "678987" -data_27 = " == " -data_28 = "n" +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# TypeOfNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, $s0 +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +# TypeNameNode +lw $t8, -8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 8($t0) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +srl $t9, $t1, 16 +sw $t9, 0($t8) +sw $t1, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 -.CODE -function function_abort_at_Object { - PARAM self +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_length_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +# LengthNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s0, $t1 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - ERROR 0 -} -function function_copy_at_Object { - PARAM self +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_concat_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_copy_at_Object_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - local_copy_at_Object_internal_0 = COPY self - RETURN local_copy_at_Object_internal_0 -} -function function_type_name_at_Object { - PARAM self +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_substr_at_String: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_type_name_at_Object_internal_0 - LOCAL local_type_name_at_Object_internal_1 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $s0, 0 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# LengthNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s0, $t1 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +lw $t8, -64($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, -24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# IfGotoNode +lw $t8, -40($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +li $t1, 0 +bne $t0, $t1, error1 +lw $t8, -80($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, -80($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, -64($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +lw $t8, -72($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error1: +lw $t8, -24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# IfGotoNode +lw $t8, -48($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +li $t1, 0 +bne $t0, $t1, error2 +lw $t8, -64($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +lw $t8, -72($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error2: +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +add $t2, $t0, $t1 +srl $t9, $t2, 16 +sw $t9, 0($t8) +sw $t2, 4($t8) +lw $t8, -32($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, -16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# IfGotoNode +lw $t8, -56($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +li $t1, 0 +bne $t0, $t1, error3 +lw $t8, -64($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +lw $t8, -72($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error3: +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +lw $t8, 24($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +lw $t8, 16($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +add $s0, $s0, $s3 +move $a0, $s1 +li $v0, 9 +syscall +move $t0, $s0 +move $t1, $v0 +move $t3, $s1 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 1 +addi $t1, $t1, 1 +addi $t3, $t3, -1 +beqz $t3, mip_label_0 +j mip_label_0 +mip_label_0: +move $t2, $zero +sb $t2, 0($t1) +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - local_type_name_at_Object_internal_1 = TYPEOF self - local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 - RETURN local_type_name_at_Object_internal_0 -} -function function_length_at_String { - PARAM self +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 88 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_length_at_String_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 4 +syscall - local_length_at_String_internal_0 = LENGTH self - RETURN local_length_at_String_internal_0 -} -function function_concat_at_String { - PARAM self - PARAM string +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_string_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_concat_at_String_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $a0, 1024 +li $v0, 9 +syscall +move $a0, $v0 +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $a1, 1024 +li $v0, 8 +syscall +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - local_concat_at_String_internal_0 = CONCAT self string - RETURN local_concat_at_String_internal_0 -} -function function_substr_at_String { - PARAM self - PARAM start - PARAM length +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_out_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_substr_at_String_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $a0, $t8, $t9 +li $v0, 1 +syscall - local_substr_at_String_internal_0 = SUBSTRING self start length - RETURN local_substr_at_String_internal_0 -} -function function_out_string_at_IO { - +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_in_int_at_IO: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_out_string_at_IO_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $v0, 5 +syscall +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - PRINTSTR local_out_string_at_IO_internal_0 -} -function function_in_string_at_IO { - +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +entry: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - LOCAL local_in_string_at_IO_internal_0 +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +li $a0, 40 +li $v0, 9 +syscall +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +li $t0, 3 +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +srl $t9, $t0, 16 +sw $t9, 0($t8) +sw $t0, 4($t8) +# ArgNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# StaticCallNode +jal function_main_at_Main +srl $t9, $v0, 16 +sw $t9, 0($t8) +sw $v0, 4($t8) +addi $sp, $sp, 8 - local_in_string_at_IO_internal_0 = READSTR - RETURN local_in_string_at_IO_internal_0 -} -function function_out_int_at_IO { - PARAM int_val +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -8 +srl $t9, $fp, 16 +sw $t9, 0($t8) +sw $fp, 4($t8) +move $fp, $sp - +# Allocate memory for Local variables +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $zero, 16 +sw $t9, 0($t8) +sw $zero, 4($t8) +addi $sp, $sp, -8 +srl $t9, $ra, 16 +sw $t9, 0($t8) +sw $ra, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s1, 16 +sw $t9, 0($t8) +sw $s1, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s2, 16 +sw $t9, 0($t8) +sw $s2, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s3, 16 +sw $t9, 0($t8) +sw $s3, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s4, 16 +sw $t9, 0($t8) +sw $s4, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s5, 16 +sw $t9, 0($t8) +sw $s5, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s6, 16 +sw $t9, 0($t8) +sw $s6, 4($t8) +addi $sp, $sp, -8 +srl $t9, $s7, 16 +sw $t9, 0($t8) +sw $s7, 4($t8) +# Generating body code +lw $t8, -8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +# ArgNode +lw $t8, -8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# ArgNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, -8 +srl $t9, $s0, 16 +sw $t9, 0($t8) +sw $s0, 4($t8) +# DynamicCallNode +lw $t8, 8($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t0, $t8, $t9 +lw $t8, 5($t0) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $t1, $t8, $t9 +j mip_label_0 +mip_label_0: +move $t2, $ra +jr $ra +mip_label_0: +jal mip_label_0 +move $ra, $t2 +addi $ra, $ra, 12 +jr $t1 +addi $sp, $sp, 16 +# ReturnNode +lw $t8, 0($fp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $v0, $t8, $t9 - PRINTINT int_val -} -function function_in_int_at_IO { - - - LOCAL local_in_int_at_IO_internal_0 - - local_in_int_at_IO_internal_0 = READINT - RETURN local_in_int_at_IO_internal_0 -} -function entry { - - - LOCAL local__internal_0 - LOCAL local__internal_1 - - local__internal_0 = ALLOCATE Main - ARG local__internal_0 - local__internal_1 = CALL function_main_at_Main -} -function function_c2i_at_A2I { - PARAM self - PARAM char - - LOCAL local_c2i_at_A2I_internal_0 - LOCAL local_c2i_at_A2I_internal_1 - LOCAL local_c2i_at_A2I_internal_2 - LOCAL local_c2i_at_A2I_internal_3 - LOCAL local_c2i_at_A2I_internal_4 - LOCAL local_c2i_at_A2I_internal_5 - LOCAL local_c2i_at_A2I_internal_6 - LOCAL local_c2i_at_A2I_internal_7 - LOCAL local_c2i_at_A2I_internal_8 - LOCAL local_c2i_at_A2I_internal_9 - LOCAL local_c2i_at_A2I_internal_10 - LOCAL local_c2i_at_A2I_internal_11 - LOCAL local_c2i_at_A2I_internal_12 - LOCAL local_c2i_at_A2I_internal_13 - LOCAL local_c2i_at_A2I_internal_14 - LOCAL local_c2i_at_A2I_internal_15 - LOCAL local_c2i_at_A2I_internal_16 - LOCAL local_c2i_at_A2I_internal_17 - LOCAL local_c2i_at_A2I_internal_18 - LOCAL local_c2i_at_A2I_internal_19 - LOCAL local_c2i_at_A2I_internal_20 - LOCAL local_c2i_at_A2I_internal_21 - LOCAL local_c2i_at_A2I_internal_22 - LOCAL local_c2i_at_A2I_internal_23 - LOCAL local_c2i_at_A2I_internal_24 - LOCAL local_c2i_at_A2I_internal_25 - LOCAL local_c2i_at_A2I_internal_26 - LOCAL local_c2i_at_A2I_internal_27 - LOCAL local_c2i_at_A2I_internal_28 - LOCAL local_c2i_at_A2I_internal_29 - LOCAL local_c2i_at_A2I_internal_30 - LOCAL local_c2i_at_A2I_internal_31 - - local_c2i_at_A2I_internal_0 = LOAD data_0 - local_c2i_at_A2I_internal_1 = STREQ char local_c2i_at_A2I_internal_0 - IF local_c2i_at_A2I_internal_1 GOTO TRUE_0 - local_c2i_at_A2I_internal_3 = LOAD data_1 - local_c2i_at_A2I_internal_4 = STREQ char local_c2i_at_A2I_internal_3 - IF local_c2i_at_A2I_internal_4 GOTO TRUE_1 - local_c2i_at_A2I_internal_6 = LOAD data_2 - local_c2i_at_A2I_internal_7 = STREQ char local_c2i_at_A2I_internal_6 - IF local_c2i_at_A2I_internal_7 GOTO TRUE_2 - local_c2i_at_A2I_internal_9 = LOAD data_3 - local_c2i_at_A2I_internal_10 = STREQ char local_c2i_at_A2I_internal_9 - IF local_c2i_at_A2I_internal_10 GOTO TRUE_3 - local_c2i_at_A2I_internal_12 = LOAD data_4 - local_c2i_at_A2I_internal_13 = STREQ char local_c2i_at_A2I_internal_12 - IF local_c2i_at_A2I_internal_13 GOTO TRUE_4 - local_c2i_at_A2I_internal_15 = LOAD data_5 - local_c2i_at_A2I_internal_16 = STREQ char local_c2i_at_A2I_internal_15 - IF local_c2i_at_A2I_internal_16 GOTO TRUE_5 - local_c2i_at_A2I_internal_18 = LOAD data_6 - local_c2i_at_A2I_internal_19 = STREQ char local_c2i_at_A2I_internal_18 - IF local_c2i_at_A2I_internal_19 GOTO TRUE_6 - local_c2i_at_A2I_internal_21 = LOAD data_7 - local_c2i_at_A2I_internal_22 = STREQ char local_c2i_at_A2I_internal_21 - IF local_c2i_at_A2I_internal_22 GOTO TRUE_7 - local_c2i_at_A2I_internal_24 = LOAD data_8 - local_c2i_at_A2I_internal_25 = STREQ char local_c2i_at_A2I_internal_24 - IF local_c2i_at_A2I_internal_25 GOTO TRUE_8 - local_c2i_at_A2I_internal_27 = LOAD data_9 - local_c2i_at_A2I_internal_28 = STREQ char local_c2i_at_A2I_internal_27 - IF local_c2i_at_A2I_internal_28 GOTO TRUE_9 - ARG self - local_c2i_at_A2I_internal_31 = VCALL A2I abort - local_c2i_at_A2I_internal_30 = 0 - local_c2i_at_A2I_internal_29 = local_c2i_at_A2I_internal_30 - GOTO END_9 - LABEL TRUE_9 - local_c2i_at_A2I_internal_29 = 9 - LABEL END_9 - local_c2i_at_A2I_internal_26 = local_c2i_at_A2I_internal_29 - GOTO END_8 - LABEL TRUE_8 - local_c2i_at_A2I_internal_26 = 8 - LABEL END_8 - local_c2i_at_A2I_internal_23 = local_c2i_at_A2I_internal_26 - GOTO END_7 - LABEL TRUE_7 - local_c2i_at_A2I_internal_23 = 7 - LABEL END_7 - local_c2i_at_A2I_internal_20 = local_c2i_at_A2I_internal_23 - GOTO END_6 - LABEL TRUE_6 - local_c2i_at_A2I_internal_20 = 6 - LABEL END_6 - local_c2i_at_A2I_internal_17 = local_c2i_at_A2I_internal_20 - GOTO END_5 - LABEL TRUE_5 - local_c2i_at_A2I_internal_17 = 5 - LABEL END_5 - local_c2i_at_A2I_internal_14 = local_c2i_at_A2I_internal_17 - GOTO END_4 - LABEL TRUE_4 - local_c2i_at_A2I_internal_14 = 4 - LABEL END_4 - local_c2i_at_A2I_internal_11 = local_c2i_at_A2I_internal_14 - GOTO END_3 - LABEL TRUE_3 - local_c2i_at_A2I_internal_11 = 3 - LABEL END_3 - local_c2i_at_A2I_internal_8 = local_c2i_at_A2I_internal_11 - GOTO END_2 - LABEL TRUE_2 - local_c2i_at_A2I_internal_8 = 2 - LABEL END_2 - local_c2i_at_A2I_internal_5 = local_c2i_at_A2I_internal_8 - GOTO END_1 - LABEL TRUE_1 - local_c2i_at_A2I_internal_5 = 1 - LABEL END_1 - local_c2i_at_A2I_internal_2 = local_c2i_at_A2I_internal_5 - GOTO END_0 - LABEL TRUE_0 - local_c2i_at_A2I_internal_2 = 0 - LABEL END_0 - RETURN local_c2i_at_A2I_internal_2 -} -function function_i2c_at_A2I { - PARAM self - PARAM i - - LOCAL local_i2c_at_A2I_internal_0 - LOCAL local_i2c_at_A2I_internal_1 - LOCAL local_i2c_at_A2I_internal_2 - LOCAL local_i2c_at_A2I_internal_3 - LOCAL local_i2c_at_A2I_internal_4 - LOCAL local_i2c_at_A2I_internal_5 - LOCAL local_i2c_at_A2I_internal_6 - LOCAL local_i2c_at_A2I_internal_7 - LOCAL local_i2c_at_A2I_internal_8 - LOCAL local_i2c_at_A2I_internal_9 - LOCAL local_i2c_at_A2I_internal_10 - LOCAL local_i2c_at_A2I_internal_11 - LOCAL local_i2c_at_A2I_internal_12 - LOCAL local_i2c_at_A2I_internal_13 - LOCAL local_i2c_at_A2I_internal_14 - LOCAL local_i2c_at_A2I_internal_15 - LOCAL local_i2c_at_A2I_internal_16 - LOCAL local_i2c_at_A2I_internal_17 - LOCAL local_i2c_at_A2I_internal_18 - LOCAL local_i2c_at_A2I_internal_19 - LOCAL local_i2c_at_A2I_internal_20 - LOCAL local_i2c_at_A2I_internal_21 - LOCAL local_i2c_at_A2I_internal_22 - LOCAL local_i2c_at_A2I_internal_23 - LOCAL local_i2c_at_A2I_internal_24 - LOCAL local_i2c_at_A2I_internal_25 - LOCAL local_i2c_at_A2I_internal_26 - LOCAL local_i2c_at_A2I_internal_27 - LOCAL local_i2c_at_A2I_internal_28 - LOCAL local_i2c_at_A2I_internal_29 - LOCAL local_i2c_at_A2I_internal_30 - LOCAL local_i2c_at_A2I_internal_31 - LOCAL local_i2c_at_A2I_internal_32 - - local_i2c_at_A2I_internal_0 = i == 0 - IF local_i2c_at_A2I_internal_0 GOTO TRUE_0 - local_i2c_at_A2I_internal_2 = i == 1 - IF local_i2c_at_A2I_internal_2 GOTO TRUE_1 - local_i2c_at_A2I_internal_4 = i == 2 - IF local_i2c_at_A2I_internal_4 GOTO TRUE_2 - local_i2c_at_A2I_internal_6 = i == 3 - IF local_i2c_at_A2I_internal_6 GOTO TRUE_3 - local_i2c_at_A2I_internal_8 = i == 4 - IF local_i2c_at_A2I_internal_8 GOTO TRUE_4 - local_i2c_at_A2I_internal_10 = i == 5 - IF local_i2c_at_A2I_internal_10 GOTO TRUE_5 - local_i2c_at_A2I_internal_12 = i == 6 - IF local_i2c_at_A2I_internal_12 GOTO TRUE_6 - local_i2c_at_A2I_internal_14 = i == 7 - IF local_i2c_at_A2I_internal_14 GOTO TRUE_7 - local_i2c_at_A2I_internal_16 = i == 8 - IF local_i2c_at_A2I_internal_16 GOTO TRUE_8 - local_i2c_at_A2I_internal_18 = i == 9 - IF local_i2c_at_A2I_internal_18 GOTO TRUE_9 - ARG self - local_i2c_at_A2I_internal_21 = VCALL A2I abort - local_i2c_at_A2I_internal_22 = LOAD data_10 - local_i2c_at_A2I_internal_20 = local_i2c_at_A2I_internal_22 - local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_20 - GOTO END_9 - LABEL TRUE_9 - local_i2c_at_A2I_internal_23 = LOAD data_11 - local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_23 - LABEL END_9 - local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_19 - GOTO END_8 - LABEL TRUE_8 - local_i2c_at_A2I_internal_24 = LOAD data_12 - local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_24 - LABEL END_8 - local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_17 - GOTO END_7 - LABEL TRUE_7 - local_i2c_at_A2I_internal_25 = LOAD data_13 - local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_25 - LABEL END_7 - local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_15 - GOTO END_6 - LABEL TRUE_6 - local_i2c_at_A2I_internal_26 = LOAD data_14 - local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_26 - LABEL END_6 - local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_13 - GOTO END_5 - LABEL TRUE_5 - local_i2c_at_A2I_internal_27 = LOAD data_15 - local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_27 - LABEL END_5 - local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_11 - GOTO END_4 - LABEL TRUE_4 - local_i2c_at_A2I_internal_28 = LOAD data_16 - local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_28 - LABEL END_4 - local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_9 - GOTO END_3 - LABEL TRUE_3 - local_i2c_at_A2I_internal_29 = LOAD data_17 - local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_29 - LABEL END_3 - local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_7 - GOTO END_2 - LABEL TRUE_2 - local_i2c_at_A2I_internal_30 = LOAD data_18 - local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_30 - LABEL END_2 - local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_5 - GOTO END_1 - LABEL TRUE_1 - local_i2c_at_A2I_internal_31 = LOAD data_19 - local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_31 - LABEL END_1 - local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2c_at_A2I_internal_32 = LOAD data_20 - local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_32 - LABEL END_0 - RETURN local_i2c_at_A2I_internal_1 -} -function function_a2i_at_A2I { - PARAM self - PARAM s - - LOCAL local_a2i_at_A2I_internal_0 - LOCAL local_a2i_at_A2I_internal_1 - LOCAL local_a2i_at_A2I_internal_2 - LOCAL local_a2i_at_A2I_internal_3 - LOCAL local_a2i_at_A2I_internal_4 - LOCAL local_a2i_at_A2I_internal_5 - LOCAL local_a2i_at_A2I_internal_6 - LOCAL local_a2i_at_A2I_internal_7 - LOCAL local_a2i_at_A2I_internal_8 - LOCAL local_a2i_at_A2I_internal_9 - LOCAL local_a2i_at_A2I_internal_10 - LOCAL local_a2i_at_A2I_internal_11 - LOCAL local_a2i_at_A2I_internal_12 - LOCAL local_a2i_at_A2I_internal_13 - LOCAL local_a2i_at_A2I_internal_14 - LOCAL local_a2i_at_A2I_internal_15 - LOCAL local_a2i_at_A2I_internal_16 - LOCAL local_a2i_at_A2I_internal_17 - LOCAL local_a2i_at_A2I_internal_18 - LOCAL local_a2i_at_A2I_internal_19 - LOCAL local_a2i_at_A2I_internal_20 - - ARG s - local_a2i_at_A2I_internal_0 = CALL function_length_at_String - local_a2i_at_A2I_internal_1 = local_a2i_at_A2I_internal_0 == 0 - IF local_a2i_at_A2I_internal_1 GOTO TRUE_0 - ARG 1 - ARG 0 - ARG s - local_a2i_at_A2I_internal_3 = CALL function_substr_at_String - local_a2i_at_A2I_internal_4 = LOAD data_21 - local_a2i_at_A2I_internal_5 = STREQ local_a2i_at_A2I_internal_3 local_a2i_at_A2I_internal_4 - IF local_a2i_at_A2I_internal_5 GOTO TRUE_1 - ARG 1 - ARG 0 - ARG s - local_a2i_at_A2I_internal_7 = CALL function_substr_at_String - local_a2i_at_A2I_internal_8 = LOAD data_22 - local_a2i_at_A2I_internal_9 = STREQ local_a2i_at_A2I_internal_7 local_a2i_at_A2I_internal_8 - IF local_a2i_at_A2I_internal_9 GOTO TRUE_2 - ARG s - ARG self - local_a2i_at_A2I_internal_11 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_11 - GOTO END_2 - LABEL TRUE_2 - ARG s - local_a2i_at_A2I_internal_15 = CALL function_length_at_String - local_a2i_at_A2I_internal_14 = local_a2i_at_A2I_internal_15 - 1 - ARG local_a2i_at_A2I_internal_14 - ARG 1 - ARG s - local_a2i_at_A2I_internal_13 = CALL function_substr_at_String - ARG local_a2i_at_A2I_internal_13 - ARG self - local_a2i_at_A2I_internal_12 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_12 - LABEL END_2 - local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_10 - GOTO END_1 - LABEL TRUE_1 - ARG s - local_a2i_at_A2I_internal_20 = CALL function_length_at_String - local_a2i_at_A2I_internal_19 = local_a2i_at_A2I_internal_20 - 1 - ARG local_a2i_at_A2I_internal_19 - ARG 1 - ARG s - local_a2i_at_A2I_internal_18 = CALL function_substr_at_String - ARG local_a2i_at_A2I_internal_18 - ARG self - local_a2i_at_A2I_internal_17 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_16 = COMPLEMENT local_a2i_at_A2I_internal_17 - local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_16 - LABEL END_1 - local_a2i_at_A2I_internal_2 = local_a2i_at_A2I_internal_6 - GOTO END_0 - LABEL TRUE_0 - local_a2i_at_A2I_internal_2 = 0 - LABEL END_0 - RETURN local_a2i_at_A2I_internal_2 -} -function function_a2i_aux_at_A2I { - PARAM self - PARAM s - - LOCAL local_a2i_aux_at_A2I_internal_0 - LOCAL local_a2i_aux_at_A2I_internal_1 - LOCAL local_a2i_aux_at_A2I_internal_2 - LOCAL local_a2i_aux_at_A2I_internal_3 - LOCAL local_a2i_aux_at_A2I_internal_4 - LOCAL local_a2i_aux_at_A2I_internal_5 - LOCAL local_a2i_aux_at_A2I_internal_6 - LOCAL local_a2i_aux_at_A2I_internal_7 - LOCAL local_a2i_aux_at_A2I_internal_8 - LOCAL local_a2i_aux_at_A2I_internal_9 - LOCAL local_a2i_aux_at_A2I_internal_10 - LOCAL local_a2i_aux_at_A2I_internal_11 - - ARG s - local_a2i_aux_at_A2I_internal_2 = CALL function_length_at_String - LABEL START_0 - local_a2i_aux_at_A2I_internal_5 = i < j - IF local_a2i_aux_at_A2I_internal_5 GOTO CONTINUE_0 - GOTO END_0 - LABEL CONTINUE_0 - local_a2i_aux_at_A2I_internal_8 = int * 10 - ARG 1 - ARG i - ARG s - local_a2i_aux_at_A2I_internal_10 = CALL function_substr_at_String - ARG local_a2i_aux_at_A2I_internal_10 - ARG self - local_a2i_aux_at_A2I_internal_9 = VCALL A2I c2i - local_a2i_aux_at_A2I_internal_7 = local_a2i_aux_at_A2I_internal_8 + local_a2i_aux_at_A2I_internal_9 - int = local_a2i_aux_at_A2I_internal_7 - local_a2i_aux_at_A2I_internal_11 = i + 1 - i = local_a2i_aux_at_A2I_internal_11 - local_a2i_aux_at_A2I_internal_6 = 0 - GOTO START_0 - LABEL END_0 - local_a2i_aux_at_A2I_internal_4 = 0 - local_a2i_aux_at_A2I_internal_3 = local_a2i_aux_at_A2I_internal_4 - local_a2i_aux_at_A2I_internal_1 = int - local_a2i_aux_at_A2I_internal_0 = local_a2i_aux_at_A2I_internal_1 - RETURN local_a2i_aux_at_A2I_internal_0 -} -function function_i2a_at_A2I { - PARAM self - PARAM i - - LOCAL local_i2a_at_A2I_internal_0 - LOCAL local_i2a_at_A2I_internal_1 - LOCAL local_i2a_at_A2I_internal_2 - LOCAL local_i2a_at_A2I_internal_3 - LOCAL local_i2a_at_A2I_internal_4 - LOCAL local_i2a_at_A2I_internal_5 - LOCAL local_i2a_at_A2I_internal_6 - LOCAL local_i2a_at_A2I_internal_7 - LOCAL local_i2a_at_A2I_internal_8 - LOCAL local_i2a_at_A2I_internal_9 - LOCAL local_i2a_at_A2I_internal_10 - - local_i2a_at_A2I_internal_0 = i == 0 - IF local_i2a_at_A2I_internal_0 GOTO TRUE_0 - local_i2a_at_A2I_internal_2 = 0 < i - IF local_i2a_at_A2I_internal_2 GOTO TRUE_1 - local_i2a_at_A2I_internal_7 = COMPLEMENT 1 - local_i2a_at_A2I_internal_6 = i * local_i2a_at_A2I_internal_7 - ARG local_i2a_at_A2I_internal_6 - ARG self - local_i2a_at_A2I_internal_5 = VCALL A2I i2a_aux - ARG local_i2a_at_A2I_internal_5 - local_i2a_at_A2I_internal_8 = LOAD data_23 - ARG local_i2a_at_A2I_internal_8 - local_i2a_at_A2I_internal_4 = CALL function_concat_at_String - local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_4 - GOTO END_1 - LABEL TRUE_1 - ARG i - ARG self - local_i2a_at_A2I_internal_9 = VCALL A2I i2a_aux - local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_9 - LABEL END_1 - local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2a_at_A2I_internal_10 = LOAD data_24 - local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_10 - LABEL END_0 - RETURN local_i2a_at_A2I_internal_1 -} -function function_i2a_aux_at_A2I { - PARAM self - PARAM i - - LOCAL local_i2a_aux_at_A2I_internal_0 - LOCAL local_i2a_aux_at_A2I_internal_1 - LOCAL local_i2a_aux_at_A2I_internal_2 - LOCAL local_i2a_aux_at_A2I_internal_3 - LOCAL local_i2a_aux_at_A2I_internal_4 - LOCAL local_i2a_aux_at_A2I_internal_5 - LOCAL local_i2a_aux_at_A2I_internal_6 - LOCAL local_i2a_aux_at_A2I_internal_7 - LOCAL local_i2a_aux_at_A2I_internal_8 - LOCAL local_i2a_aux_at_A2I_internal_9 - - local_i2a_aux_at_A2I_internal_0 = i == 0 - IF local_i2a_aux_at_A2I_internal_0 GOTO TRUE_0 - local_i2a_aux_at_A2I_internal_2 = i / 10 - local_i2a_aux_at_A2I_internal_7 = next * 10 - local_i2a_aux_at_A2I_internal_6 = i - local_i2a_aux_at_A2I_internal_7 - ARG local_i2a_aux_at_A2I_internal_6 - ARG self - local_i2a_aux_at_A2I_internal_5 = VCALL A2I i2c - ARG local_i2a_aux_at_A2I_internal_5 - ARG next - ARG self - local_i2a_aux_at_A2I_internal_8 = VCALL A2I i2a_aux - ARG local_i2a_aux_at_A2I_internal_8 - local_i2a_aux_at_A2I_internal_4 = CALL function_concat_at_String - local_i2a_aux_at_A2I_internal_3 = local_i2a_aux_at_A2I_internal_4 - local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2a_aux_at_A2I_internal_9 = LOAD data_25 - local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_9 - LABEL END_0 - RETURN local_i2a_aux_at_A2I_internal_1 -} -function function_main_at_Main { - PARAM self - - LOCAL local_main_at_Main_internal_0 - LOCAL local_main_at_Main_internal_1 - LOCAL local_main_at_Main_internal_2 - LOCAL local_main_at_Main_internal_3 - LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_internal_5 - LOCAL local_main_at_Main_internal_6 - LOCAL local_main_at_Main_internal_7 - LOCAL local_main_at_Main_internal_8 - LOCAL local_main_at_Main_internal_9 - LOCAL local_main_at_Main_internal_10 - LOCAL local_main_at_Main_internal_11 - LOCAL local_main_at_Main_internal_12 - - local_main_at_Main_internal_1 = LOAD data_26 - ARG local_main_at_Main_internal_1 - local_main_at_Main_internal_2 = ALLOCATE A2I - ARG local_main_at_Main_internal_2 - local_main_at_Main_internal_0 = CALL function_a2i_at_A2I - ARG 678987 - local_main_at_Main_internal_4 = ALLOCATE A2I - ARG local_main_at_Main_internal_4 - local_main_at_Main_internal_3 = CALL function_i2a_at_A2I - ARG a - ARG self - local_main_at_Main_internal_7 = VCALL Main out_int - local_main_at_Main_internal_9 = LOAD data_27 - ARG local_main_at_Main_internal_9 - ARG self - local_main_at_Main_internal_8 = VCALL Main out_string - ARG b - ARG self - local_main_at_Main_internal_10 = VCALL Main out_string - local_main_at_Main_internal_12 = LOAD data_28 - ARG local_main_at_Main_internal_12 - ARG self - local_main_at_Main_internal_11 = VCALL Main out_string - local_main_at_Main_internal_6 = local_main_at_Main_internal_11 - local_main_at_Main_internal_5 = local_main_at_Main_internal_6 - RETURN local_main_at_Main_internal_5 -} \ No newline at end of file +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s7, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s6, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s5, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s4, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s3, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s2, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s1, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $s0, $t8, $t9 +addi $sp, $sp, 8 +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $ra, $t8, $t9 +addi $sp, $sp, 8 +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $t8, 0($sp) +sll $t8, $t8, 16 +addi $t7, $t7, 4 +lw $t9, 0($t7) +or $fp, $t8, $t9 +addi $sp, $sp, 8 +jr $ra \ No newline at end of file From e7e5b21574ac6b467538bc77e5f78be6d42c7284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 10 Dec 2020 22:32:29 -0500 Subject: [PATCH 087/191] Fix wrong semantic test --- src/engine/cp/semantic.py | 15 ++++++++++----- src/engine/visitors/checker.py | 12 +++++++----- src/main.py | 6 ++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index aa95cc53..2fa659bc 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -311,12 +311,17 @@ def create_child(self): self.children.append(child) return child - def define_variable(self, vname, vtype): + def define_variable(self, vname, vtype, let=False): info = VariableInfo(vname, vtype) - for i in self.locals: - if i.name == vname: - raise SemanticError(f'Variable {vname} already exists in the current context') - self.locals.append(info) + for i in range(len(self.locals)): + if self.locals[i].name == vname: + if not let: + raise SemanticError(f'Variable {vname} already exists in the current context') + else: + self.locals[i] = info + break + else: + self.locals.append(info) return info def find_variable(self, vname, index=None): diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 665c71ca..00dc8c56 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -35,18 +35,19 @@ def visit(self, node, scope = None): def visit(self, node, scope): self.current_type = self.context.get_type(node.id.lex) - #Verificando ciclos en la herencia + attrs = [] parent = self.current_type.parent while parent: + if parent == self.current_type: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + CYCLIC_HERITAGE % (parent.name)) self.current_type.parent = self.object_type break - + attrs += parent.attributes parent = parent.parent - for a in self.current_type.attributes: + for a in self.current_type.attributes + attrs: if a.name == 'self': line, column = [ (attrib.line, attrib.column) for attrib in node.features if type(attrib) is AttrDeclarationNode and attrib.id.lex == 'self'][0] self.errors.append(ERROR_ON_LN_COL % (line, column) + "SemanticError: " + "Incorrect use of self in attribute declaration") @@ -164,7 +165,7 @@ def visit(self, node, scope): self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) try: - scope.define_variable(idx.lex, id_type) + scope.define_variable(idx.lex, id_type, True) except SemanticError as e: self.errors.append(ERROR_ON_LN_COL % (idx.line, idx.column) + "SemanticError: " + e.text) @@ -207,7 +208,8 @@ def visit(self, node, scope): @visitor.when(AssignNode) def visit(self, node, scope): expression = node.expression - + node_type = ErrorType() + if scope.is_defined(node.id.lex): var = scope.find_variable(node.id.lex) node_type = var.type diff --git a/src/main.py b/src/main.py index a76a59ce..f6790a95 100644 --- a/src/main.py +++ b/src/main.py @@ -42,17 +42,19 @@ collect.visit(ast) if len(collect_errors): - for e in collect_errors[::-1]: + for e in collect_errors: print(e) exit(1) context = collect.context builder_errors = [] builder = Builder(context, builder_errors) + + builder.visit(ast) if len(builder_errors): - for e in builder_errors[::-1]: + for e in builder_errors: print(e) exit(1) From 9aad5a20567ad61bfa913c6f20564ff7f0b8019b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 10 Dec 2020 22:34:22 -0500 Subject: [PATCH 088/191] Restore error list natural order --- src/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.py b/src/main.py index f6790a95..fd6e7128 100644 --- a/src/main.py +++ b/src/main.py @@ -64,7 +64,7 @@ scope = checker.visit(ast) if len(checker_errors): - for e in checker_errors[::-1]: + for e in checker_errors: print(e) exit(1) From 1a979336f12f2bed49008126a3236de18ea254b6 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Fri, 11 Dec 2020 12:06:26 -0500 Subject: [PATCH 089/191] cil generator, endline problem fix --- src/engine/codegen/cil.py | 2 +- src/engine/commons/tokens.py | 49 ++++++++---------------------------- 2 files changed, 11 insertions(+), 40 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 61419dea..5187ef69 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -117,7 +117,7 @@ def define_string_type(self): no_error_label3 = LabelNode("error3") self.register_instruction(AssignNode(zero, 0)) self.register_instruction(LengthNode(length_var, self_param)) - eol = self.register_data('\n').name + eol = self.register_data('\\n').name msg_eol = self.define_internal_local() self.register_instruction(LessEqNode(cmp_var1, zero, start)) diff --git a/src/engine/commons/tokens.py b/src/engine/commons/tokens.py index cbafc3c3..3a78d0df 100644 --- a/src/engine/commons/tokens.py +++ b/src/engine/commons/tokens.py @@ -3,7 +3,7 @@ keywords = ( 'CLASS', 'ELSE', - ### false case is independently treated + # false case is independently treated 'FI', 'IF', 'IN', @@ -19,7 +19,7 @@ 'NEW', 'OF', 'NOT' - ### true case is independently treated + # true case is independently treated ) literals = ['+', '-', '*', '/', ':', ';', '(', ')', '{', '}', '@', '.', ','] @@ -58,41 +58,12 @@ } tokens = ( - # Identifiers - 'TYPE', 'ID', - # Primitive data types - 'INTEGER', 'STRING', 'BOOL', - # Special keywords - 'ACTION', - # Operators - 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', + # Identifiers + 'TYPE', 'ID', + # Primitive data types + 'INTEGER', 'STRING', 'BOOL', + # Special keywords + 'ACTION', + # Operators + 'ASSIGN', 'LESS', 'LESSEQUAL', 'EQUAL', 'INT_COMPLEMENT', ) - - -class Token: - """ - Basic token class. - - Parameters - ---------- - lex : str - Token's lexeme. - token_type : Enum - Token's type. - """ - - def __init__(self, lex, token_type, line=0, column=0): - self.lex = lex - self.token_type = token_type - self.line = line - self.column = column - - @property - def type(self): - return self.type - - def __str__(self): - return f'{self.token_type}: {self.lex}' - - def __repr__(self): - return str(self) From 5e37b847492b9e8d8d7afa0084cdf5a569b76249 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Fri, 11 Dec 2020 12:08:13 -0500 Subject: [PATCH 090/191] inheritance build in collector and store in context --- src/engine/cp/semantic.py | 102 +++++++++++++++++++------------ src/engine/visitors/collector.py | 33 ++++++---- 2 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index aa95cc53..de95157f 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -1,10 +1,12 @@ import itertools as itt + class SemanticError(Exception): @property def text(self): return self.args[0] + class Attribute: def __init__(self, name, typex): self.name = name @@ -16,17 +18,20 @@ def __str__(self): 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.param_infos = [VariableInfo(f'_{name}_{pname}', ptype) for pname, ptype in zip(param_names, params_types)] + self.param_infos = [VariableInfo( + f'_{name}_{pname}', ptype) for pname, ptype in zip(param_names, params_types)] self.return_type = return_type self.return_info = VariableInfo(f'_{name}', return_type) def __str__(self): - params = ', '.join(f'{n}: {t.name}' for n,t in zip(self.param_names, self.param_types)) + 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): @@ -34,8 +39,9 @@ def __eq__(self, other): other.return_type == self.return_type and \ other.param_types == self.param_types + class Type: - def __init__(self, name:str, sealed=False, built_in = False): + def __init__(self, name: str, sealed=False, built_in=False): self.name = name self.attributes = [] self.methods = {} @@ -47,7 +53,8 @@ def set_parent(self, parent): if self.parent is not None: raise SemanticError(f'Parent type is already set for {self.name}.') if parent.sealed: - raise SemanticError(f'Parent type "{parent.name}" is sealed. Can\'t inherit from it.') + raise SemanticError( + f'Parent type "{parent.name}" is sealed. Can\'t inherit from it.') self.parent = parent def type_union(self, other): @@ -70,18 +77,20 @@ def type_union(self, other): return t1[-1] - def get_attribute(self, name:str): + 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}.') + 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}.') + raise SemanticError( + f'Attribute "{name}" is not defined in {self.name}.') - def define_attribute(self, name:str, typex): + def define_attribute(self, name: str, typex): try: self.get_attribute(name) except SemanticError: @@ -89,25 +98,30 @@ def define_attribute(self, name:str, typex): self.attributes.append(attribute) return attribute else: - raise SemanticError(f'Attribute "{name}" is already defined in {self.name}.') + raise SemanticError( + f'Attribute "{name}" is already defined in {self.name}.') - def get_method(self, name:str): + def get_method(self, name: str): try: return self.methods[name] except KeyError: if self.parent is None: - raise SemanticError(f'Method "{name}" is not defined in {self.name}.') + 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}.') + 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): + def define_method(self, name: str, param_names: list, param_types: list, return_type): if name in self.methods: - raise SemanticError(f'Method "{name}" already defined in {self.name}') + raise SemanticError( + f'Method "{name}" already defined in {self.name}') # raise SemanticError(f'Method "{name}" already defined in {self.name} with a different signature.') - method = self.methods[name] = Method(name, param_names, param_types, return_type) + method = self.methods[name] = Method( + name, param_names, param_types, return_type) return method def all_attributes(self): @@ -127,10 +141,10 @@ def all_methods(self): else: yield (method, typex) for method in self.methods.values(): - if method.name in done: continue + if method.name in done: + continue yield (method, self) - def conforms_to(self, other): return other.bypass() or self == other or self.parent is not None and self.parent.conforms_to(other) @@ -153,6 +167,7 @@ def __str__(self): def __repr__(self): return str(self) + class SelfType(Type): def __init__(self): Type.__init__(self, 'SELF_TYPE') @@ -167,8 +182,9 @@ def bypass(self): def __eq__(self, other): return isinstance(other, SelfType) + class ErrorType(Type): - def __init__(self, message = ""): + def __init__(self, message=""): Type.__init__(self, '') self.sealed = True self.message = message @@ -185,28 +201,34 @@ def bypass(self): def __eq__(self, other): return isinstance(other, Type) + class Context: def __init__(self): + self.inheritance = {} self.types = {} self.basic_types = ['Object', 'IO', 'Int', 'String', 'Bool'] - def create_type(self, name:str, builtin = False): + def create_type(self, name: str, builtin=False): if name in self.basic_types and name in self.types: - raise SemanticError(f'SemanticError: Redefinition of basic class {name}.') + raise SemanticError( + f'SemanticError: Redefinition of basic class {name}.') if name in self.types: - raise SemanticError(f'Type with the same name ({name}) already in context.') - typex = self.types[name] = Type(name,built_in=builtin) + raise SemanticError( + f'Type with the same name ({name}) already in context.') + typex = self.types[name] = Type(name, built_in=builtin) return typex def add_type(self, typex): if typex.name in self.basic_types: - raise SemanticError(f'SemanticError: Redefinition of basic class {typex.name}.') + raise SemanticError( + f'SemanticError: Redefinition of basic class {typex.name}.') if typex.name in self.types: - raise SemanticError(f'Type with the same name ({typex.name}) already in context.') + raise SemanticError( + f'Type with the same name ({typex.name}) already in context.') self.types[typex.name] = typex return typex - def get_type(self, name:str): + def get_type(self, name: str): try: return self.types[name] except KeyError: @@ -218,6 +240,7 @@ def __str__(self): def __repr__(self): return str(self) + class VariableInfo: def __init__(self, name, vtype): self.name = name @@ -237,7 +260,7 @@ def infer_type(self): if not self.infered: message = "" t = all(not x.built_in for x in self.calls + self.assigns) - #print(t) + # print(t) if t: call = None for typex in self.calls: @@ -254,7 +277,8 @@ def infer_type(self): assign = typex if not assign else assign.type_union(typex) if assign: - self.type = assign if not call or assign.conforms_to(call) else ErrorType() + self.type = assign if not call or assign.conforms_to( + call) else ErrorType() else: self.type = call @@ -262,7 +286,7 @@ def infer_type(self): self.assigns = [] return self.infered, message - + else: self.type = None for x in self.assigns + self.calls: @@ -271,13 +295,14 @@ def infer_type(self): break error = [] - #print(self.type.name) + # print(self.type.name) for x in self.assigns + self.calls: if not x.conforms_to(self.type): error.append(x) - - message = f"Incompatible Types {self.type.name} and " + " ".join(e.name for e in error) if error else "" + + message = f"Incompatible Types {self.type.name} and " + \ + " ".join(e.name for e in error) if error else "" self.infered = True @@ -286,7 +311,6 @@ def infer_type(self): return True, message - return False, "" def __repr__(self): @@ -294,7 +318,7 @@ def __repr__(self): def __str__(self): return f'Variable Name: {self.name}, Variable Type: {self.type} \n' - + class Scope: def __init__(self, parent=None): @@ -315,12 +339,14 @@ def define_variable(self, vname, vtype): info = VariableInfo(vname, vtype) for i in self.locals: if i.name == vname: - raise SemanticError(f'Variable {vname} already exists in the current context') + raise SemanticError( + f'Variable {vname} already exists in the current context') 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) + 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: @@ -331,10 +357,10 @@ def is_defined(self, vname): def is_local(self, vname): return any(True for x in self.locals if x.name == vname) - + def __repr__(self): return str(self) - + def __str__(self): return "".join(str(i) for i in self.locals) + "".join(str(s) for s in self.children) - #return f'Scope: {self.index}\n' + "\n".join(str(x) for x in self.locals) + "\n".join(str(s) for s in self.children) \ No newline at end of file + # return f'Scope: {self.index}\n' + "\n".join(str(x) for x in self.locals) + "\n".join(str(s) for s in self.children) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 7f158be8..e62d8e3c 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -2,21 +2,22 @@ from engine.parser import ProgramNode, ClassDeclarationNode from engine.semantic_errors import ERROR_ON_LN_COL, CYCLIC_HERITAGE + class Collector: - def __init__(self, errors = []): + def __init__(self, errors=[]): self.context = Context() self.errors = errors self.parents = {} - #Tipos especiales + # Tipos especiales self.context.add_type(SelfType()) - #Tipos Buit-In - self.context.create_type('Object',builtin = True) - self.context.create_type('IO',builtin = True) - self.context.create_type('Int',builtin = True) - self.context.create_type('String',builtin = True) - self.context.create_type('Bool',builtin = True) + # Tipos Buit-In + self.context.create_type('Object', builtin=True) + self.context.create_type('IO', builtin=True) + self.context.create_type('Int', builtin=True) + self.context.create_type('String', builtin=True) + self.context.create_type('Bool', builtin=True) self.parents['Object'] = None self.parents['IO'] = 'Object' @@ -24,17 +25,21 @@ def __init__(self, errors = []): self.parents['String'] = 'Object' self.parents['Bool'] = 'Object' + @property + def parents(self): + return self.context.inheritance + def ciclic_heritage(self, name, parent): if parent is None: return False if name == parent: return True return self.ciclic_heritage(name, self.parents[parent]) - + @visitor.on('node') def visit(self, node): pass - + @visitor.when(ProgramNode) def visit(self, node): for class_def in node.declarations: @@ -45,12 +50,14 @@ def visit(self, node): if declaration.id.lex not in self.parents.keys(): self.parents[declaration.id.lex] = 'Object' if declaration.parent == None else declaration.parent.lex if declaration.parent != None and declaration.parent.lex in self.parents.keys() and self.ciclic_heritage(declaration.id.lex, declaration.parent.lex): - self.errors.append(ERROR_ON_LN_COL % (declaration.line, declaration.column) + "SemanticError: " + CYCLIC_HERITAGE % (declaration.id.lex)) + self.errors.append(ERROR_ON_LN_COL % ( + declaration.line, declaration.column) + "SemanticError: " + CYCLIC_HERITAGE % (declaration.id.lex)) break - + @visitor.when(ClassDeclarationNode) def visit(self, node): try: self.context.create_type(node.id.lex) except SemanticError as se: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + se.text) \ No newline at end of file + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "SemanticError: " + se.text) From 108332f71d99cbe69c8db22850f1e88f86af30d7 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 11 Dec 2020 14:04:27 -0500 Subject: [PATCH 091/191] latest change --- src/engine/codegen/cil.py | 27 +- src/engine/codegen/cil_ast.py | 4 + src/engine/codegen/cil_format.py | 4 + src/engine/codegen/mips.py | 38 +- src/engine/codegen/to_cil.py | 1 + src/engine/codegen/to_mips.py | 79 +- src/test.mips | 2419 ++++++++++-------------------- 7 files changed, 846 insertions(+), 1726 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 17ace480..54548faf 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -118,17 +118,13 @@ def define_string_type(self): no_error_label3 = LabelNode("error3") self.register_instruction(BoxNode(zero, 0)) self.register_instruction(LengthNode(length_var, self_param)) - eol = self.register_data('\n').name - eol_dest = self.define_internal_local() - self.register_instruction(LoadNode(eol_dest, eol)) + eol = self.register_data('\\n').name msg_eol = self.define_internal_local() self.register_instruction(LessEqNode(cmp_var1, zero, start)) self.register_instruction(IfGotoNode(cmp_var1, no_error_label1.label)) error_msg = self.register_data("Invalid substring start").name - error_dest = self.define_internal_local() - self.register_instruction(LoadNode(error_dest, error_msg)) - self.register_instruction(ConcatNode(msg_eol, error_dest, eol_dest)) + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label1) @@ -136,7 +132,7 @@ def define_string_type(self): self.register_instruction(LessEqNode(cmp_var2, zero, length)) self.register_instruction(IfGotoNode(cmp_var2, no_error_label2.label)) error_msg = self.register_data("Invalid substring length").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol_dest)) + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label2) @@ -145,7 +141,7 @@ def define_string_type(self): self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) error_msg = self.register_data("Invalid substring").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol_dest)) + self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) self.register_instruction(PrintStrNode(msg_eol)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label3) @@ -171,7 +167,6 @@ def define_io_type(self): self.to_function_name(self.current_method.name, type_name)) str_val = self.define_internal_local() self.register_instruction(PrintStrNode(str_val)) - # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_string') @@ -189,7 +184,6 @@ def define_io_type(self): self.to_function_name(self.current_method.name, type_name)) int_val = self.register_param(VariableInfo('int_val', None)) self.register_instruction(PrintIntNode(int_val)) - # self.register_instruction(ReturnNode(0)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_int') @@ -216,9 +210,16 @@ def define_object_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) - # self.register_instruction(PrintStrNode('abort with type')) - self.register_instruction(ErrorNode()) - # self.register_instruction(ReturnNode(0)) + type_name = self.define_internal_local() + abort_msg = self.register_data("Abort called from class ").name + eol = self.register_data('\\n').name + msg = self.define_internal_local() + msg_eol = self.define_internal_local() + self.register_instruction(TypeNameNode(type_name, self_local)) + self.register_instruction(ConcatNode(msg, abort_msg, type_name)) + self.register_instruction(ConcatNode(msg_eol, msg, eol)) + self.register_instruction(PrintStrNode(msg_eol)) + self.register_instruction(AbortNode()) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('copy') diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 37715191..9d422604 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -134,6 +134,10 @@ def __init__(self, dest, value): self.value = value +class AbortNode(InstructionNode): + pass + + class AllocateNode(InstructionNode): def __init__(self, dest, itype): self.dest = dest diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index bf7c4d43..0cbe8b30 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -173,6 +173,10 @@ def visit(self, node: ErrorNode): def visit(self, node: BoxNode): return f'{node.dest} = {node.value}' + @visitor.when(AbortNode) + def visit(self, node: AbortNode): + return f'ABORT' + @visitor.when(NotNode) def visit(self, node: NotNode): return f'{node.dest} = NOT {node.expression}' diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 1c1845cf..deb87886 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -51,9 +51,6 @@ def __init__(self, type_number: int, typex: TypeNode): def set_type(self): for idx, feature in enumerate(self.type.features): if isinstance(feature, str): - # The plus 2 is because the two first elementes - # in the instance are the type_int and the type_str_dir. - # Also enumerate starts with 0 self.attr_offsets[feature] = idx + 2 else: func_name, long_name = feature @@ -85,7 +82,7 @@ def __init__(self): # Meta Functions def compile(self): - return '\n'.join([MipsLabel.data] + self.dotdata + [MipsLabel.text] + self.dotcode) + return '\n'.join([MipsLabel.data] + self.dotdata + [] + [MipsLabel.text] + self.dotcode) def _write(self, line): self.dotcode.append(line) @@ -106,28 +103,29 @@ def asciiz(self, string): self._write_data(f'.asciiz "{string}"') def push(self, register): - self.addi(reg.sp, reg.sp, -8) + self.addi(reg.sp, reg.sp, -4) self.store_memory(register, self.offset(reg.sp)) def pop(self, register): self.load_memory(register, self.offset(reg.sp)) - self.addi(reg.sp, reg.sp, 8) + self.addi(reg.sp, reg.sp, 4) def load_memory(self, dst, address: str): - self.lw(reg.t8, address) - self.sll(reg.t8, reg.t8, 16) - self.la(reg.t7, address) - self.addi(reg.t7, reg.t7, 4) - self.lw(reg.t9, self.offset(reg.t7)) - self.or_(dst, reg.t8, reg.t9) + self.lw(dst, address) + # self.sll(reg.t8, reg.t8, 16) + # self.la(reg.t7, address) + # self.addi(reg.t7, reg.t7, 4) + # self.lw(reg.t9, self.offset(reg.t7)) + # self.or_(dst, reg.t8, reg.t9) def store_memory(self, src: Registers, address: str): - self.la(reg.t8, address) + self.sw(src, address) + # self.la(reg.t8, address) - self.srl(reg.t9, src, 16) + # self.srl(reg.t9, src, 16) - self.sw(reg.t9, self.offset(reg.t8)) # store high bits - self.sw(src, self.offset(reg.t8, 4)) # store low bits + # self.sw(reg.t9, self.offset(reg.t8)) # store high bits + # self.sw(src, self.offset(reg.t8, 4)) # store low bits # System Calls @@ -381,12 +379,18 @@ def jr(self, rsrc): ''' self._write(f'jr {rsrc}') + def jalr(self, rdest): + ''' + Jump and Link Register + ''' + self._write(f"jalr {rdest}") # Load Instructions + def la(self, rdest, address): ''' Load Address ''' - return f'la {rdest}, {address}' + self._write(f'la {rdest}, {address}') def lb(self, rdest, address): ''' diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 8aa108c7..49529323 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -206,6 +206,7 @@ def visit(self, node: cool.LetInNode, scope: Scope): let_scope = Scope(parent=scope) for let_id, let_type, let_expr in node.let_body: let_scope.define_variable(let_id.lex, let_type.lex) + self.register_instruction(LocalNode(let_id.lex)) self.visit(let_expr, let_scope) result = self.define_internal_local() diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 8c26df3d..c9d0aa98 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -7,7 +7,7 @@ class CIL_TO_MIPS: - def __init__(self, data_size=8): + def __init__(self, data_size=4): self.types = [] self.types_offsets: Dict[str, TypeData] = dict() self.arguments = {} @@ -134,15 +134,17 @@ def visit(self, node: FunctionNode): self.visit(local, index=idx) self.store_registers() + self.mips.empty_line() self.mips.comment("Generating body code") for instruction in node.instructions: self.visit(instruction) + self.mips.empty_line() - self.arguments = None self.load_registers() self.mips.comment("Clean stack variable space") self.mips.addi(reg.sp, reg.sp, len(node.localvars) * self.data_size) + self.arguments = None self.mips.comment("Return") self.mips.pop(reg.fp) self.mips.jr(reg.ra) @@ -154,7 +156,7 @@ def visit(self, node: DataNode): @visitor.when(ParamNode) def visit(self, node: ParamNode, index=0): - self.arguments[node.name] = index + self.arguments[node.name] = index + 1 @visitor.when(LocalNode) def visit(self, node: LocalNode, index=0): @@ -162,7 +164,7 @@ def visit(self, node: LocalNode, index=0): if node.name in self.local_vars: pass else: - self.local_vars[node.name] = index + self.local_vars[node.name] = -(index + 1) @visitor.when(GetAttribNode) def visit(self, node: GetAttribNode): @@ -195,12 +197,13 @@ def visit(self, node: SetAttribNode): @visitor.when(AssignNode) def visit(self, node: AssignNode): + print(node.dest, node.source) self.load_memory(reg.t0, node.source) self.store_memory(reg.t0, node.dest) @visitor.when(ComplementNode) def visit(self, node: ComplementNode): - self.load_memory(reg.t0, node.body) + self.load_memory(reg.t0, node.expression) self.mips.nor(reg.t1, reg.t0, reg.t0) self.store_memory(reg.t1, node.dest) @@ -222,7 +225,7 @@ def visit(self, node: MinusNode): def visit(self, node: StarNode): self.load_memory(reg.t0, node.left) self.load_memory(reg.t1, node.right) - self.mips.mult(reg.t2, reg.t0, reg.t1) + self.mips.mult(reg.t0, reg.t1) self.mips.mflo(reg.t0) self.store_memory(reg.t0, node.dest) @@ -280,26 +283,33 @@ def visit(self, node: AllocateNode): type_data = self.types_offsets[node.type] length = len(type_data.attr_offsets) + len(type_data.func_offsets) + 2 - length *= self.data_size / 2 + length *= self.data_size self.mips.li(reg.a0, length) self.mips.sbrk() - self.store_memory(reg.v0, node.dest) - self.mips.li(reg.t0, type_data.pos) - self.mips.store_memory(reg.t0, reg.v0) - self.mips.la(reg.t0, type_data.str) + self.mips.move(reg.s1, reg.v0) + self.store_memory(reg.s1, node.dest) + + self.mips.li(reg.s0, type_data.pos) + self.mips.store_memory(reg.s0, reg.s1) + + self.mips.la(reg.s0, type_data.str) self.mips.store_memory( - reg.t0, self.mips.offset(reg.v0, 1 * self.data_size)) + reg.s0, self.mips.offset(reg.v0, self.data_size)) + + self.mips.li(reg.s0, length) + self.mips.store_memory( + reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) for offset in type_data.attr_offsets.values(): self.mips.store_memory(reg.zero, self.mips.offset( - reg.v0, offset * self.data_size)) + reg.s1, offset * self.data_size)) for name, offset in type_data.func_offsets.items(): direct_name = type_data.func_names[name] - self.mips.la(reg.t0, direct_name) + self.mips.la(reg.s0, direct_name) self.mips.store_memory( - reg.t0, - self.mips.offset(reg.v0, offset * self.data_size)) + reg.s0, + self.mips.offset(reg.s1, offset * self.data_size)) @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): @@ -334,14 +344,11 @@ def visit(self, node: StaticCallNode): def visit(self, node: DynamicCallNode): self.mips.comment("DynamicCallNode") type_data = self.types_offsets[node.type] - offset = type_data.func_offsets[node.method] - self.load_memory(reg.t0, node.obj) - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset)) - label_get_pc = self.get_pc(reg.t2) - self.mips.jal(label_get_pc) - self.mips.move(reg.ra, reg.t2) - self.mips.addi(reg.ra, reg.ra, 12) - self.mips.jr(reg.t1) + offset = type_data.func_offsets[node.method] * self.data_size + self.load_memory(reg.s0, node.obj) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, offset)) + self.mips.jalr(reg.s1) + self.store_memory(reg.v0, node.dest) @visitor.when(ArgNode) def visit(self, node: ArgNode): @@ -360,6 +367,11 @@ def visit(self, node: BoxNode): self.mips.li(reg.s0, node.value) self.store_memory(reg.s0, node.dest) + @visitor.when(AbortNode) + def visit(self, node: AbortNode): + self.mips.exit() + self.mips.empty_line() + def copy_data(self, src, dst, length): """ length: fixed in bytes size. @@ -506,26 +518,9 @@ def visit(self, node: StringEqualNode): self.mips.label(end_label) self.mips.store_memory(reg.v0, node.dest) - @visitor.when(ConcatNode) - def visit(self, node): - self.load_memory(reg.s0, node.msg1) - self.load_memory(reg.s1, node.msg2) - - self.get_string_length(reg.s0, reg.s4) - self.get_string_length(reg.s1, reg.s5) - - self.mips.add(reg.a0, reg.s4, reg.s5) - self.mips.sbrk() - self.mips.move(reg.s3, reg.v0) - - self.copy_str(reg.s0, reg.s3, reg.v0) - self.copy_str(reg.s1, reg.v0, reg.v0) - - self.store_memory(reg.s3, node.dest) - @visitor.when(LoadNode) def visit(self, node: LoadNode): - self.load_memory(reg.t0, node.dest) + self.load_memory(reg.t0, node.msg) def copy_substr(self, src, dst, length): loop = self.get_label() diff --git a/src/test.mips b/src/test.mips index 3182e6d6..2de02735 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,14 +1,17 @@ .data data_0 -.asciiz " -" +.asciiz "Abort called from class " data_1 -.asciiz "Invalid substring start" +.asciiz "\n" data_2 -.asciiz "Invalid substring length" +.asciiz "\n" data_3 -.asciiz "Invalid substring" +.asciiz "Invalid substring start" data_4 +.asciiz "Invalid substring length" +data_5 +.asciiz "Invalid substring" +data_6 .asciiz "Hello, World.n" .text main: @@ -18,169 +21,200 @@ li $v0, 10 syscall function_abort_at_Object: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code -# ErrorNode -li $a0, 1 -li $v0, 17 +# TypeNameNode +lw $t0, 8($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) +la $s0, data_0 +lw $s1, 4($fp) +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +sw $s3, 8($fp) +lw $s0, 8($fp) +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mip_label_0: +lb $t3, 0($t0) +beqz $t3, mip_label_0 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mip_label_0 +mip_label_0: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mip_label_0: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mip_label_0 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mip_label_0 +mip_label_0: +move $v0, $t1 +sw $s3, 12($fp) +lw $a0, 12($fp) +li $v0, 4 +syscall +li $v0, 10 syscall -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 + +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 0 +addi $sp, $sp, 12 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_copy_at_Object: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code +la $s1, -4($fp) li $s3, 0 move $t0, $s0 move $t1, $s1 @@ -195,285 +229,129 @@ beqz $t3, mip_label_0 j mip_label_0 mip_label_0: # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_type_name_at_Object: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code # TypeOfNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, $s0 -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) +lw $s0, 8($fp) +lw $s1, $s0 +sw $s1, 8($fp) # TypeNameNode -lw $t8, -8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 8($t0) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 -srl $t9, $t1, 16 -sw $t9, 0($t8) -sw $t1, 4($t8) +lw $t0, 8($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_length_at_String: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code # LengthNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +lw $s1, 8($fp) move $t0, $s1 li $t1, 0 mip_label_0: @@ -484,140 +362,65 @@ addi $t0, $t0, 1 j mip_label_0 mip_label_0: move $s0, $t1 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) +sw $s0, 4($fp) # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_concat_at_String: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +lw $s0, 8($fp) +lw $s1, 12($fp) move $t0, $s0 li $t1, 0 mip_label_0: @@ -664,180 +467,83 @@ addi $t1, $t1, 1 j mip_label_0 mip_label_0: move $v0, $t1 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) +sw $s3, 4($fp) # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_substr_at_String: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code li $s0, 0 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) +sw $s0, 16($fp) # LengthNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +lw $s1, 8($fp) move $t0, $s1 li $t1, 0 mip_label_0: @@ -848,53 +554,19 @@ addi $t0, $t0, 1 j mip_label_0 mip_label_0: move $s0, $t1 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -lw $t8, -64($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, -24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 +sw $s0, 12($fp) +lw $t0, 16($fp) +lw $t1, 12($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) +sw $t0, 24($fp) # IfGotoNode -lw $t8, -40($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 +lw $t0, 24($fp) li $t1, 0 bne $t0, $t1, error1 -lw $t8, -80($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, -80($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, -64($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +la $s0, data_3 +la $s1, data_2 move $t0, $s0 li $t1, 0 mip_label_0: @@ -941,14 +613,8 @@ addi $t1, $t1, 1 j mip_label_0 mip_label_0: move $v0, $t1 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -lw $t8, -72($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 +sw $s3, 36($fp) +lw $a0, 36($fp) li $v0, 4 syscall # ErrorNode @@ -956,35 +622,18 @@ li $a0, 1 li $v0, 17 syscall error1: -lw $t8, -24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 +lw $t0, 16($fp) +lw $t1, 16($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) +sw $t0, 28($fp) # IfGotoNode -lw $t8, -48($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 +lw $t0, 28($fp) li $t1, 0 bne $t0, $t1, error2 -lw $t8, -64($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +la $s0, data_4 +la $s1, data_2 move $t0, $s0 li $t1, 0 mip_label_0: @@ -1031,14 +680,8 @@ addi $t1, $t1, 1 j mip_label_0 mip_label_0: move $v0, $t1 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -lw $t8, -72($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 +sw $s3, 36($fp) +lw $a0, 36($fp) li $v0, 4 syscall # ErrorNode @@ -1046,49 +689,22 @@ li $a0, 1 li $v0, 17 syscall error2: -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 +lw $t0, 12($fp) +lw $t1, 16($fp) add $t2, $t0, $t1 -srl $t9, $t2, 16 -sw $t9, 0($t8) -sw $t2, 4($t8) -lw $t8, -32($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, -16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 +sw $t2, 20($fp) +lw $t0, 20($fp) +lw $t1, 12($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) +sw $t0, 32($fp) # IfGotoNode -lw $t8, -56($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 +lw $t0, 32($fp) li $t1, 0 bne $t0, $t1, error3 -lw $t8, -64($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 +la $s0, data_5 +la $s1, data_2 move $t0, $s0 li $t1, 0 mip_label_0: @@ -1135,14 +751,8 @@ addi $t1, $t1, 1 j mip_label_0 mip_label_0: move $v0, $t1 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -lw $t8, -72($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 +sw $s3, 36($fp) +lw $a0, 36($fp) li $v0, 4 syscall # ErrorNode @@ -1150,21 +760,9 @@ li $a0, 1 li $v0, 17 syscall error3: -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -lw $t8, 24($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -lw $t8, 16($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 +lw $s0, 8($fp) +lw $s1, 16($fp) +lw $s3, 12($fp) add $s0, $s0, $s3 move $a0, $s1 li $v0, 9 @@ -1183,917 +781,430 @@ j mip_label_0 mip_label_0: move $t2, $zero sb $t2, 0($t1) -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) +sw $v0, 4($fp) # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 88 +addi $sp, $sp, 36 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_out_string_at_IO: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 +lw $a0, 4($fp) li $v0, 4 syscall -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_in_string_at_IO: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code li $a0, 1024 li $v0, 9 syscall move $a0, $v0 -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) +sw $v0, 4($fp) li $a1, 1024 li $v0, 8 syscall # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_out_int_at_IO: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $a0, $t8, $t9 +lw $a0, 8($fp) li $v0, 1 syscall -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space addi $sp, $sp, 0 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_in_int_at_IO: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code li $v0, 5 syscall -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) +sw $v0, 4($fp) # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 8 +addi $sp, $sp, 4 # Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 -addi $sp, $sp, 8 +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra entry: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code li $a0, 40 li $v0, 9 syscall -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -li $t0, 3 -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) -srl $t9, $t0, 16 -sw $t9, 0($t8) -sw $t0, 4($t8) +move $s1, $v0 +sw $s1, 4($fp) +li $s0, 3 +sw $s0, $s1 +la $s0, +sw $s0, 4($v0) +li $s0, 40 +sw $s0, 8($s1) +la $s0, function_abort_at_Object +sw $s0, 8($s1) +la $s0, function_type_name_at_Object +sw $s0, 12($s1) +la $s0, function_copy_at_Object +sw $s0, 16($s1) +la $s0, function_out_string_at_IO +sw $s0, 20($s1) +la $s0, function_out_int_at_IO +sw $s0, 24($s1) +la $s0, function_in_string_at_IO +sw $s0, 28($s1) +la $s0, function_in_int_at_IO +sw $s0, 32($s1) +la $s0, function_main_at_Main +sw $s0, 36($s1) # ArgNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) # StaticCallNode jal function_main_at_Main -srl $t9, $v0, 16 -sw $t9, 0($t8) -sw $v0, 4($t8) -addi $sp, $sp, 8 +sw $v0, 8($fp) +addi $sp, $sp, 4 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra function_main_at_Main: # Set stack frame -addi $sp, $sp, -8 -srl $t9, $fp, 16 -sw $t9, 0($t8) -sw $fp, 4($t8) +addi $sp, $sp, -4 +sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $zero, 16 -sw $t9, 0($t8) -sw $zero, 4($t8) -addi $sp, $sp, -8 -srl $t9, $ra, 16 -sw $t9, 0($t8) -sw $ra, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s1, 16 -sw $t9, 0($t8) -sw $s1, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s2, 16 -sw $t9, 0($t8) -sw $s2, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s3, 16 -sw $t9, 0($t8) -sw $s3, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s4, 16 -sw $t9, 0($t8) -sw $s4, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s5, 16 -sw $t9, 0($t8) -sw $s5, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s6, 16 -sw $t9, 0($t8) -sw $s6, 4($t8) -addi $sp, $sp, -8 -srl $t9, $s7, 16 -sw $t9, 0($t8) -sw $s7, 4($t8) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $zero, 0($sp) +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) +addi $sp, $sp, -4 +sw $s7, 0($sp) + # Generating body code -lw $t8, -8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 +la $s0, data_6 # ArgNode -lw $t8, -8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) # ArgNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, -8 -srl $t9, $s0, 16 -sw $t9, 0($t8) -sw $s0, 4($t8) +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) # DynamicCallNode -lw $t8, 8($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t0, $t8, $t9 -lw $t8, 5($t0) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $t1, $t8, $t9 -j mip_label_0 -mip_label_0: -move $t2, $ra -jr $ra -mip_label_0: -jal mip_label_0 -move $ra, $t2 -addi $ra, $ra, 12 -jr $t1 -addi $sp, $sp, 16 +lw $s0, 8($fp) +lw $s1, 20($s0) +jalr $s1 +sw $v0, 4($fp) +addi $sp, $sp, 8 # ReturnNode -lw $t8, 0($fp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $v0, $t8, $t9 +lw $v0, 4($fp) -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s7, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s6, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s5, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s4, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s3, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s2, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s1, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $s0, $t8, $t9 -addi $sp, $sp, 8 -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $ra, $t8, $t9 -addi $sp, $sp, 8 +lw $s7, 0($sp) +addi $sp, $sp, 4 +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 16 -# Return -lw $t8, 0($sp) -sll $t8, $t8, 16 -addi $t7, $t7, 4 -lw $t9, 0($t7) -or $fp, $t8, $t9 addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 jr $ra \ No newline at end of file From a78ef241655c6e62616f3af317bafe0e4adbb8cc Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Fri, 11 Dec 2020 17:03:09 -0500 Subject: [PATCH 092/191] case of node good implementation --- src/engine/codegen/cil.py | 4 +++ src/engine/codegen/cil_ast.py | 7 +++++ src/engine/codegen/to_cil.py | 51 +++++++++++++++++++++++++++----- src/engine/cp/semantic.py | 5 ++++ src/engine/parser/ast_parser.py | 6 ++-- src/engine/parser/cool_parser.py | 6 ++-- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 5187ef69..ec4030a4 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -66,6 +66,10 @@ def register_data(self, value): self.dotdata.append(data_node) return data_node + def sort_case_list(self, case_expressions): + return sorted(case_expressions, reverse=True, + key=lambda x: self.context.inheritance_deep(x.type)) + ################################### def define_string_type(self): diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 1cf0a8d4..e8b97711 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -56,6 +56,13 @@ def __init__(self, dest, obj, attrib, typex): self.type = typex +class ConformsNode(InstructionNode): + def __init__(self, dest, expr, type_test): + self.dest = dest + self.expr = expr # variable id + self.type = type_test + + class SetAttribNode(InstructionNode): def __init__(self, obj, attrib, value, typex): self.obj = obj diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index efc7b7f5..06c7d869 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -181,23 +181,56 @@ def visit(self, node: cool.WhileLoopNode, scope): return 0 @visitor.when(cool.CaseOfNode) - def visit(self, node: cool.CaseOfNode, scope): + def visit(self, node: cool.CaseOfNode, scope: Scope): expr = self.visit(node.expression, scope) result = self.define_internal_local() - exptype = self.define_internal_local() + exp_type = self.define_internal_local() end_label = LabelNode('END') - self.register_instruction(TypeOfNode(expr, exptype)) + error_label = LabelNode(f'ERROR_CASE_{node.id}') + # TODO: Label error logic if is void + self.register_instruction(TypeOfNode(expr, exp_type)) - for i, case in enumerate(node.branches): + case_expressions = self.sort_case_list(node.branches) + + for i, case in enumerate(case_expressions): + next_branch_label = LabelNode(f'CASE_{case.id}_{i}') child_scope = Scope(parent=scope) - expr_n = self.visit(case, child_scope) - self.register_instruction(AssignNode(result, expr_n)) + expr_i = self.visit( + case, child_scope, + expr=expr, + expr_type=exp_type, + next_label=next_branch_label, + ) + self.register_instruction(AssignNode(result, expr_i)) self.register_instruction(GotoNode(end_label.label)) - self.register_instruction(LabelNode(f'CASE_{i}')) + self.register_instruction(next_branch_label) + + self.register_instruction(error_label) + # TODO: specify the message error here [ i think :/ ] + self.register_instruction(ErrorNode()) self.register_instruction(end_label) return result + @visitor.when(cool.CaseActionExpression) + def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_type=None, next_label=None): + test_res = self.define_internal_local() + + matching_label = LabelNode('CASE_MATCH_{node.id}_{node.typex}') + self.register_instruction(ConformsNode(test_res, expr, node.typex)) + self.register_instruction(IfGotoNode(expr, matching_label)) + self.register_instruction( + GotoNode(next_label.label) + ) + self.register_instruction(matching_label) + l_var = self.define_internal_local() + typex = self.context.get_type(node.type) + scope.define_variable(l_var, typex) + self.register_instruction(AssignNode(l_var, expr)) + + case_action_expr = self.visit(node.expression, scope) + return case_action_expr + @visitor.when(cool.LetInNode) def visit(self, node: cool.LetInNode, scope: Scope): let_scope = Scope(parent=scope) @@ -226,7 +259,9 @@ def visit(self, node: cool.FunctionCallNode, scope): self.register_instruction(ArgNode(arg_value)) obj = self.visit(node.obj, scope) self.register_instruction(ArgNode(obj)) - self.register_instruction(StaticCallNode(name, result)) if name else \ + if name: + self.register_instruction(StaticCallNode(name, result)) + else: self.register_instruction( DynamicCallNode(typex, node.id.lex, result)) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index de95157f..54526bd3 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -234,6 +234,11 @@ def get_type(self, name: str): except KeyError: raise SemanticError(f'Type "{name}" is not defined.') + def inheritance_deep(self, type_name: str) -> int: + if type_name not in self.inheritance: + return 0 + return 1 + self.inheritance_deep(self.inheritance[type_name]) + def __str__(self): return '{\n\t' + '\n\t'.join(y for x in self.types.values() for y in str(x).split('\n')) + '\n}' diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py index 2defa961..c51b9b7d 100644 --- a/src/engine/parser/ast_parser.py +++ b/src/engine/parser/ast_parser.py @@ -33,7 +33,7 @@ def __iter__(self): yield from (self.id, self.type, self.expression) -class CaseVariableDeclaration(DeclarationNode): +class CaseActionExpression(DeclarationNode): def __init__(self, idx, typex, expression=Node): self.id = idx self.type = typex @@ -197,13 +197,11 @@ def __init__(self, obj, idx, args, typex=None): self.type = typex self.line = idx.line self.column = idx.column - + def __iter__(self): yield from (self.id, self.type, self.expression) - - class MemberCallNode(ExpressionNode): def __init__(self, idx, args): self.id = idx diff --git a/src/engine/parser/cool_parser.py b/src/engine/parser/cool_parser.py index 34051a61..15a22ffb 100644 --- a/src/engine/parser/cool_parser.py +++ b/src/engine/parser/cool_parser.py @@ -218,11 +218,11 @@ def p_case_list(self, p): '''case_list : ID COLON TYPE ACTION expr SEMI | ID COLON TYPE ACTION expr SEMI case_list ''' if len(p) == 7: - p[0] = [CaseVariableDeclaration( + p[0] = [CaseActionExpression( p.slice[1], p.slice[3], p[5])] else: - p[0] = [CaseVariableDeclaration( - p.slice[1], p.slice[3], p[5])] + p[7] + p[0] = [CaseActionExpression( + p.slice[1], p.slice[3], p[5])] + p[7] def p_case_list_error(self, p): '''case_list : error COLON TYPE ACTION expr SEMI From fa75e51e71f0e9803882c617c50b0a252b052a20 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Fri, 11 Dec 2020 17:33:52 -0500 Subject: [PATCH 093/191] let in node good implementation --- src/engine/codegen/to_cil.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 06c7d869..ad675732 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -234,15 +234,23 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_t @visitor.when(cool.LetInNode) def visit(self, node: cool.LetInNode, scope: Scope): let_scope = Scope(parent=scope) - for let_id, let_type, let_expr in node.let_body: - let_scope.define_variable(let_id.lex, let_type.lex) - self.visit(let_expr, let_scope) + for var_decl in node.let_body: + let_scope.define_variable(var_decl.id, var_decl.type) + self.visit(var_decl, let_scope) - result = self.define_internal_local() - expr = self.visit(node.in_body, let_scope) - self.register_instruction(AssignNode(result, expr)) + result = self.visit(node.in_body, let_scope) return result + @visitor.when(cool.LetVariableDeclaration) + def visit(self, node: cool.LetVariableDeclaration, scope: Scope): + var_info = scope.find_variable(node.id) + local_var = self.register_local(var_info.name) + + value = self.visit(node.expression, scope) + + self.register_instruction(AssignNode(local_var, value)) + return local_var + @visitor.when(cool.FunctionCallNode) def visit(self, node: cool.FunctionCallNode, scope): if not (node.type): From d2123b661d0be9a37000b69d48a5be436b88f688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 13:38:35 -0500 Subject: [PATCH 094/191] add word_size and string_max_size --- src/engine/codegen/mips.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index deb87886..80231176 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -2,6 +2,10 @@ from typing import Dict, List from .cil_ast import TypeNode +word_size = 2 + +string_max_size = 1000 + class Registers: zero = '$zero' # Constant 0 From 3b18eddf5fd2153a67917360182301ec52d96f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 13:53:46 -0500 Subject: [PATCH 095/191] Add Vtable class --- src/engine/codegen/mips.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 80231176..8f3a8b62 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -6,6 +6,20 @@ string_max_size = 1000 +class VTable: + + def __init__(self, methods): + self.methods = methods + + def size(self): + return len(self.methods) + + def __getitem__(self, name): + return self.methods[name] + + def get_index(self, name): + return list(self.methods.keys()).index(name) + class Registers: zero = '$zero' # Constant 0 From 292ad4849d7e41c10fa0a652edb82b1c5af98497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 14:07:47 -0500 Subject: [PATCH 096/191] Add MemoryType class --- src/engine/codegen/mips.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 8f3a8b62..4d55239b 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -20,6 +20,27 @@ def __getitem__(self, name): def get_index(self, name): return list(self.methods.keys()).index(name) +class MemoryType: + + def __init__(self, name, id, attrs, methods, base_index, ptr_name): + self.name = name + self.id = id + self.attrs = attrs + self.methods = methods + self.vtable = base_index + self.ptr_name = ptr_name + + def size(self): + return 4 + len(self.attrs) + + def get_attr_index(self, attr): + return 4 + self.attrs.index(attr) + + def get_method_index(self, method): + return self.vtable + self.methods.index(method) + + def get_ptr_name(self): + return self.ptr_name class Registers: zero = '$zero' # Constant 0 From 9d507a79ceb64efa67f1c672ca160bb9dc0efea3 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Mon, 14 Dec 2020 14:59:00 -0500 Subject: [PATCH 097/191] bugfixing cool_to_cil visitor --- src/engine/codegen/cil.py | 8 ++- src/engine/codegen/cil_ast.py | 4 +- src/engine/codegen/cil_format.py | 6 +- src/engine/codegen/to_cil.py | 107 +++++++++++++++++++------------ src/engine/visitors/collector.py | 4 -- 5 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index ec4030a4..07e41bd3 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -10,12 +10,16 @@ def __init__(self, context): self.current_type = None self.current_method = None self.current_function = None - self.label_counter = 0 self.context = context + self._label_counter = 0 self.define_object_type() self.define_string_type() self.define_io_type() + def label_counter_gen(self): + self._label_counter += 1 + return self._label_counter + @property def params(self): return self.current_function.params @@ -70,7 +74,7 @@ def sort_case_list(self, case_expressions): return sorted(case_expressions, reverse=True, key=lambda x: self.context.inheritance_deep(x.type)) - ################################### + ################################### def define_string_type(self): self.current_type = self.context.get_type('String') diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index e8b97711..14f118d5 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -57,10 +57,10 @@ def __init__(self, dest, obj, attrib, typex): class ConformsNode(InstructionNode): - def __init__(self, dest, expr, type_test): + def __init__(self, dest, expr, typex): self.dest = dest self.expr = expr # variable id - self.type = type_test + self.type = typex class SetAttribNode(InstructionNode): diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index e5c03f40..0fa6285a 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -169,9 +169,9 @@ def visit(self, node: EqualNode): def visit(self, node: ErrorNode): return f'ERROR {node.error}' - # @visitor.when(ConformNode) - # def visit(self, node: ConformNode): - # return f'{node.dest} = COMFORM {node.obj} {node.type}' + @visitor.when(ConformsNode) + def visit(self, node: ConformsNode): + return f'{node.dest} = COMFORM {node.expr} {node.type}' @visitor.when(NotNode) def visit(self, node: NotNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index ad675732..dc459e47 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -1,4 +1,5 @@ from engine import parser as cool +from engine.cp.semantic import Context from .cil_ast import * from ..cp import visitor from ..cp.semantic import VariableInfo, Scope @@ -20,24 +21,38 @@ def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): self.register_instruction(cil_node(result, expr)) return result + def sort_class_declar(self, program: cool.ProgramNode): + self.context: Context + program.declarations = sorted( + ( + declaration + for declaration in program.declarations + if isinstance(declaration, cool.ClassDeclarationNode) + ), + reverse=True, + key=lambda cd: self.context.inheritance_deep(cd.id.lex), + ) + def init_class_attr(self, scope: Scope, class_id, self_inst): attr_nodes = self.attr_init[class_id] for attr in attr_nodes: - attr_scope = Scope(parent=scope) + attr_scope = scope.create_child() attr_scope.define_variable('self', self_inst) self.visit(attr, attr_scope) def save_attr_init(self, node: cool.ProgramNode): self.attr_init = dict() - classes = [declaration for declaration in node.declarations if isinstance( - declaration, cool.ClassDeclarationNode)] - for declaration in classes: + for declaration in node.declarations: self.attr_init[declaration.id.lex] = [] if declaration.parent and not declaration.parent.lex in ['IO', 'Object']: self.attr_init[declaration.id.lex] += self.attr_init[declaration.parent.lex] - for feature in declaration.features: - if isinstance(feature, cool.AttrDeclarationNode): - self.attr_init[declaration.id.lex].append(feature) + self.attr_init[declaration.id.lex] += [ + feature for feature in declaration.features + if isinstance(feature, cool.AttrDeclarationNode) + ] + + def create_vtables(self, node: cool.ProgramNode): + pass @visitor.on('node') def visit(self, node, scope): @@ -46,7 +61,10 @@ def visit(self, node, scope): @visitor.when(cool.ProgramNode) def visit(self, node: cool.ProgramNode, scope=None): scope = Scope() + self.sort_class_declar(node) self.save_attr_init(node) + self.create_vtables(node) + # entry self.current_function = self.register_function('entry') instance = self.define_internal_local() result = self.define_internal_local() @@ -56,17 +74,22 @@ def visit(self, node: cool.ProgramNode, scope=None): self.register_instruction(ArgNode(instance)) name = self.to_function_name('main', 'Main') self.register_instruction(StaticCallNode(name, result)) + # end entry + self.current_function = None - classes = [declaration for declaration in node.declarations if isinstance( - declaration, cool.ClassDeclarationNode)] + classes = [ + declaration + for declaration in node.declarations + if isinstance(declaration, cool.ClassDeclarationNode) + ] for declaration in classes: - self.visit(declaration, scope) + self.visit(declaration, scope.create_child()) return ProgramNode(self.dottypes, self.dotdata, self.dotcode) @visitor.when(cool.ClassDeclarationNode) - def visit(self, node: cool.ClassDeclarationNode, scope): + def visit(self, node: cool.ClassDeclarationNode, scope: Scope): self.current_type = self.context.get_type(node.id.lex) type_node = self.register_type(node.id.lex) type_node.attributes = [(attr.name) @@ -83,7 +106,7 @@ def visit(self, node: cool.ClassDeclarationNode, scope): @visitor.when(cool.FuncDeclarationNode) def visit(self, node: cool.FuncDeclarationNode, scope: Scope): - fun_scope = Scope(parent=scope) + fun_scope = scope.create_child() self.current_method = self.current_type.get_method(node.id.lex) type_name = self.current_type.name @@ -116,16 +139,16 @@ def visit(self, node: cool.BlockNode, scope): return result @visitor.when(cool.AssignNode) - def visit(self, node: cool.AssignNode, scope): + def visit(self, node: cool.AssignNode, scope: Scope): expr = self.visit(node.expression, scope) - attr_info = scope.find_variable(node.id.lex) - if not attr_info: + var_info = scope.find_variable(node.id.lex) + if not var_info: selfx = scope.find_variable('self').name self.register_instruction(SetAttribNode( selfx, node.id.lex, expr, self.current_type.name)) else: - attr_info = attr_info.name - self.register_instruction(AssignNode(attr_info, expr)) + var_info = var_info.name + self.register_instruction(AssignNode(var_info, expr)) return 0 @visitor.when(cool.NewNode) @@ -138,14 +161,15 @@ def visit(self, node: cool.NewNode, scope): @visitor.when(cool.IfThenElseNode) def visit(self, node: cool.IfThenElseNode, scope): + label_counter = self.label_counter_gen() cond = self.visit(node.condition, scope) - child_scope = Scope(parent=scope) - true_label = LabelNode(f'TRUE_{self.label_counter}') - end_label = LabelNode(f'END_{self.label_counter}') + child_scope = scope.create_child() + true_label = LabelNode(f'TRUE_{label_counter}') + end_label = LabelNode(f'END_{label_counter}') result = self.define_internal_local() self.register_instruction(IfGotoNode( cond, true_label.label)) - self.label_counter += 1 + label_counter += 1 false_expr = self.visit(node.else_body, child_scope) self.register_instruction(AssignNode(result, false_expr)) self.register_instruction( @@ -155,16 +179,17 @@ def visit(self, node: cool.IfThenElseNode, scope): true_expr = self.visit(node.if_body, child_scope) self.register_instruction(AssignNode(result, true_expr)) self.register_instruction(end_label) - self.label_counter = 0 + label_counter = self.label_counter_gen() return result @visitor.when(cool.WhileLoopNode) def visit(self, node: cool.WhileLoopNode, scope): - while_scope = Scope(parent=scope) - start_label = LabelNode(f'START_{self.label_counter}') - continue_label = LabelNode(f'CONTINUE_{self.label_counter}') - end_label = LabelNode(f'END_{self.label_counter}') + while_scope = scope.create_child() + label_counter = self.label_counter_gen() + start_label = LabelNode(f'START_{label_counter}') + continue_label = LabelNode(f'CONTINUE_{label_counter}') + end_label = LabelNode(f'END_{label_counter}') self.register_instruction(start_label) @@ -173,28 +198,29 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) self.visit(node.body, while_scope) - self.label_counter += 1 + label_counter = self.label_counter_gen() self.register_instruction(GotoNode(start_label.label)) self.register_instruction(end_label) - self.label_counter = 0 return 0 @visitor.when(cool.CaseOfNode) def visit(self, node: cool.CaseOfNode, scope: Scope): + label_counter = self.label_counter_gen() expr = self.visit(node.expression, scope) result = self.define_internal_local() exp_type = self.define_internal_local() - end_label = LabelNode('END') - error_label = LabelNode(f'ERROR_CASE_{node.id}') + end_label = LabelNode(f'END_{label_counter}') + error_label = LabelNode(f'ERROR_CASE_{label_counter}') # TODO: Label error logic if is void self.register_instruction(TypeOfNode(expr, exp_type)) case_expressions = self.sort_case_list(node.branches) for i, case in enumerate(case_expressions): - next_branch_label = LabelNode(f'CASE_{case.id}_{i}') - child_scope = Scope(parent=scope) + next_branch_label = LabelNode(f'CASE_{case.id.lex}_{i}') + child_scope = scope.create_child() + print(exp_type) expr_i = self.visit( case, child_scope, expr=expr, @@ -216,15 +242,15 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_type=None, next_label=None): test_res = self.define_internal_local() - matching_label = LabelNode('CASE_MATCH_{node.id}_{node.typex}') - self.register_instruction(ConformsNode(test_res, expr, node.typex)) + matching_label = LabelNode(f'CASE_MATCH_{node.id.lex}_{node.type.lex}') + self.register_instruction(ConformsNode(test_res, expr, node.type)) self.register_instruction(IfGotoNode(expr, matching_label)) self.register_instruction( GotoNode(next_label.label) ) self.register_instruction(matching_label) l_var = self.define_internal_local() - typex = self.context.get_type(node.type) + typex = self.context.get_type(node.type.lex) scope.define_variable(l_var, typex) self.register_instruction(AssignNode(l_var, expr)) @@ -233,9 +259,9 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_t @visitor.when(cool.LetInNode) def visit(self, node: cool.LetInNode, scope: Scope): - let_scope = Scope(parent=scope) + let_scope = scope.create_child() for var_decl in node.let_body: - let_scope.define_variable(var_decl.id, var_decl.type) + let_scope.define_variable(var_decl.id.lex, var_decl.type) self.visit(var_decl, let_scope) result = self.visit(node.in_body, let_scope) @@ -243,8 +269,8 @@ def visit(self, node: cool.LetInNode, scope: Scope): @visitor.when(cool.LetVariableDeclaration) def visit(self, node: cool.LetVariableDeclaration, scope: Scope): - var_info = scope.find_variable(node.id) - local_var = self.register_local(var_info.name) + var_info = scope.find_variable(node.id.lex) + local_var = self.register_local(var_info) value = self.visit(node.expression, scope) @@ -253,11 +279,12 @@ def visit(self, node: cool.LetVariableDeclaration, scope: Scope): @visitor.when(cool.FunctionCallNode) def visit(self, node: cool.FunctionCallNode, scope): + name = None if not (node.type): typex = self.context.get_type(node.obj.static_type.name).name else: typex = node.type.lex - name = self.to_function_name(node.id.lex, typex) + name = self.to_function_name(node.id.lex, typex) result = self.define_internal_local() rev_args = [] for arg in node.args: diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index e62d8e3c..766c1a89 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -25,10 +25,6 @@ def __init__(self, errors=[]): self.parents['String'] = 'Object' self.parents['Bool'] = 'Object' - @property - def parents(self): - return self.context.inheritance - def ciclic_heritage(self, name, parent): if parent is None: return False From daf17f2843da83e461a34602e0b65d798c969ae7 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 14 Dec 2020 15:44:39 -0500 Subject: [PATCH 098/191] built-in types defined --- src/engine/codegen/cil.py | 21 + src/engine/codegen/cil_format.py | 2 +- src/engine/codegen/to_cil.py | 3 +- src/main.py | 9 +- src/test.cl | 145 ++++- src/test.mips | 938 ++++++++++++++----------------- 6 files changed, 587 insertions(+), 531 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 07e41bd3..88d8a408 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -15,6 +15,8 @@ def __init__(self, context): self.define_object_type() self.define_string_type() self.define_io_type() + self.define_int_type() + self.define_bool_type() def label_counter_gen(self): self._label_counter += 1 @@ -76,11 +78,30 @@ def sort_case_list(self, case_expressions): ################################### + def define_int_type(self): + self.current_type = self.context.get_type('Int') + type_node = self.register_type('Int') + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.attributes.append('value') + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + + def define_bool_type(self): + self.current_type = self.context.get_type('Bool') + type_node = self.register_type('Bool') + type_node.attributes = [(attr.name) + for attr in self.current_type.all_attributes()] + type_node.attributes.append('value') + type_node.methods = [(method.name, self.to_function_name( + method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] + def define_string_type(self): self.current_type = self.context.get_type('String') type_node = self.register_type('String') type_node.attributes = [(attr.name) for attr in self.current_type.all_attributes()] + type_node.attributes.append('value') type_node.methods = [(method.name, self.to_function_name( method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 0fa6285a..3a8c934d 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -129,7 +129,7 @@ def visit(self, node: GetAttribNode): @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): - return f'SETATTR {node.obj} {node.attrib} {node.value}' + return f'SETATTR {node.attrib} OF {node.obj}_{node.type} = {node.value}' @visitor.when(LabelNode) def visit(self, node: LabelNode): diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index dc459e47..9dc4924e 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -44,7 +44,7 @@ def save_attr_init(self, node: cool.ProgramNode): self.attr_init = dict() for declaration in node.declarations: self.attr_init[declaration.id.lex] = [] - if declaration.parent and not declaration.parent.lex in ['IO', 'Object']: + if declaration.parent and not declaration.parent.lex in ['IO', 'Int', 'String', 'Bool', 'Object']: self.attr_init[declaration.id.lex] += self.attr_init[declaration.parent.lex] self.attr_init[declaration.id.lex] += [ feature for feature in declaration.features @@ -220,7 +220,6 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): for i, case in enumerate(case_expressions): next_branch_label = LabelNode(f'CASE_{case.id.lex}_{i}') child_scope = scope.create_child() - print(exp_type) expr_i = self.visit( case, child_scope, expr=expr, diff --git a/src/main.py b/src/main.py index a76a59ce..298629cf 100644 --- a/src/main.py +++ b/src/main.py @@ -70,12 +70,13 @@ cil = COOL_TO_CIL(checker.context) cil_ast = cil.visit(ast) -emsamb = CIL_TO_MIPS() -emsamb.visit(cil_ast) +# emsamb = CIL_TO_MIPS() +# emsamb.visit(cil_ast) -m_ast = emsamb.mips.compile() +# f_ast = emsamb.mips.compile() +f_ast = CIL_FORMATTER().visit(cil_ast) -string_formatted = str(m_ast) +string_formatted = str(f_ast) output_file.write(string_formatted) input_file.close() diff --git a/src/test.cl b/src/test.cl index e752253b..025ea169 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,21 +1,132 @@ -class Main inherits IO { +-- 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 { - { - out_string("Enter number of numbers to multiply\n"); - out_int(prod(in_int())); - out_string("\n"); - } - }; - - prod(i : Int) : Int { - let y : Int <- 1 in { - while (not (i = 0) ) loop { - out_string("Enter Number: "); - y <- y * in_int(Main : Int); -- the parser correctly catches the error here - i <- i - 1; + (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(); } - pool; - y; - } + ) -- end let an_article + ) -- end let a_book }; }; diff --git a/src/test.mips b/src/test.mips index 6a353b55..48dabc8c 100644 --- a/src/test.mips +++ b/src/test.mips @@ -7,7 +7,7 @@ type Object { method copy: function_copy_at_Object } type String { - + attribute value method abort: function_abort_at_Object method type_name: function_type_name_at_Object @@ -27,20 +27,85 @@ type IO { method in_string: function_in_string_at_IO method in_int: function_in_int_at_IO } -type A2I { +type Int { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type Bool { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type Book { + attribute title + attribute author + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method initBook: function_initBook_at_Book + method print: function_print_at_Book +} +type Article { + attribute title + attribute author + attribute per_title + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method initBook: function_initBook_at_Book + method print: function_print_at_Article + method initArticle: function_initArticle_at_Article +} +type BookList { method abort: function_abort_at_Object method type_name: function_type_name_at_Object method copy: function_copy_at_Object - method c2i: function_c2i_at_A2I - method i2c: function_i2c_at_A2I - method a2i: function_a2i_at_A2I - method a2i_aux: function_a2i_aux_at_A2I - method i2a: function_i2a_at_A2I - method i2a_aux: function_i2a_aux_at_A2I + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method isNil: function_isNil_at_BookList + method cons: function_cons_at_BookList + method car: function_car_at_BookList + method cdr: function_cdr_at_BookList + method print_list: function_print_list_at_BookList } -type Main { +type Cons { + attribute xcar + attribute xcdr + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method isNil: function_isNil_at_Cons + method cons: function_cons_at_BookList + method car: function_car_at_Cons + method cdr: function_cdr_at_Cons + method print_list: function_print_list_at_Cons + method init: function_init_at_Cons +} +type Nil { method abort: function_abort_at_Object @@ -50,39 +115,39 @@ type Main { method out_int: function_out_int_at_IO method in_string: function_in_string_at_IO method in_int: function_in_int_at_IO + method isNil: function_isNil_at_Nil + method cons: function_cons_at_BookList + method car: function_car_at_BookList + method cdr: function_cdr_at_BookList + method print_list: function_print_list_at_Nil +} +type Main { + attribute books + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object method main: function_main_at_Main } .DATA -data_0 = "0" -data_1 = "1" -data_2 = "2" -data_3 = "3" -data_4 = "4" -data_5 = "5" -data_6 = "6" -data_7 = "7" -data_8 = "8" -data_9 = "9" -data_10 = "" -data_11 = "9" -data_12 = "8" -data_13 = "7" -data_14 = "6" -data_15 = "5" -data_16 = "4" -data_17 = "3" -data_18 = "2" -data_19 = "1" -data_20 = "0" -data_21 = "-" -data_22 = "+" -data_23 = "-" -data_24 = "0" -data_25 = "" -data_26 = "678987" -data_27 = " == " -data_28 = "n" +data_0 = "\n" +data_1 = "Invalid substring start" +data_2 = "Invalid substring length" +data_3 = "Invalid substring" +data_4 = "n" +data_5 = "title: " +data_6 = "n" +data_7 = "author: " +data_8 = "n" +data_9 = "periodical: " +data_10 = "- dynamic type was Book -n" +data_11 = "- dynamic type was Article -n" +data_12 = "Compilers, Principles, Techniques, and Tools" +data_13 = "Aho, Sethi, and Ullman" +data_14 = "The Top 100 CD_ROMs" +data_15 = "Ulanoff" +data_16 = "PC Magazine" .CODE function function_abort_at_Object { @@ -90,6 +155,7 @@ function function_abort_at_Object { + PRINTSTR abort with type ERROR 0 } function function_copy_at_Object { @@ -133,7 +199,36 @@ function function_substr_at_String { PARAM length LOCAL local_substr_at_String_internal_0 - + LOCAL local_substr_at_String_internal_1 + LOCAL local_substr_at_String_internal_2 + LOCAL local_substr_at_String_internal_3 + LOCAL local_substr_at_String_internal_4 + LOCAL local_substr_at_String_internal_5 + LOCAL local_substr_at_String_internal_6 + LOCAL local_substr_at_String_internal_7 + LOCAL local_substr_at_String_internal_8 + + local_substr_at_String_internal_3 = 0 + local_substr_at_String_internal_2 = LENGTH self + local_substr_at_String_internal_5 = local_substr_at_String_internal_3 <= start + IF local_substr_at_String_internal_5 GOTO error1 + local_substr_at_String_internal_8 = CONCAT data_1 data_0 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error1 + local_substr_at_String_internal_6 = local_substr_at_String_internal_3 <= length + IF local_substr_at_String_internal_6 GOTO error2 + local_substr_at_String_internal_8 = CONCAT data_2 data_0 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error2 + local_substr_at_String_internal_4 = start + length + local_substr_at_String_internal_7 = local_substr_at_String_internal_4 <= local_substr_at_String_internal_2 + IF local_substr_at_String_internal_7 GOTO error3 + local_substr_at_String_internal_8 = CONCAT data_3 data_0 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error3 local_substr_at_String_internal_0 = SUBSTRING self start length RETURN local_substr_at_String_internal_0 } @@ -174,477 +269,292 @@ function entry { LOCAL local__internal_1 local__internal_0 = ALLOCATE Main + SETATTR books OF self_Main = 0 ARG local__internal_0 local__internal_1 = CALL function_main_at_Main } -function function_c2i_at_A2I { +function function_initBook_at_Book { + PARAM self + PARAM title_p + PARAM author_p + + LOCAL local_initBook_at_Book_internal_0 + + SETATTR title OF self_Book = title_p + SETATTR author OF self_Book = author_p + local_initBook_at_Book_internal_0 = self + RETURN local_initBook_at_Book_internal_0 +} +function function_print_at_Book { PARAM self - PARAM char - - LOCAL local_c2i_at_A2I_internal_0 - LOCAL local_c2i_at_A2I_internal_1 - LOCAL local_c2i_at_A2I_internal_2 - LOCAL local_c2i_at_A2I_internal_3 - LOCAL local_c2i_at_A2I_internal_4 - LOCAL local_c2i_at_A2I_internal_5 - LOCAL local_c2i_at_A2I_internal_6 - LOCAL local_c2i_at_A2I_internal_7 - LOCAL local_c2i_at_A2I_internal_8 - LOCAL local_c2i_at_A2I_internal_9 - LOCAL local_c2i_at_A2I_internal_10 - LOCAL local_c2i_at_A2I_internal_11 - LOCAL local_c2i_at_A2I_internal_12 - LOCAL local_c2i_at_A2I_internal_13 - LOCAL local_c2i_at_A2I_internal_14 - LOCAL local_c2i_at_A2I_internal_15 - LOCAL local_c2i_at_A2I_internal_16 - LOCAL local_c2i_at_A2I_internal_17 - LOCAL local_c2i_at_A2I_internal_18 - LOCAL local_c2i_at_A2I_internal_19 - LOCAL local_c2i_at_A2I_internal_20 - LOCAL local_c2i_at_A2I_internal_21 - LOCAL local_c2i_at_A2I_internal_22 - LOCAL local_c2i_at_A2I_internal_23 - LOCAL local_c2i_at_A2I_internal_24 - LOCAL local_c2i_at_A2I_internal_25 - LOCAL local_c2i_at_A2I_internal_26 - LOCAL local_c2i_at_A2I_internal_27 - LOCAL local_c2i_at_A2I_internal_28 - LOCAL local_c2i_at_A2I_internal_29 - LOCAL local_c2i_at_A2I_internal_30 - LOCAL local_c2i_at_A2I_internal_31 - - local_c2i_at_A2I_internal_0 = LOAD data_0 - local_c2i_at_A2I_internal_1 = STREQ char local_c2i_at_A2I_internal_0 - IF local_c2i_at_A2I_internal_1 GOTO TRUE_0 - local_c2i_at_A2I_internal_3 = LOAD data_1 - local_c2i_at_A2I_internal_4 = STREQ char local_c2i_at_A2I_internal_3 - IF local_c2i_at_A2I_internal_4 GOTO TRUE_1 - local_c2i_at_A2I_internal_6 = LOAD data_2 - local_c2i_at_A2I_internal_7 = STREQ char local_c2i_at_A2I_internal_6 - IF local_c2i_at_A2I_internal_7 GOTO TRUE_2 - local_c2i_at_A2I_internal_9 = LOAD data_3 - local_c2i_at_A2I_internal_10 = STREQ char local_c2i_at_A2I_internal_9 - IF local_c2i_at_A2I_internal_10 GOTO TRUE_3 - local_c2i_at_A2I_internal_12 = LOAD data_4 - local_c2i_at_A2I_internal_13 = STREQ char local_c2i_at_A2I_internal_12 - IF local_c2i_at_A2I_internal_13 GOTO TRUE_4 - local_c2i_at_A2I_internal_15 = LOAD data_5 - local_c2i_at_A2I_internal_16 = STREQ char local_c2i_at_A2I_internal_15 - IF local_c2i_at_A2I_internal_16 GOTO TRUE_5 - local_c2i_at_A2I_internal_18 = LOAD data_6 - local_c2i_at_A2I_internal_19 = STREQ char local_c2i_at_A2I_internal_18 - IF local_c2i_at_A2I_internal_19 GOTO TRUE_6 - local_c2i_at_A2I_internal_21 = LOAD data_7 - local_c2i_at_A2I_internal_22 = STREQ char local_c2i_at_A2I_internal_21 - IF local_c2i_at_A2I_internal_22 GOTO TRUE_7 - local_c2i_at_A2I_internal_24 = LOAD data_8 - local_c2i_at_A2I_internal_25 = STREQ char local_c2i_at_A2I_internal_24 - IF local_c2i_at_A2I_internal_25 GOTO TRUE_8 - local_c2i_at_A2I_internal_27 = LOAD data_9 - local_c2i_at_A2I_internal_28 = STREQ char local_c2i_at_A2I_internal_27 - IF local_c2i_at_A2I_internal_28 GOTO TRUE_9 + + LOCAL local_print_at_Book_internal_0 + LOCAL local_print_at_Book_internal_1 + LOCAL local_print_at_Book_internal_2 + LOCAL local_print_at_Book_internal_3 + LOCAL local_print_at_Book_internal_4 + LOCAL local_print_at_Book_internal_5 + LOCAL local_print_at_Book_internal_6 + LOCAL local_print_at_Book_internal_7 + LOCAL local_print_at_Book_internal_8 + LOCAL local_print_at_Book_internal_9 + LOCAL local_print_at_Book_internal_10 + LOCAL local_print_at_Book_internal_11 + LOCAL local_print_at_Book_internal_12 + + local_print_at_Book_internal_2 = LOAD data_4 + ARG local_print_at_Book_internal_2 + local_print_at_Book_internal_4 = GETATTR self title + ARG local_print_at_Book_internal_4 + local_print_at_Book_internal_6 = LOAD data_5 + ARG local_print_at_Book_internal_6 ARG self - local_c2i_at_A2I_internal_31 = VCALL A2I abort - local_c2i_at_A2I_internal_30 = 0 - local_c2i_at_A2I_internal_29 = local_c2i_at_A2I_internal_30 - GOTO END_9 - LABEL TRUE_9 - local_c2i_at_A2I_internal_29 = 9 - LABEL END_9 - local_c2i_at_A2I_internal_26 = local_c2i_at_A2I_internal_29 - GOTO END_8 - LABEL TRUE_8 - local_c2i_at_A2I_internal_26 = 8 - LABEL END_8 - local_c2i_at_A2I_internal_23 = local_c2i_at_A2I_internal_26 - GOTO END_7 - LABEL TRUE_7 - local_c2i_at_A2I_internal_23 = 7 - LABEL END_7 - local_c2i_at_A2I_internal_20 = local_c2i_at_A2I_internal_23 - GOTO END_6 - LABEL TRUE_6 - local_c2i_at_A2I_internal_20 = 6 - LABEL END_6 - local_c2i_at_A2I_internal_17 = local_c2i_at_A2I_internal_20 - GOTO END_5 - LABEL TRUE_5 - local_c2i_at_A2I_internal_17 = 5 - LABEL END_5 - local_c2i_at_A2I_internal_14 = local_c2i_at_A2I_internal_17 - GOTO END_4 - LABEL TRUE_4 - local_c2i_at_A2I_internal_14 = 4 - LABEL END_4 - local_c2i_at_A2I_internal_11 = local_c2i_at_A2I_internal_14 - GOTO END_3 - LABEL TRUE_3 - local_c2i_at_A2I_internal_11 = 3 - LABEL END_3 - local_c2i_at_A2I_internal_8 = local_c2i_at_A2I_internal_11 - GOTO END_2 - LABEL TRUE_2 - local_c2i_at_A2I_internal_8 = 2 - LABEL END_2 - local_c2i_at_A2I_internal_5 = local_c2i_at_A2I_internal_8 - GOTO END_1 - LABEL TRUE_1 - local_c2i_at_A2I_internal_5 = 1 - LABEL END_1 - local_c2i_at_A2I_internal_2 = local_c2i_at_A2I_internal_5 - GOTO END_0 - LABEL TRUE_0 - local_c2i_at_A2I_internal_2 = 0 - LABEL END_0 - RETURN local_c2i_at_A2I_internal_2 -} -function function_i2c_at_A2I { + local_print_at_Book_internal_5 = VCALL Book out_string + ARG local_print_at_Book_internal_5 + local_print_at_Book_internal_3 = VCALL Book out_string + ARG local_print_at_Book_internal_3 + local_print_at_Book_internal_1 = VCALL Book out_string + local_print_at_Book_internal_8 = LOAD data_6 + ARG local_print_at_Book_internal_8 + local_print_at_Book_internal_10 = GETATTR self author + ARG local_print_at_Book_internal_10 + local_print_at_Book_internal_12 = LOAD data_7 + ARG local_print_at_Book_internal_12 + ARG self + local_print_at_Book_internal_11 = VCALL Book out_string + ARG local_print_at_Book_internal_11 + local_print_at_Book_internal_9 = VCALL Book out_string + ARG local_print_at_Book_internal_9 + local_print_at_Book_internal_7 = VCALL Book out_string + local_print_at_Book_internal_0 = self + RETURN local_print_at_Book_internal_0 +} +function function_initArticle_at_Article { PARAM self - PARAM i - - LOCAL local_i2c_at_A2I_internal_0 - LOCAL local_i2c_at_A2I_internal_1 - LOCAL local_i2c_at_A2I_internal_2 - LOCAL local_i2c_at_A2I_internal_3 - LOCAL local_i2c_at_A2I_internal_4 - LOCAL local_i2c_at_A2I_internal_5 - LOCAL local_i2c_at_A2I_internal_6 - LOCAL local_i2c_at_A2I_internal_7 - LOCAL local_i2c_at_A2I_internal_8 - LOCAL local_i2c_at_A2I_internal_9 - LOCAL local_i2c_at_A2I_internal_10 - LOCAL local_i2c_at_A2I_internal_11 - LOCAL local_i2c_at_A2I_internal_12 - LOCAL local_i2c_at_A2I_internal_13 - LOCAL local_i2c_at_A2I_internal_14 - LOCAL local_i2c_at_A2I_internal_15 - LOCAL local_i2c_at_A2I_internal_16 - LOCAL local_i2c_at_A2I_internal_17 - LOCAL local_i2c_at_A2I_internal_18 - LOCAL local_i2c_at_A2I_internal_19 - LOCAL local_i2c_at_A2I_internal_20 - LOCAL local_i2c_at_A2I_internal_21 - LOCAL local_i2c_at_A2I_internal_22 - LOCAL local_i2c_at_A2I_internal_23 - LOCAL local_i2c_at_A2I_internal_24 - LOCAL local_i2c_at_A2I_internal_25 - LOCAL local_i2c_at_A2I_internal_26 - LOCAL local_i2c_at_A2I_internal_27 - LOCAL local_i2c_at_A2I_internal_28 - LOCAL local_i2c_at_A2I_internal_29 - LOCAL local_i2c_at_A2I_internal_30 - LOCAL local_i2c_at_A2I_internal_31 - LOCAL local_i2c_at_A2I_internal_32 - - local_i2c_at_A2I_internal_0 = i == 0 - IF local_i2c_at_A2I_internal_0 GOTO TRUE_0 - local_i2c_at_A2I_internal_2 = i == 1 - IF local_i2c_at_A2I_internal_2 GOTO TRUE_1 - local_i2c_at_A2I_internal_4 = i == 2 - IF local_i2c_at_A2I_internal_4 GOTO TRUE_2 - local_i2c_at_A2I_internal_6 = i == 3 - IF local_i2c_at_A2I_internal_6 GOTO TRUE_3 - local_i2c_at_A2I_internal_8 = i == 4 - IF local_i2c_at_A2I_internal_8 GOTO TRUE_4 - local_i2c_at_A2I_internal_10 = i == 5 - IF local_i2c_at_A2I_internal_10 GOTO TRUE_5 - local_i2c_at_A2I_internal_12 = i == 6 - IF local_i2c_at_A2I_internal_12 GOTO TRUE_6 - local_i2c_at_A2I_internal_14 = i == 7 - IF local_i2c_at_A2I_internal_14 GOTO TRUE_7 - local_i2c_at_A2I_internal_16 = i == 8 - IF local_i2c_at_A2I_internal_16 GOTO TRUE_8 - local_i2c_at_A2I_internal_18 = i == 9 - IF local_i2c_at_A2I_internal_18 GOTO TRUE_9 + PARAM title_p + PARAM author_p + PARAM per_title_p + + LOCAL local_initArticle_at_Article_internal_0 + LOCAL local_initArticle_at_Article_internal_1 + + ARG author_p + ARG title_p ARG self - local_i2c_at_A2I_internal_21 = VCALL A2I abort - local_i2c_at_A2I_internal_22 = LOAD data_10 - local_i2c_at_A2I_internal_20 = local_i2c_at_A2I_internal_22 - local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_20 - GOTO END_9 - LABEL TRUE_9 - local_i2c_at_A2I_internal_23 = LOAD data_11 - local_i2c_at_A2I_internal_19 = local_i2c_at_A2I_internal_23 - LABEL END_9 - local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_19 - GOTO END_8 - LABEL TRUE_8 - local_i2c_at_A2I_internal_24 = LOAD data_12 - local_i2c_at_A2I_internal_17 = local_i2c_at_A2I_internal_24 - LABEL END_8 - local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_17 - GOTO END_7 - LABEL TRUE_7 - local_i2c_at_A2I_internal_25 = LOAD data_13 - local_i2c_at_A2I_internal_15 = local_i2c_at_A2I_internal_25 - LABEL END_7 - local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_15 - GOTO END_6 - LABEL TRUE_6 - local_i2c_at_A2I_internal_26 = LOAD data_14 - local_i2c_at_A2I_internal_13 = local_i2c_at_A2I_internal_26 - LABEL END_6 - local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_13 - GOTO END_5 - LABEL TRUE_5 - local_i2c_at_A2I_internal_27 = LOAD data_15 - local_i2c_at_A2I_internal_11 = local_i2c_at_A2I_internal_27 - LABEL END_5 - local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_11 - GOTO END_4 - LABEL TRUE_4 - local_i2c_at_A2I_internal_28 = LOAD data_16 - local_i2c_at_A2I_internal_9 = local_i2c_at_A2I_internal_28 - LABEL END_4 - local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_9 - GOTO END_3 - LABEL TRUE_3 - local_i2c_at_A2I_internal_29 = LOAD data_17 - local_i2c_at_A2I_internal_7 = local_i2c_at_A2I_internal_29 - LABEL END_3 - local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_7 - GOTO END_2 - LABEL TRUE_2 - local_i2c_at_A2I_internal_30 = LOAD data_18 - local_i2c_at_A2I_internal_5 = local_i2c_at_A2I_internal_30 - LABEL END_2 - local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_5 - GOTO END_1 - LABEL TRUE_1 - local_i2c_at_A2I_internal_31 = LOAD data_19 - local_i2c_at_A2I_internal_3 = local_i2c_at_A2I_internal_31 - LABEL END_1 - local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2c_at_A2I_internal_32 = LOAD data_20 - local_i2c_at_A2I_internal_1 = local_i2c_at_A2I_internal_32 - LABEL END_0 - RETURN local_i2c_at_A2I_internal_1 -} -function function_a2i_at_A2I { + local_initArticle_at_Article_internal_1 = VCALL Article initBook + SETATTR per_title OF self_Article = per_title_p + local_initArticle_at_Article_internal_0 = self + RETURN local_initArticle_at_Article_internal_0 +} +function function_print_at_Article { PARAM self - PARAM s - - LOCAL local_a2i_at_A2I_internal_0 - LOCAL local_a2i_at_A2I_internal_1 - LOCAL local_a2i_at_A2I_internal_2 - LOCAL local_a2i_at_A2I_internal_3 - LOCAL local_a2i_at_A2I_internal_4 - LOCAL local_a2i_at_A2I_internal_5 - LOCAL local_a2i_at_A2I_internal_6 - LOCAL local_a2i_at_A2I_internal_7 - LOCAL local_a2i_at_A2I_internal_8 - LOCAL local_a2i_at_A2I_internal_9 - LOCAL local_a2i_at_A2I_internal_10 - LOCAL local_a2i_at_A2I_internal_11 - LOCAL local_a2i_at_A2I_internal_12 - LOCAL local_a2i_at_A2I_internal_13 - LOCAL local_a2i_at_A2I_internal_14 - LOCAL local_a2i_at_A2I_internal_15 - LOCAL local_a2i_at_A2I_internal_16 - LOCAL local_a2i_at_A2I_internal_17 - LOCAL local_a2i_at_A2I_internal_18 - LOCAL local_a2i_at_A2I_internal_19 - LOCAL local_a2i_at_A2I_internal_20 - - ARG s - local_a2i_at_A2I_internal_0 = CALL function_length_at_String - local_a2i_at_A2I_internal_1 = local_a2i_at_A2I_internal_0 == 0 - IF local_a2i_at_A2I_internal_1 GOTO TRUE_0 - ARG 1 - ARG 0 - ARG s - local_a2i_at_A2I_internal_3 = CALL function_substr_at_String - local_a2i_at_A2I_internal_4 = LOAD data_21 - local_a2i_at_A2I_internal_5 = STREQ local_a2i_at_A2I_internal_3 local_a2i_at_A2I_internal_4 - IF local_a2i_at_A2I_internal_5 GOTO TRUE_1 - ARG 1 - ARG 0 - ARG s - local_a2i_at_A2I_internal_7 = CALL function_substr_at_String - local_a2i_at_A2I_internal_8 = LOAD data_22 - local_a2i_at_A2I_internal_9 = STREQ local_a2i_at_A2I_internal_7 local_a2i_at_A2I_internal_8 - IF local_a2i_at_A2I_internal_9 GOTO TRUE_2 - ARG s + + LOCAL local_print_at_Article_internal_0 + LOCAL local_print_at_Article_internal_1 + LOCAL local_print_at_Article_internal_2 + LOCAL local_print_at_Article_internal_3 + LOCAL local_print_at_Article_internal_4 + LOCAL local_print_at_Article_internal_5 + LOCAL local_print_at_Article_internal_6 + LOCAL local_print_at_Article_internal_7 + ARG self - local_a2i_at_A2I_internal_11 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_11 - GOTO END_2 - LABEL TRUE_2 - ARG s - local_a2i_at_A2I_internal_15 = CALL function_length_at_String - local_a2i_at_A2I_internal_14 = local_a2i_at_A2I_internal_15 - 1 - ARG local_a2i_at_A2I_internal_14 - ARG 1 - ARG s - local_a2i_at_A2I_internal_13 = CALL function_substr_at_String - ARG local_a2i_at_A2I_internal_13 + local_print_at_Article_internal_1 = CALL function_print_at_Book + local_print_at_Article_internal_3 = LOAD data_8 + ARG local_print_at_Article_internal_3 + local_print_at_Article_internal_5 = GETATTR self per_title + ARG local_print_at_Article_internal_5 + local_print_at_Article_internal_7 = LOAD data_9 + ARG local_print_at_Article_internal_7 ARG self - local_a2i_at_A2I_internal_12 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_10 = local_a2i_at_A2I_internal_12 - LABEL END_2 - local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_10 - GOTO END_1 - LABEL TRUE_1 - ARG s - local_a2i_at_A2I_internal_20 = CALL function_length_at_String - local_a2i_at_A2I_internal_19 = local_a2i_at_A2I_internal_20 - 1 - ARG local_a2i_at_A2I_internal_19 - ARG 1 - ARG s - local_a2i_at_A2I_internal_18 = CALL function_substr_at_String - ARG local_a2i_at_A2I_internal_18 + local_print_at_Article_internal_6 = VCALL Article out_string + ARG local_print_at_Article_internal_6 + local_print_at_Article_internal_4 = VCALL Article out_string + ARG local_print_at_Article_internal_4 + local_print_at_Article_internal_2 = VCALL Article out_string + local_print_at_Article_internal_0 = self + RETURN local_print_at_Article_internal_0 +} +function function_isNil_at_BookList { + PARAM self + + LOCAL local_isNil_at_BookList_internal_0 + LOCAL local_isNil_at_BookList_internal_1 + ARG self - local_a2i_at_A2I_internal_17 = VCALL A2I a2i_aux - local_a2i_at_A2I_internal_16 = COMPLEMENT local_a2i_at_A2I_internal_17 - local_a2i_at_A2I_internal_6 = local_a2i_at_A2I_internal_16 - LABEL END_1 - local_a2i_at_A2I_internal_2 = local_a2i_at_A2I_internal_6 - GOTO END_0 - LABEL TRUE_0 - local_a2i_at_A2I_internal_2 = 0 - LABEL END_0 - RETURN local_a2i_at_A2I_internal_2 -} -function function_a2i_aux_at_A2I { + local_isNil_at_BookList_internal_1 = VCALL BookList abort + local_isNil_at_BookList_internal_0 = 1 + RETURN local_isNil_at_BookList_internal_0 +} +function function_cons_at_BookList { PARAM self - PARAM s - - LOCAL local_a2i_aux_at_A2I_internal_0 - LOCAL local_a2i_aux_at_A2I_internal_1 - LOCAL local_a2i_aux_at_A2I_internal_2 - LOCAL local_a2i_aux_at_A2I_internal_3 - LOCAL local_a2i_aux_at_A2I_internal_4 - LOCAL local_a2i_aux_at_A2I_internal_5 - LOCAL local_a2i_aux_at_A2I_internal_6 - LOCAL local_a2i_aux_at_A2I_internal_7 - LOCAL local_a2i_aux_at_A2I_internal_8 - LOCAL local_a2i_aux_at_A2I_internal_9 - LOCAL local_a2i_aux_at_A2I_internal_10 - LOCAL local_a2i_aux_at_A2I_internal_11 - - ARG s - local_a2i_aux_at_A2I_internal_2 = CALL function_length_at_String - LABEL START_0 - local_a2i_aux_at_A2I_internal_5 = i < j - IF local_a2i_aux_at_A2I_internal_5 GOTO CONTINUE_0 - GOTO END_0 - LABEL CONTINUE_0 - local_a2i_aux_at_A2I_internal_8 = int * 10 - ARG 1 - ARG i - ARG s - local_a2i_aux_at_A2I_internal_10 = CALL function_substr_at_String - ARG local_a2i_aux_at_A2I_internal_10 + PARAM hd + + LOCAL local_cons_at_BookList_new_cell_0 + LOCAL local_cons_at_BookList_internal_1 + LOCAL local_cons_at_BookList_internal_2 + + local_cons_at_BookList_internal_1 = ALLOCATE Cons + SETATTR xcar OF self_Cons = 0 + SETATTR xcdr OF self_Cons = 0 + local_cons_at_BookList_new_cell_0 = local_cons_at_BookList_internal_1 ARG self - local_a2i_aux_at_A2I_internal_9 = VCALL A2I c2i - local_a2i_aux_at_A2I_internal_7 = local_a2i_aux_at_A2I_internal_8 + local_a2i_aux_at_A2I_internal_9 - int = local_a2i_aux_at_A2I_internal_7 - local_a2i_aux_at_A2I_internal_11 = i + 1 - i = local_a2i_aux_at_A2I_internal_11 - local_a2i_aux_at_A2I_internal_6 = 0 - GOTO START_0 - LABEL END_0 - local_a2i_aux_at_A2I_internal_4 = 0 - local_a2i_aux_at_A2I_internal_3 = local_a2i_aux_at_A2I_internal_4 - local_a2i_aux_at_A2I_internal_1 = int - local_a2i_aux_at_A2I_internal_0 = local_a2i_aux_at_A2I_internal_1 - RETURN local_a2i_aux_at_A2I_internal_0 -} -function function_i2a_at_A2I { + ARG hd + ARG new_cell + local_cons_at_BookList_internal_2 = VCALL Cons init + RETURN local_cons_at_BookList_internal_2 +} +function function_car_at_BookList { PARAM self - PARAM i - - LOCAL local_i2a_at_A2I_internal_0 - LOCAL local_i2a_at_A2I_internal_1 - LOCAL local_i2a_at_A2I_internal_2 - LOCAL local_i2a_at_A2I_internal_3 - LOCAL local_i2a_at_A2I_internal_4 - LOCAL local_i2a_at_A2I_internal_5 - LOCAL local_i2a_at_A2I_internal_6 - LOCAL local_i2a_at_A2I_internal_7 - LOCAL local_i2a_at_A2I_internal_8 - LOCAL local_i2a_at_A2I_internal_9 - LOCAL local_i2a_at_A2I_internal_10 - - local_i2a_at_A2I_internal_0 = i == 0 - IF local_i2a_at_A2I_internal_0 GOTO TRUE_0 - local_i2a_at_A2I_internal_2 = 0 < i - IF local_i2a_at_A2I_internal_2 GOTO TRUE_1 - local_i2a_at_A2I_internal_7 = COMPLEMENT 1 - local_i2a_at_A2I_internal_6 = i * local_i2a_at_A2I_internal_7 - ARG local_i2a_at_A2I_internal_6 + + LOCAL local_car_at_BookList_internal_0 + LOCAL local_car_at_BookList_internal_1 + LOCAL local_car_at_BookList_internal_2 + ARG self - local_i2a_at_A2I_internal_5 = VCALL A2I i2a_aux - ARG local_i2a_at_A2I_internal_5 - local_i2a_at_A2I_internal_8 = LOAD data_23 - ARG local_i2a_at_A2I_internal_8 - local_i2a_at_A2I_internal_4 = CALL function_concat_at_String - local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_4 - GOTO END_1 - LABEL TRUE_1 - ARG i + local_car_at_BookList_internal_1 = VCALL BookList abort + local_car_at_BookList_internal_2 = ALLOCATE Book + SETATTR title OF self_Book = 0 + SETATTR author OF self_Book = 0 + local_car_at_BookList_internal_0 = local_car_at_BookList_internal_2 + RETURN local_car_at_BookList_internal_0 +} +function function_cdr_at_BookList { + PARAM self + + LOCAL local_cdr_at_BookList_internal_0 + LOCAL local_cdr_at_BookList_internal_1 + LOCAL local_cdr_at_BookList_internal_2 + ARG self - local_i2a_at_A2I_internal_9 = VCALL A2I i2a_aux - local_i2a_at_A2I_internal_3 = local_i2a_at_A2I_internal_9 - LABEL END_1 - local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2a_at_A2I_internal_10 = LOAD data_24 - local_i2a_at_A2I_internal_1 = local_i2a_at_A2I_internal_10 - LABEL END_0 - RETURN local_i2a_at_A2I_internal_1 -} -function function_i2a_aux_at_A2I { + local_cdr_at_BookList_internal_1 = VCALL BookList abort + local_cdr_at_BookList_internal_2 = ALLOCATE BookList + local_cdr_at_BookList_internal_0 = local_cdr_at_BookList_internal_2 + RETURN local_cdr_at_BookList_internal_0 +} +function function_print_list_at_BookList { PARAM self - PARAM i - - LOCAL local_i2a_aux_at_A2I_internal_0 - LOCAL local_i2a_aux_at_A2I_internal_1 - LOCAL local_i2a_aux_at_A2I_internal_2 - LOCAL local_i2a_aux_at_A2I_internal_3 - LOCAL local_i2a_aux_at_A2I_internal_4 - LOCAL local_i2a_aux_at_A2I_internal_5 - LOCAL local_i2a_aux_at_A2I_internal_6 - LOCAL local_i2a_aux_at_A2I_internal_7 - LOCAL local_i2a_aux_at_A2I_internal_8 - LOCAL local_i2a_aux_at_A2I_internal_9 - - local_i2a_aux_at_A2I_internal_0 = i == 0 - IF local_i2a_aux_at_A2I_internal_0 GOTO TRUE_0 - local_i2a_aux_at_A2I_internal_2 = i / 10 - local_i2a_aux_at_A2I_internal_7 = next * 10 - local_i2a_aux_at_A2I_internal_6 = i - local_i2a_aux_at_A2I_internal_7 - ARG local_i2a_aux_at_A2I_internal_6 + + LOCAL local_print_list_at_BookList_internal_0 + ARG self - local_i2a_aux_at_A2I_internal_5 = VCALL A2I i2c - ARG local_i2a_aux_at_A2I_internal_5 - ARG next + local_print_list_at_BookList_internal_0 = VCALL BookList abort + RETURN local_print_list_at_BookList_internal_0 +} +function function_isNil_at_Cons { + PARAM self + + + + RETURN 0 +} +function function_init_at_Cons { + PARAM self + PARAM hd + PARAM tl + + LOCAL local_init_at_Cons_internal_0 + + SETATTR xcar OF self_Cons = hd + SETATTR xcdr OF self_Cons = tl + local_init_at_Cons_internal_0 = self + RETURN local_init_at_Cons_internal_0 +} +function function_car_at_Cons { + PARAM self + + LOCAL local_car_at_Cons_internal_0 + + local_car_at_Cons_internal_0 = GETATTR self xcar + RETURN local_car_at_Cons_internal_0 +} +function function_cdr_at_Cons { + PARAM self + + LOCAL local_cdr_at_Cons_internal_0 + + local_cdr_at_Cons_internal_0 = GETATTR self xcdr + RETURN local_cdr_at_Cons_internal_0 +} +function function_print_list_at_Cons { + PARAM self + + LOCAL local_print_list_at_Cons_internal_0 + LOCAL local_print_list_at_Cons_internal_1 + LOCAL local_print_list_at_Cons_internal_2 + LOCAL local_print_list_at_Cons_internal_3 + LOCAL local_print_list_at_Cons_internal_4 + LOCAL local_print_list_at_Cons_internal_5 + LOCAL local_print_list_at_Cons_internal_6 + LOCAL local_print_list_at_Cons_internal_7 + LOCAL local_print_list_at_Cons_internal_8 + LOCAL local_print_list_at_Cons_internal_9 + LOCAL local_print_list_at_Cons_internal_10 + LOCAL local_print_list_at_Cons_internal_11 + LOCAL local_print_list_at_Cons_internal_12 + LOCAL local_print_list_at_Cons_internal_13 + LOCAL local_print_list_at_Cons_internal_14 + + local_print_list_at_Cons_internal_2 = GETATTR self xcar + ARG local_print_list_at_Cons_internal_2 + local_print_list_at_Cons_internal_1 = VCALL Book print + local_print_list_at_Cons_internal_4 = TYPEOF local_print_list_at_Cons_internal_1 + local_print_list_at_Cons_internal_5 = COMFORM local_print_list_at_Cons_internal_1 TYPE: Book + IF local_print_list_at_Cons_internal_1 GOTO + GOTO CASE_dummy_0 + LABEL CASE_MATCH_dummy_Book + local_print_list_at_Cons_internal_6 = local_print_list_at_Cons_internal_1 + local_print_list_at_Cons_internal_8 = LOAD data_10 + ARG local_print_list_at_Cons_internal_8 ARG self - local_i2a_aux_at_A2I_internal_8 = VCALL A2I i2a_aux - ARG local_i2a_aux_at_A2I_internal_8 - local_i2a_aux_at_A2I_internal_4 = CALL function_concat_at_String - local_i2a_aux_at_A2I_internal_3 = local_i2a_aux_at_A2I_internal_4 - local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_3 - GOTO END_0 - LABEL TRUE_0 - local_i2a_aux_at_A2I_internal_9 = LOAD data_25 - local_i2a_aux_at_A2I_internal_1 = local_i2a_aux_at_A2I_internal_9 - LABEL END_0 - RETURN local_i2a_aux_at_A2I_internal_1 + local_print_list_at_Cons_internal_7 = VCALL Cons out_string + local_print_list_at_Cons_internal_3 = local_print_list_at_Cons_internal_7 + GOTO END_1 + LABEL CASE_dummy_0 + local_print_list_at_Cons_internal_9 = COMFORM local_print_list_at_Cons_internal_1 TYPE: Article + IF local_print_list_at_Cons_internal_1 GOTO + GOTO CASE_dummy_1 + LABEL CASE_MATCH_dummy_Article + local_print_list_at_Cons_internal_10 = local_print_list_at_Cons_internal_1 + local_print_list_at_Cons_internal_12 = LOAD data_11 + ARG local_print_list_at_Cons_internal_12 + ARG self + local_print_list_at_Cons_internal_11 = VCALL Cons out_string + local_print_list_at_Cons_internal_3 = local_print_list_at_Cons_internal_11 + GOTO END_1 + LABEL CASE_dummy_1 + LABEL ERROR_CASE_1 + ERROR 0 + LABEL END_1 + local_print_list_at_Cons_internal_14 = GETATTR self xcdr + ARG local_print_list_at_Cons_internal_14 + local_print_list_at_Cons_internal_13 = VCALL BookList print_list + local_print_list_at_Cons_internal_0 = local_print_list_at_Cons_internal_13 + RETURN local_print_list_at_Cons_internal_0 +} +function function_isNil_at_Nil { + PARAM self + + + + RETURN 1 +} +function function_print_list_at_Nil { + PARAM self + + + + RETURN 1 } function function_main_at_Main { PARAM self - LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_a_book_0 LOCAL local_main_at_Main_internal_1 LOCAL local_main_at_Main_internal_2 LOCAL local_main_at_Main_internal_3 LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_internal_5 + LOCAL local_main_at_Main_an_article_5 LOCAL local_main_at_Main_internal_6 LOCAL local_main_at_Main_internal_7 LOCAL local_main_at_Main_internal_8 @@ -652,31 +562,45 @@ function function_main_at_Main { LOCAL local_main_at_Main_internal_10 LOCAL local_main_at_Main_internal_11 LOCAL local_main_at_Main_internal_12 - - local_main_at_Main_internal_1 = LOAD data_26 - ARG local_main_at_Main_internal_1 - local_main_at_Main_internal_2 = ALLOCATE A2I + LOCAL local_main_at_Main_internal_13 + LOCAL local_main_at_Main_internal_14 + LOCAL local_main_at_Main_internal_15 + LOCAL local_main_at_Main_internal_16 + + local_main_at_Main_internal_2 = LOAD data_12 + local_main_at_Main_internal_3 = LOAD data_13 + ARG local_main_at_Main_internal_3 ARG local_main_at_Main_internal_2 - local_main_at_Main_internal_0 = CALL function_a2i_at_A2I - ARG 678987 - local_main_at_Main_internal_4 = ALLOCATE A2I + local_main_at_Main_internal_4 = ALLOCATE Book + SETATTR title OF self_Book = 0 + SETATTR author OF self_Book = 0 ARG local_main_at_Main_internal_4 - local_main_at_Main_internal_3 = CALL function_i2a_at_A2I - ARG a - ARG self - local_main_at_Main_internal_7 = VCALL Main out_int - local_main_at_Main_internal_9 = LOAD data_27 + local_main_at_Main_internal_1 = VCALL Book initBook + local_main_at_Main_a_book_0 = local_main_at_Main_internal_1 + local_main_at_Main_internal_7 = LOAD data_14 + local_main_at_Main_internal_8 = LOAD data_15 + local_main_at_Main_internal_9 = LOAD data_16 ARG local_main_at_Main_internal_9 - ARG self - local_main_at_Main_internal_8 = VCALL Main out_string - ARG b - ARG self - local_main_at_Main_internal_10 = VCALL Main out_string - local_main_at_Main_internal_12 = LOAD data_28 - ARG local_main_at_Main_internal_12 - ARG self - local_main_at_Main_internal_11 = VCALL Main out_string - local_main_at_Main_internal_6 = local_main_at_Main_internal_11 - local_main_at_Main_internal_5 = local_main_at_Main_internal_6 - RETURN local_main_at_Main_internal_5 + ARG local_main_at_Main_internal_8 + ARG local_main_at_Main_internal_7 + local_main_at_Main_internal_10 = ALLOCATE Article + SETATTR title OF self_Article = 0 + SETATTR author OF self_Article = 0 + SETATTR per_title OF self_Article = 0 + ARG local_main_at_Main_internal_10 + local_main_at_Main_internal_6 = VCALL Article initArticle + local_main_at_Main_an_article_5 = local_main_at_Main_internal_6 + ARG an_article + ARG a_book + local_main_at_Main_internal_14 = ALLOCATE Nil + ARG local_main_at_Main_internal_14 + local_main_at_Main_internal_13 = VCALL Nil cons + ARG local_main_at_Main_internal_13 + local_main_at_Main_internal_12 = VCALL Cons cons + SETATTR books OF self_Main = local_main_at_Main_internal_12 + local_main_at_Main_internal_16 = GETATTR self books + ARG local_main_at_Main_internal_16 + local_main_at_Main_internal_15 = VCALL BookList print_list + local_main_at_Main_internal_11 = local_main_at_Main_internal_15 + RETURN local_main_at_Main_internal_11 } \ No newline at end of file From 2a13f7599de59a49709b98ea164a2b72922a914c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 15:48:34 -0500 Subject: [PATCH 099/191] Add global descriptor class --- src/engine/codegen/mips.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 4d55239b..00ac3ab7 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -6,6 +6,35 @@ string_max_size = 1000 +class GlobalDescriptor: + + def __init__(self, dottypes: list(TypeNode), name_ptrs): + self.vTable = None + self.Types = Dict[str, MemoryType] = dict() + + methods = {} + + index = 0 + + start_method = 0 + end_method = 0 + + for dottype in dottypes: + + methds = [] + + for (method_name, method_tag) in dottype.methods: + methods[method_name] = method_tag + methds.append(method_name) + end_method += 1 + + self.Types[dottype.name] = MemoryType(dottype.name, index, dottype.attrs, methds, start_method, name_ptrs[dottype.name]) + + start_method = end_method + + + self.vTable = VTable(methods) + class VTable: def __init__(self, methods): From bad5762a87a830ca16c557be9cb2e55140025f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 16:38:33 -0500 Subject: [PATCH 100/191] add allocate vtable method --- src/engine/codegen/mips.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 00ac3ab7..94492f81 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -515,3 +515,15 @@ def mflo(self, rdest): Move from `low` ''' self._write(f'mflo {rdest}') + + #VTble allocate + def allocate_vtable(self, size): + ''' + Allocate Vtable and store its adrress in s7 + ''' + + self.li(reg.a0, size) + self.sbrk() + self.move(reg.a0, reg.s7) + + From 664e2b663755ec5b42539f92b3a8fc4f9f9a4f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 16:53:16 -0500 Subject: [PATCH 101/191] add allocate vtable, fill_vtable and build_tags --- src/engine/codegen/cil_ast.py | 14 +++++++++++++ src/engine/codegen/mips.py | 6 ++++-- src/engine/codegen/to_mips.py | 37 +++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 9d422604..34c6f370 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -19,6 +19,20 @@ def __init__(self, name): self.methods = [] self.features = [] + def __str__(self): + string_base = self.name + "\n" + + string_base += "Attrs \n" + + for attr in self.attributes: + string_base += str(attr) + "\n" + + string_base += "Methods \n" + + for methos in self.methods: + string_base += str(methos) + "\n" + + return string_base class DataNode(Node): def __init__(self, vname, value): diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 94492f81..8968c1d3 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -522,8 +522,10 @@ def allocate_vtable(self, size): Allocate Vtable and store its adrress in s7 ''' - self.li(reg.a0, size) + self.comment("Allocate Vtable") + vtable_size = size * word_size + self.li(reg.a0, vtable_size) self.sbrk() self.move(reg.a0, reg.s7) - + diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index c9d0aa98..41342ae7 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,6 +1,6 @@ from .cil_ast import * from ..cp import visitor -from .mips import MipsCode, TypeData, MipsLabel +from .mips import MipsCode, MemoryType, MipsLabel, VTable, TypeData, GlobalDescriptor, word_size, string_max_size from .mips import Registers as reg from typing import Dict, List @@ -9,7 +9,7 @@ class CIL_TO_MIPS: def __init__(self, data_size=4): self.types = [] - self.types_offsets: Dict[str, TypeData] = dict() + self.types_offsets: Dict[str, MemoryType] = dict() self.arguments = {} self.local_vars = {} self.data_segment = [] @@ -25,12 +25,37 @@ def __init__(self, data_size=4): reg.s6, reg.s7, ] self.label_count = 0 + self.vtable_reg = reg.s7 self.mips = MipsCode() def build_types(self, types): for idx, typex in enumerate(types): self.types_offsets[typex.name] = TypeData(idx, typex) + def fill_vtable(self): + index = 0 + + self.mips.comment("Build VTable") + for _,tag in self.global_descriptor.vTable.methods: + self.mips.la(reg.s0, tag) + self.mips.sw(reg.s0, f'{index}({reg.s7})') + index += 1 + + + + def build_tags(self, dottypes:list(TypeData)): + base_tag = "classname_" + + tags = dict() + + for dottype in dottypes: + name = base_tag + dottype.name + tags[dottype.name] = name + self.mips.data_label(name) + self.mips.asciiz(dottype.name) + + return tags + def get_offset(self, arg: str): if arg in self.arguments or arg in self.local_vars: offset = ( @@ -100,6 +125,14 @@ def visit(self, node: ProgramNode): self.types = node.dottypes self.build_types(self.types) + tags = self.build_tags(node.dottypes) + + self.global_descriptor = GlobalDescriptor(node.dottypes, tags) + + self.mips.allocate_vtable(self.global_descriptor.vTable.size()) + + self.fill_vtable() + for data in node.dotdata: self.visit(data) self.data_segment.append(data.name) From 5d4f0bd4002b3d8e27314f360ec2def753cfe123 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Mon, 14 Dec 2020 17:07:00 -0500 Subject: [PATCH 102/191] cil constructor created --- src/engine/codegen/cil.py | 1 + src/engine/codegen/to_cil.py | 39 +++++++++++++++++++++++++-------- src/engine/parser/ast_parser.py | 3 +++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 07e41bd3..b0b9f0e8 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -11,6 +11,7 @@ def __init__(self, context): self.current_method = None self.current_function = None self.context = context + self.attr_declarations = {} self._label_counter = 0 self.define_object_type() self.define_string_type() diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index dc459e47..38a15a64 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -1,3 +1,4 @@ +from typing import List from engine import parser as cool from engine.cp.semantic import Context from .cil_ast import * @@ -34,22 +35,40 @@ def sort_class_declar(self, program: cool.ProgramNode): ) def init_class_attr(self, scope: Scope, class_id, self_inst): - attr_nodes = self.attr_init[class_id] + attr_nodes = self.attr_declarations[class_id] for attr in attr_nodes: attr_scope = scope.create_child() attr_scope.define_variable('self', self_inst) self.visit(attr, attr_scope) - def save_attr_init(self, node: cool.ProgramNode): - self.attr_init = dict() + def save_attr_initializations(self, node: cool.ProgramNode, scope): + self.attr_declarations = dict() for declaration in node.declarations: - self.attr_init[declaration.id.lex] = [] + self.attr_declarations[declaration.id.lex] = [] if declaration.parent and not declaration.parent.lex in ['IO', 'Object']: - self.attr_init[declaration.id.lex] += self.attr_init[declaration.parent.lex] - self.attr_init[declaration.id.lex] += [ + self.attr_declarations[declaration.id.lex] += self.attr_declarations[declaration.parent.lex] + self.attr_declarations[declaration.id.lex] += [ feature for feature in declaration.features if isinstance(feature, cool.AttrDeclarationNode) ] + self.create_constructor( + self.attr_declarations[declaration.id.lex], declaration.id.lex + ) + + def create_constructor(self, attr_declarations: List[cool.AttrDeclarationNode], type_name): + self.current_function = self.register_function(f'ctor_{type_name}') + self.current_type = self.context.get_type(type_name) + instance = self.register_param(VariableInfo('self', self.current_type)) + + scope = Scope() + scope.define_variable('self', instance) + for attr in attr_declarations: + self.visit(attr, scope) + + self.register_instruction(ReturnNode(instance)) + + self.current_type = None + self.current_function = None def create_vtables(self, node: cool.ProgramNode): pass @@ -62,7 +81,7 @@ def visit(self, node, scope): def visit(self, node: cool.ProgramNode, scope=None): scope = Scope() self.sort_class_declar(node) - self.save_attr_init(node) + self.save_attr_initializations(node, scope) self.create_vtables(node) # entry self.current_function = self.register_function('entry') @@ -125,6 +144,7 @@ def visit(self, node: cool.FuncDeclarationNode, scope: Scope): @visitor.when(cool.AttrDeclarationNode) def visit(self, node: cool.AttrDeclarationNode, scope): + # typex = self.context.get_type(type_name) result = self.visit(node.expression, scope) if node.expression else 0 self_inst = scope.find_variable('self').name self.register_instruction( @@ -156,7 +176,9 @@ def visit(self, node: cool.NewNode, scope): new_local = self.define_internal_local() typex = self.context.get_type(node.type.lex) self.register_instruction(AllocateNode(new_local, typex.name)) - self.init_class_attr(scope, node.type.lex, new_local) + self.register_instruction(ArgNode(new_local)) + self.register_instruction( + StaticCallNode(f'ctor_{typex.name}', new_local)) return new_local @visitor.when(cool.IfThenElseNode) @@ -220,7 +242,6 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): for i, case in enumerate(case_expressions): next_branch_label = LabelNode(f'CASE_{case.id.lex}_{i}') child_scope = scope.create_child() - print(exp_type) expr_i = self.visit( case, child_scope, expr=expr, diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py index c51b9b7d..6123ffd4 100644 --- a/src/engine/parser/ast_parser.py +++ b/src/engine/parser/ast_parser.py @@ -62,6 +62,9 @@ def __init__(self, idx, typex, expression=None): self.line = idx.line self.column = idx.column + def __iter__(self): + yield from (self.id, self.type, self.expression) + class FuncDeclarationNode(DeclarationNode): def __init__(self, idx, params, return_type, body): From a05215804d55705439d4b8fa26e87a90e6e8fd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 17:43:16 -0500 Subject: [PATCH 103/191] Fix cyclic inheritance missing parents --- src/engine/visitors/collector.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 766c1a89..9fd1e43f 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -54,6 +54,10 @@ def visit(self, node): def visit(self, node): try: self.context.create_type(node.id.lex) + if(node.parent): + self.parents[node.id.lex] = node.parent.lex + else: + self.parents[node.id.lex] = 'Object' except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % ( node.line, node.column) + "SemanticError: " + se.text) From b2c9eb1d60da52756a566ac9c0dfa87beb997381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 17:56:06 -0500 Subject: [PATCH 104/191] Fix annotations --- src/engine/codegen/mips.py | 2 +- src/engine/codegen/to_mips.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 8968c1d3..0befb0b5 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -8,7 +8,7 @@ class GlobalDescriptor: - def __init__(self, dottypes: list(TypeNode), name_ptrs): + def __init__(self, dottypes, name_ptrs): self.vTable = None self.Types = Dict[str, MemoryType] = dict() diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 41342ae7..e9027960 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -43,7 +43,7 @@ def fill_vtable(self): - def build_tags(self, dottypes:list(TypeData)): + def build_tags(self, dottypes: List[TypeData]): base_tag = "classname_" tags = dict() From 853a1cdfc73ea9816ca68b0b6084d960735d5ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 18:47:58 -0500 Subject: [PATCH 105/191] Fix newline lexing errors --- src/engine/lexer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/lexer.py b/src/engine/lexer.py index 7191db13..6036ffb8 100644 --- a/src/engine/lexer.py +++ b/src/engine/lexer.py @@ -212,8 +212,8 @@ def t_string_eof(self, t): def t_string_all(self, t): r'[^\n]' if t.lexer.unterminated_slash: - spec = {'b': '\b', 't': '\t', 'f': '\f'} - if t.value in ['b', 't', 'f']: + spec = {'b': '\b', 't': '\t', 'f': '\f', 'n': '\n', '\\':'\\'} + if t.value in ['b', 't', 'f', 'n', '\\']: t.lexer.string += spec[t.value] else: t.lexer.string += t.value From b16444bd1f162418b43b0ebb54f7a3289f87129e Mon Sep 17 00:00:00 2001 From: thenai310 Date: Mon, 14 Dec 2020 18:52:43 -0500 Subject: [PATCH 106/191] data fixing --- src/engine/codegen/cil.py | 3 + src/test.cl | 135 +---------- src/test.mips | 463 +++----------------------------------- 3 files changed, 42 insertions(+), 559 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index d283d2fa..be8eeb64 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -68,6 +68,9 @@ def register_type(self, name): return type_node def register_data(self, value): + for data in self.dotdata: + if value == data.value: + return data vname = f'data_{len(self.dotdata)}' data_node = DataNode(vname, value) self.dotdata.append(data_node) diff --git a/src/test.cl b/src/test.cl index 025ea169..0c818f90 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,132 +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 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 - }; +class Main inherits IO { + main(): IO { + out_string("Hello, World.\n") + }; }; diff --git a/src/test.mips b/src/test.mips index ed94eb6e..07e08c87 100644 --- a/src/test.mips +++ b/src/test.mips @@ -41,71 +41,7 @@ type Bool { method type_name: function_type_name_at_Object method copy: function_copy_at_Object } -type Book { - attribute title - attribute author - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method initBook: function_initBook_at_Book - method print: function_print_at_Book -} -type Article { - attribute title - attribute author - attribute per_title - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method initBook: function_initBook_at_Book - method print: function_print_at_Article - method initArticle: function_initArticle_at_Article -} -type BookList { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method isNil: function_isNil_at_BookList - method cons: function_cons_at_BookList - method car: function_car_at_BookList - method cdr: function_cdr_at_BookList - method print_list: function_print_list_at_BookList -} -type Cons { - attribute xcar - attribute xcdr - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method isNil: function_isNil_at_Cons - method cons: function_cons_at_BookList - method car: function_car_at_Cons - method cdr: function_cdr_at_Cons - method print_list: function_print_list_at_Cons - method init: function_init_at_Cons -} -type Nil { +type Main { method abort: function_abort_at_Object @@ -115,48 +51,30 @@ type Nil { method out_int: function_out_int_at_IO method in_string: function_in_string_at_IO method in_int: function_in_int_at_IO - method isNil: function_isNil_at_Nil - method cons: function_cons_at_BookList - method car: function_car_at_BookList - method cdr: function_cdr_at_BookList - method print_list: function_print_list_at_Nil -} -type Main { - attribute books - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object method main: function_main_at_Main } .DATA -data_0 = "\n" -data_1 = "Invalid substring start" -data_2 = "Invalid substring length" -data_3 = "Invalid substring" -data_4 = "n" -data_5 = "title: " -data_6 = "n" -data_7 = "author: " -data_8 = "n" -data_9 = "periodical: " -data_10 = "- dynamic type was Book -n" -data_11 = "- dynamic type was Article -n" -data_12 = "Compilers, Principles, Techniques, and Tools" -data_13 = "Aho, Sethi, and Ullman" -data_14 = "The Top 100 CD_ROMs" -data_15 = "Ulanoff" -data_16 = "PC Magazine" +data_0 = "Abort called from class " +data_1 = "\n" +data_2 = "Invalid substring start" +data_3 = "Invalid substring length" +data_4 = "Invalid substring" +data_5 = "Hello, World.n" .CODE function function_abort_at_Object { PARAM self - + LOCAL local_abort_at_Object_internal_0 + LOCAL local_abort_at_Object_internal_1 + LOCAL local_abort_at_Object_internal_2 - PRINTSTR abort with type - ERROR 0 + local_abort_at_Object_internal_0 = TYPENAME self + local_abort_at_Object_internal_1 = CONCAT data_0 local_abort_at_Object_internal_0 + local_abort_at_Object_internal_2 = CONCAT local_abort_at_Object_internal_1 data_1 + PRINTSTR local_abort_at_Object_internal_2 + ABORT } function function_copy_at_Object { PARAM self @@ -212,20 +130,20 @@ function function_substr_at_String { local_substr_at_String_internal_2 = LENGTH self local_substr_at_String_internal_5 = local_substr_at_String_internal_3 <= start IF local_substr_at_String_internal_5 GOTO error1 - local_substr_at_String_internal_8 = CONCAT data_1 data_0 + local_substr_at_String_internal_8 = CONCAT data_2 data_1 PRINTSTR local_substr_at_String_internal_8 ERROR 0 LABEL error1 local_substr_at_String_internal_6 = local_substr_at_String_internal_3 <= length IF local_substr_at_String_internal_6 GOTO error2 - local_substr_at_String_internal_8 = CONCAT data_2 data_0 + local_substr_at_String_internal_8 = CONCAT data_3 data_1 PRINTSTR local_substr_at_String_internal_8 ERROR 0 LABEL error2 local_substr_at_String_internal_4 = start + length local_substr_at_String_internal_7 = local_substr_at_String_internal_4 <= local_substr_at_String_internal_2 IF local_substr_at_String_internal_7 GOTO error3 - local_substr_at_String_internal_8 = CONCAT data_3 data_0 + local_substr_at_String_internal_8 = CONCAT data_4 data_1 PRINTSTR local_substr_at_String_internal_8 ERROR 0 LABEL error3 @@ -262,6 +180,13 @@ function function_in_int_at_IO { local_in_int_at_IO_internal_0 = READINT RETURN local_in_int_at_IO_internal_0 } +function ctor_Main { + PARAM self + + + + RETURN self +} function entry { @@ -269,338 +194,20 @@ function entry { LOCAL local__internal_1 local__internal_0 = ALLOCATE Main - SETATTR books OF self_Main = 0 ARG local__internal_0 local__internal_1 = CALL function_main_at_Main -} -function function_initBook_at_Book { - PARAM self - PARAM title_p - PARAM author_p - - LOCAL local_initBook_at_Book_internal_0 - - SETATTR title OF self_Book = title_p - SETATTR author OF self_Book = author_p - local_initBook_at_Book_internal_0 = self - RETURN local_initBook_at_Book_internal_0 -} -function function_print_at_Book { - PARAM self - - LOCAL local_print_at_Book_internal_0 - LOCAL local_print_at_Book_internal_1 - LOCAL local_print_at_Book_internal_2 - LOCAL local_print_at_Book_internal_3 - LOCAL local_print_at_Book_internal_4 - LOCAL local_print_at_Book_internal_5 - LOCAL local_print_at_Book_internal_6 - LOCAL local_print_at_Book_internal_7 - LOCAL local_print_at_Book_internal_8 - LOCAL local_print_at_Book_internal_9 - LOCAL local_print_at_Book_internal_10 - LOCAL local_print_at_Book_internal_11 - LOCAL local_print_at_Book_internal_12 - - local_print_at_Book_internal_2 = LOAD data_4 - ARG local_print_at_Book_internal_2 - local_print_at_Book_internal_4 = GETATTR self title - ARG local_print_at_Book_internal_4 - local_print_at_Book_internal_6 = LOAD data_5 - ARG local_print_at_Book_internal_6 - ARG self - local_print_at_Book_internal_5 = VCALL Book out_string - ARG local_print_at_Book_internal_5 - local_print_at_Book_internal_3 = VCALL Book out_string - ARG local_print_at_Book_internal_3 - local_print_at_Book_internal_1 = VCALL Book out_string - local_print_at_Book_internal_8 = LOAD data_6 - ARG local_print_at_Book_internal_8 - local_print_at_Book_internal_10 = GETATTR self author - ARG local_print_at_Book_internal_10 - local_print_at_Book_internal_12 = LOAD data_7 - ARG local_print_at_Book_internal_12 - ARG self - local_print_at_Book_internal_11 = VCALL Book out_string - ARG local_print_at_Book_internal_11 - local_print_at_Book_internal_9 = VCALL Book out_string - ARG local_print_at_Book_internal_9 - local_print_at_Book_internal_7 = VCALL Book out_string - local_print_at_Book_internal_0 = self - RETURN local_print_at_Book_internal_0 -} -function function_initArticle_at_Article { - PARAM self - PARAM title_p - PARAM author_p - PARAM per_title_p - - LOCAL local_initArticle_at_Article_internal_0 - LOCAL local_initArticle_at_Article_internal_1 - - ARG author_p - ARG title_p - ARG self - local_initArticle_at_Article_internal_1 = VCALL Article initBook - SETATTR per_title OF self_Article = per_title_p - local_initArticle_at_Article_internal_0 = self - RETURN local_initArticle_at_Article_internal_0 -} -function function_print_at_Article { - PARAM self - - LOCAL local_print_at_Article_internal_0 - LOCAL local_print_at_Article_internal_1 - LOCAL local_print_at_Article_internal_2 - LOCAL local_print_at_Article_internal_3 - LOCAL local_print_at_Article_internal_4 - LOCAL local_print_at_Article_internal_5 - LOCAL local_print_at_Article_internal_6 - LOCAL local_print_at_Article_internal_7 - - ARG self - local_print_at_Article_internal_1 = CALL function_print_at_Book - local_print_at_Article_internal_3 = LOAD data_8 - ARG local_print_at_Article_internal_3 - local_print_at_Article_internal_5 = GETATTR self per_title - ARG local_print_at_Article_internal_5 - local_print_at_Article_internal_7 = LOAD data_9 - ARG local_print_at_Article_internal_7 - ARG self - local_print_at_Article_internal_6 = VCALL Article out_string - ARG local_print_at_Article_internal_6 - local_print_at_Article_internal_4 = VCALL Article out_string - ARG local_print_at_Article_internal_4 - local_print_at_Article_internal_2 = VCALL Article out_string - local_print_at_Article_internal_0 = self - RETURN local_print_at_Article_internal_0 -} -function function_isNil_at_BookList { - PARAM self - - LOCAL local_isNil_at_BookList_internal_0 - LOCAL local_isNil_at_BookList_internal_1 - - ARG self - local_isNil_at_BookList_internal_1 = VCALL BookList abort - local_isNil_at_BookList_internal_0 = 1 - RETURN local_isNil_at_BookList_internal_0 -} -function function_cons_at_BookList { - PARAM self - PARAM hd - - LOCAL local_cons_at_BookList_new_cell_0 - LOCAL local_cons_at_BookList_internal_1 - LOCAL local_cons_at_BookList_internal_2 - - local_cons_at_BookList_internal_1 = ALLOCATE Cons - SETATTR xcar OF self_Cons = 0 - SETATTR xcdr OF self_Cons = 0 - local_cons_at_BookList_new_cell_0 = local_cons_at_BookList_internal_1 - ARG self - ARG hd - ARG new_cell - local_cons_at_BookList_internal_2 = VCALL Cons init - RETURN local_cons_at_BookList_internal_2 -} -function function_car_at_BookList { - PARAM self - - LOCAL local_car_at_BookList_internal_0 - LOCAL local_car_at_BookList_internal_1 - LOCAL local_car_at_BookList_internal_2 - - ARG self - local_car_at_BookList_internal_1 = VCALL BookList abort - local_car_at_BookList_internal_2 = ALLOCATE Book - SETATTR title OF self_Book = 0 - SETATTR author OF self_Book = 0 - local_car_at_BookList_internal_0 = local_car_at_BookList_internal_2 - RETURN local_car_at_BookList_internal_0 -} -function function_cdr_at_BookList { - PARAM self - - LOCAL local_cdr_at_BookList_internal_0 - LOCAL local_cdr_at_BookList_internal_1 - LOCAL local_cdr_at_BookList_internal_2 - - ARG self - local_cdr_at_BookList_internal_1 = VCALL BookList abort - local_cdr_at_BookList_internal_2 = ALLOCATE BookList - local_cdr_at_BookList_internal_0 = local_cdr_at_BookList_internal_2 - RETURN local_cdr_at_BookList_internal_0 -} -function function_print_list_at_BookList { - PARAM self - - LOCAL local_print_list_at_BookList_internal_0 - - ARG self - local_print_list_at_BookList_internal_0 = VCALL BookList abort - RETURN local_print_list_at_BookList_internal_0 -} -function function_isNil_at_Cons { - PARAM self - - - - RETURN 0 -} -function function_init_at_Cons { - PARAM self - PARAM hd - PARAM tl - - LOCAL local_init_at_Cons_internal_0 - - SETATTR xcar OF self_Cons = hd - SETATTR xcdr OF self_Cons = tl - local_init_at_Cons_internal_0 = self - RETURN local_init_at_Cons_internal_0 -} -function function_car_at_Cons { - PARAM self - - LOCAL local_car_at_Cons_internal_0 - - local_car_at_Cons_internal_0 = GETATTR self xcar - RETURN local_car_at_Cons_internal_0 -} -function function_cdr_at_Cons { - PARAM self - - LOCAL local_cdr_at_Cons_internal_0 - - local_cdr_at_Cons_internal_0 = GETATTR self xcdr - RETURN local_cdr_at_Cons_internal_0 -} -function function_print_list_at_Cons { - PARAM self - - LOCAL local_print_list_at_Cons_internal_0 - LOCAL local_print_list_at_Cons_internal_1 - LOCAL local_print_list_at_Cons_internal_2 - LOCAL local_print_list_at_Cons_internal_3 - LOCAL local_print_list_at_Cons_internal_4 - LOCAL local_print_list_at_Cons_internal_5 - LOCAL local_print_list_at_Cons_internal_6 - LOCAL local_print_list_at_Cons_internal_7 - LOCAL local_print_list_at_Cons_internal_8 - LOCAL local_print_list_at_Cons_internal_9 - LOCAL local_print_list_at_Cons_internal_10 - LOCAL local_print_list_at_Cons_internal_11 - LOCAL local_print_list_at_Cons_internal_12 - LOCAL local_print_list_at_Cons_internal_13 - LOCAL local_print_list_at_Cons_internal_14 - - local_print_list_at_Cons_internal_2 = GETATTR self xcar - ARG local_print_list_at_Cons_internal_2 - local_print_list_at_Cons_internal_1 = VCALL Book print - local_print_list_at_Cons_internal_4 = TYPEOF local_print_list_at_Cons_internal_1 - local_print_list_at_Cons_internal_5 = COMFORM local_print_list_at_Cons_internal_1 TYPE: Book - IF local_print_list_at_Cons_internal_1 GOTO - GOTO CASE_dummy_0 - LABEL CASE_MATCH_dummy_Book - local_print_list_at_Cons_internal_6 = local_print_list_at_Cons_internal_1 - local_print_list_at_Cons_internal_8 = LOAD data_10 - ARG local_print_list_at_Cons_internal_8 - ARG self - local_print_list_at_Cons_internal_7 = VCALL Cons out_string - local_print_list_at_Cons_internal_3 = local_print_list_at_Cons_internal_7 - GOTO END_1 - LABEL CASE_dummy_0 - local_print_list_at_Cons_internal_9 = COMFORM local_print_list_at_Cons_internal_1 TYPE: Article - IF local_print_list_at_Cons_internal_1 GOTO - GOTO CASE_dummy_1 - LABEL CASE_MATCH_dummy_Article - local_print_list_at_Cons_internal_10 = local_print_list_at_Cons_internal_1 - local_print_list_at_Cons_internal_12 = LOAD data_11 - ARG local_print_list_at_Cons_internal_12 - ARG self - local_print_list_at_Cons_internal_11 = VCALL Cons out_string - local_print_list_at_Cons_internal_3 = local_print_list_at_Cons_internal_11 - GOTO END_1 - LABEL CASE_dummy_1 - LABEL ERROR_CASE_1 - ERROR 0 - LABEL END_1 - local_print_list_at_Cons_internal_14 = GETATTR self xcdr - ARG local_print_list_at_Cons_internal_14 - local_print_list_at_Cons_internal_13 = VCALL BookList print_list - local_print_list_at_Cons_internal_0 = local_print_list_at_Cons_internal_13 - RETURN local_print_list_at_Cons_internal_0 -} -function function_isNil_at_Nil { - PARAM self - - - - RETURN 1 -} -function function_print_list_at_Nil { - PARAM self - - - - RETURN 1 + CLEAR 1 ARGS } function function_main_at_Main { PARAM self - LOCAL local_main_at_Main_a_book_0 + LOCAL local_main_at_Main_internal_0 LOCAL local_main_at_Main_internal_1 - LOCAL local_main_at_Main_internal_2 - LOCAL local_main_at_Main_internal_3 - LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_an_article_5 - LOCAL local_main_at_Main_internal_6 - LOCAL local_main_at_Main_internal_7 - LOCAL local_main_at_Main_internal_8 - LOCAL local_main_at_Main_internal_9 - LOCAL local_main_at_Main_internal_10 - LOCAL local_main_at_Main_internal_11 - LOCAL local_main_at_Main_internal_12 - LOCAL local_main_at_Main_internal_13 - LOCAL local_main_at_Main_internal_14 - LOCAL local_main_at_Main_internal_15 - LOCAL local_main_at_Main_internal_16 - - local_main_at_Main_internal_2 = LOAD data_12 - local_main_at_Main_internal_3 = LOAD data_13 - ARG local_main_at_Main_internal_3 - ARG local_main_at_Main_internal_2 - local_main_at_Main_internal_4 = ALLOCATE Book - SETATTR title OF self_Book = 0 - SETATTR author OF self_Book = 0 - ARG local_main_at_Main_internal_4 - local_main_at_Main_internal_1 = VCALL Book initBook - local_main_at_Main_a_book_0 = local_main_at_Main_internal_1 - local_main_at_Main_internal_7 = LOAD data_14 - local_main_at_Main_internal_8 = LOAD data_15 - local_main_at_Main_internal_9 = LOAD data_16 - ARG local_main_at_Main_internal_9 - ARG local_main_at_Main_internal_8 - ARG local_main_at_Main_internal_7 - local_main_at_Main_internal_10 = ALLOCATE Article - SETATTR title OF self_Article = 0 - SETATTR author OF self_Article = 0 - SETATTR per_title OF self_Article = 0 - ARG local_main_at_Main_internal_10 - local_main_at_Main_internal_6 = VCALL Article initArticle - local_main_at_Main_an_article_5 = local_main_at_Main_internal_6 - ARG an_article - ARG a_book - local_main_at_Main_internal_14 = ALLOCATE Nil - ARG local_main_at_Main_internal_14 - local_main_at_Main_internal_13 = VCALL Nil cons - ARG local_main_at_Main_internal_13 - local_main_at_Main_internal_12 = VCALL Cons cons - SETATTR books OF self_Main = local_main_at_Main_internal_12 - local_main_at_Main_internal_16 = GETATTR self books - ARG local_main_at_Main_internal_16 - local_main_at_Main_internal_15 = VCALL BookList print_list - local_main_at_Main_internal_11 = local_main_at_Main_internal_15 - RETURN local_main_at_Main_internal_11 -} + + local_main_at_Main_internal_1 = LOAD data_5 + ARG local_main_at_Main_internal_1 + ARG self + local_main_at_Main_internal_0 = VCALL Main out_string + CLEAR 2 ARGS + RETURN local_main_at_Main_internal_0 +} \ No newline at end of file From 44faa6d5fef5000c6e09938212ac5bb804898fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 18:57:36 -0500 Subject: [PATCH 107/191] Fix Vtable initialization --- src/engine/codegen/mips.py | 6 +++--- src/engine/codegen/to_mips.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 0befb0b5..c8913f55 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -8,9 +8,9 @@ class GlobalDescriptor: - def __init__(self, dottypes, name_ptrs): + def __init__(self, dottypes: List[TypeNode], name_ptrs): self.vTable = None - self.Types = Dict[str, MemoryType] = dict() + self.Types = {} methods = {} @@ -28,7 +28,7 @@ def __init__(self, dottypes, name_ptrs): methds.append(method_name) end_method += 1 - self.Types[dottype.name] = MemoryType(dottype.name, index, dottype.attrs, methds, start_method, name_ptrs[dottype.name]) + self.Types[dottype.name] = MemoryType(dottype.name, index, dottype.attributes, methds, start_method, name_ptrs[dottype.name]) start_method = end_method diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index e9027960..70e39c77 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -36,7 +36,7 @@ def fill_vtable(self): index = 0 self.mips.comment("Build VTable") - for _,tag in self.global_descriptor.vTable.methods: + for _,tag in self.global_descriptor.vTable.methods.items(): self.mips.la(reg.s0, tag) self.mips.sw(reg.s0, f'{index}({reg.s7})') index += 1 From 0e1d2287a22d0a1cc385b51115059a04719c997f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 21:07:02 -0500 Subject: [PATCH 108/191] Fix minor issues at mips generation --- src/engine/codegen/mips.py | 2 +- src/engine/codegen/to_mips.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index c8913f55..c9b07175 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -159,7 +159,7 @@ def _write_data(self, line): self.dotdata.append(line) def data_label(self, lname): - self._write_data(f'{lname}') + self._write_data(f'{lname}:') def empty_line(self): self._write('') diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 70e39c77..6bca015c 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -81,8 +81,8 @@ def get_pc(self, dst): return label def get_label(self): - return f"mip_label_{self.label_count}" self.label_count += 1 + return f"mip_label_{self.label_count}" def load_memory(self, dst, arg: str): if arg in self.arguments or arg in self.local_vars: @@ -323,7 +323,7 @@ def visit(self, node: AllocateNode): self.store_memory(reg.s1, node.dest) self.mips.li(reg.s0, type_data.pos) - self.mips.store_memory(reg.s0, reg.s1) + self.mips.store_memory(reg.s0, self.mips.offset(reg.s1)) self.mips.la(reg.s0, type_data.str) self.mips.store_memory( @@ -348,7 +348,7 @@ def visit(self, node: AllocateNode): def visit(self, node: TypeOfNode): self.mips.comment("TypeOfNode") self.load_memory(reg.s0, node.obj) - self.mips.load_memory(reg.s1, reg.s0) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0)) self.store_memory(reg.s1, node.dest) @visitor.when(LabelNode) @@ -549,7 +549,7 @@ def visit(self, node: StringEqualNode): self.mips.label(end_ok_label) self.mips.li(reg.v0, 1) self.mips.label(end_label) - self.mips.store_memory(reg.v0, node.dest) + self.store_memory(reg.v0, node.dest) @visitor.when(LoadNode) def visit(self, node: LoadNode): From 2c1f98e7c9c4cac527877bf6431cd3e4fb19b9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 21:17:34 -0500 Subject: [PATCH 109/191] Improve Typeof Node --- src/engine/codegen/to_mips.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 6bca015c..ceb9666e 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -347,8 +347,10 @@ def visit(self, node: AllocateNode): @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): self.mips.comment("TypeOfNode") + # Cargar la direccion de memoria self.load_memory(reg.s0, node.obj) - self.mips.load_memory(reg.s1, self.mips.offset(reg.s0)) + # El offset 3 para ptr al name + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0,3)) self.store_memory(reg.s1, node.dest) @visitor.when(LabelNode) From f97a8e139443917a4ba9dfcee70b8188b7a32834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 21:33:01 -0500 Subject: [PATCH 110/191] Add global descriptor getitem method --- src/engine/codegen/mips.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index c9b07175..290fdfa7 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -35,6 +35,12 @@ def __init__(self, dottypes: List[TypeNode], name_ptrs): self.vTable = VTable(methods) + def __getitem__(self, id): + for mem in self.Types.values(): + if mem.id == id: + return mem + + raise Exception(f"Class {id} not present") class VTable: def __init__(self, methods): @@ -51,9 +57,9 @@ def get_index(self, name): class MemoryType: - def __init__(self, name, id, attrs, methods, base_index, ptr_name): + def __init__(self, name, _id, attrs, methods, base_index, ptr_name): self.name = name - self.id = id + self.id = _id self.attrs = attrs self.methods = methods self.vtable = base_index From e1fd73c04190666f0a232b71f3f9c9e0f93b9c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:02:53 -0500 Subject: [PATCH 111/191] Redefine Allocate Memory --- src/engine/codegen/to_mips.py | 63 +++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index ceb9666e..513f2842 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -313,36 +313,57 @@ def visit(self, node: IsVoidNode): @visitor.when(AllocateNode) def visit(self, node: AllocateNode): - type_data = self.types_offsets[node.type] - - length = len(type_data.attr_offsets) + len(type_data.func_offsets) + 2 + # ---------- + # | ID | + # ---------- + # | Size | + # ---------- + # |Ptr_Name| + # ---------- + # |Ptr_Vtbl| + # ---------- + # | Attr1 | + # ---------- + # | Attr2 | + # .......... + # .......... + # + # s1 start addr of the class + # + self.mips.comment(f"Allocate space for {node.type}") + type_descritptor :MemoryType = self.global_descriptor.Types[node.type] + + length = type_descritptor.size() length *= self.data_size + + #sbrk call self.mips.li(reg.a0, length) self.mips.sbrk() self.mips.move(reg.s1, reg.v0) + + #pass object reference to node.dest self.store_memory(reg.s1, node.dest) - self.mips.li(reg.s0, type_data.pos) + # Store Class ID + self.mips.li(reg.s0, type_descritptor.id) self.mips.store_memory(reg.s0, self.mips.offset(reg.s1)) - self.mips.la(reg.s0, type_data.str) - self.mips.store_memory( - reg.s0, self.mips.offset(reg.v0, self.data_size)) - + # Store Class size self.mips.li(reg.s0, length) - self.mips.store_memory( - reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) - - for offset in type_data.attr_offsets.values(): - self.mips.store_memory(reg.zero, self.mips.offset( - reg.s1, offset * self.data_size)) - - for name, offset in type_data.func_offsets.items(): - direct_name = type_data.func_names[name] - self.mips.la(reg.s0, direct_name) - self.mips.store_memory( - reg.s0, - self.mips.offset(reg.s1, offset * self.data_size)) + self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, self.data_size)) + + # Store Class Name Ptr + self.mips.la(reg.s0, type_descritptor.ptr_name) + self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) + + # Store Class Vtable Ptr + self.mips.load_memory(reg.s0, self.mips.offset(self.vtable_reg, type_descritptor.vtable * self.data_size)) # first function on vtable + self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 3 * self.data_size)) + + # Reserve Attrs Space + for number,_ in enumerate(type_descritptor.attrs): + _offset = 4 + number + self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, offset * self.data_size) @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): From 5442d45dc91863ea66cc5fb362863ef1d5dae3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:03:44 -0500 Subject: [PATCH 112/191] Add missing ) --- src/engine/codegen/to_mips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 513f2842..9097c2b7 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -363,7 +363,7 @@ def visit(self, node: AllocateNode): # Reserve Attrs Space for number,_ in enumerate(type_descritptor.attrs): _offset = 4 + number - self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, offset * self.data_size) + self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, offset * self.data_size)) @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): From 0916d7da55d83de95f085c079cdce853e37f9a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:22:30 -0500 Subject: [PATCH 113/191] Redefine Dynamic Calls --- src/engine/codegen/to_mips.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 9097c2b7..f8d8b83b 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -367,7 +367,7 @@ def visit(self, node: AllocateNode): @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): - self.mips.comment("TypeOfNode") + self.mips.comment(f"TypeOfNode of {node.obj}") # Cargar la direccion de memoria self.load_memory(reg.s0, node.obj) # El offset 3 para ptr al name @@ -398,12 +398,19 @@ def visit(self, node: StaticCallNode): @visitor.when(DynamicCallNode) def visit(self, node: DynamicCallNode): - self.mips.comment("DynamicCallNode") - type_data = self.types_offsets[node.type] - offset = type_data.func_offsets[node.method] * self.data_size + self.mips.comment(f"DynamicCallNode {node.type} {node.method}") + type_descritptor = self.global_descriptor.Types[node.type] + + offset = type_descritptor.get_method_index(node.method) * self.data_size self.load_memory(reg.s0, node.obj) - self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, offset)) - self.mips.jalr(reg.s1) + + # vtable ptr in position 4 (0 .. 3) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) + # retrieve function location + self.mips.load_memory(reg.s2, self.mips.offset(reg.s1, offset)) + + # store result at v0 + self.mips.jalr(reg.s2) self.store_memory(reg.v0, node.dest) @visitor.when(ArgNode) From 6f23d00a329e08a43173139bf16e15d820a9a8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:34:17 -0500 Subject: [PATCH 114/191] Fix typo --- src/engine/codegen/mips.py | 2 +- src/engine/codegen/to_mips.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 290fdfa7..b3f0c63f 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -72,7 +72,7 @@ def get_attr_index(self, attr): return 4 + self.attrs.index(attr) def get_method_index(self, method): - return self.vtable + self.methods.index(method) + return self.methods.index(method) def get_ptr_name(self): return self.ptr_name diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index f8d8b83b..411f8b56 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -363,7 +363,7 @@ def visit(self, node: AllocateNode): # Reserve Attrs Space for number,_ in enumerate(type_descritptor.attrs): _offset = 4 + number - self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, offset * self.data_size)) + self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, _offset * self.data_size)) @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): From 85b99ff3005ac8d412efa96553b1efe438448af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:38:16 -0500 Subject: [PATCH 115/191] Fix Vtable allocation error --- src/engine/codegen/mips.py | 8 ++++---- src/engine/codegen/to_mips.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index b3f0c63f..eb335438 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -2,7 +2,7 @@ from typing import Dict, List from .cil_ast import TypeNode -word_size = 2 +word_size = 4 string_max_size = 1000 @@ -523,15 +523,15 @@ def mflo(self, rdest): self._write(f'mflo {rdest}') #VTble allocate - def allocate_vtable(self, size): + def allocate_vtable(self, size, _reg): ''' - Allocate Vtable and store its adrress in s7 + Allocate Vtable and store its adrress into reg ''' self.comment("Allocate Vtable") vtable_size = size * word_size self.li(reg.a0, vtable_size) self.sbrk() - self.move(reg.a0, reg.s7) + self.move(_reg, reg.v0) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 411f8b56..0ed2aa83 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -129,7 +129,7 @@ def visit(self, node: ProgramNode): self.global_descriptor = GlobalDescriptor(node.dottypes, tags) - self.mips.allocate_vtable(self.global_descriptor.vTable.size()) + self.mips.allocate_vtable(self.global_descriptor.vTable.size(), self.vtable_reg) self.fill_vtable() From 8da56ba13f12abe12ff00d639dce92609b35d5d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Mon, 14 Dec 2020 22:41:19 -0500 Subject: [PATCH 116/191] Improve fill_vtable method --- src/engine/codegen/to_mips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 0ed2aa83..1bd75e16 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -38,7 +38,7 @@ def fill_vtable(self): self.mips.comment("Build VTable") for _,tag in self.global_descriptor.vTable.methods.items(): self.mips.la(reg.s0, tag) - self.mips.sw(reg.s0, f'{index}({reg.s7})') + self.mips.store_memory(reg.s0, self.mips.offset(self.vtable_reg, index*self.data_size)) index += 1 From 13cd726ec6c476e948e3c06fbf6ab9d5f23e9f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 07:35:48 -0500 Subject: [PATCH 117/191] Improve GetAttributeNode Mips generation --- src/engine/codegen/to_mips.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 1bd75e16..acc7542a 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -201,11 +201,14 @@ def visit(self, node: LocalNode, index=0): @visitor.when(GetAttribNode) def visit(self, node: GetAttribNode): - self.mips.comment("GetAttribNode") + self.mips.comment(f"GetAttribNode {node.dest} = {node.ojb}.{node.attrib} Type:{node.type}") self.load_memory(reg.t0, node.obj) - type_data = self.types_offsets[node.type] - offset = type_data.attr_offsets[node.attrib] - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset)) + # get type info + type_descritptor :MemoryType = self.global_descriptor.Types[node.type] + # get attr offset + offset = type_descritptor.get_attr_index(node.attrib) + # retrieve offset from memory + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset * self.data_size)) self.store_memory(reg.t1, node.dest) @visitor.when(SetAttribNode) From b0b318154c2f07d96e52290a9551d53fe2bb7535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 14:17:59 -0500 Subject: [PATCH 118/191] Bug fixing changes --- src/engine/codegen/mips.py | 10 +++++++--- src/engine/codegen/to_mips.py | 20 +++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index eb335438..8eb2ae95 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -24,14 +24,13 @@ def __init__(self, dottypes: List[TypeNode], name_ptrs): methds = [] for (method_name, method_tag) in dottype.methods: - methods[method_name] = method_tag + name = dottype.name + "_" + method_name + methods[name] = method_tag methds.append(method_name) end_method += 1 self.Types[dottype.name] = MemoryType(dottype.name, index, dottype.attributes, methds, start_method, name_ptrs[dottype.name]) - start_method = end_method - self.vTable = VTable(methods) @@ -55,6 +54,11 @@ def __getitem__(self, name): def get_index(self, name): return list(self.methods.keys()).index(name) + @staticmethod + def build_name(name, _type): + return f"{_type}_{name}" + + class MemoryType: def __init__(self, name, _id, attrs, methods, base_index, ptr_name): diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index acc7542a..e067afa8 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -23,7 +23,7 @@ def __init__(self, data_size=4): reg.s4, reg.s5, reg.s6, - reg.s7, ] + ] self.label_count = 0 self.vtable_reg = reg.s7 self.mips = MipsCode() @@ -213,7 +213,7 @@ def visit(self, node: GetAttribNode): @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): - self.mips.comment("SetAttribNode") + self.mips.comment(f"SetAttribNode {node.obj}.{node.attrib} = {node.dest} Type:{node.value}") self.load_memory(reg.t0, node.obj) type_data = self.types_offsets[node.type] offset = type_data.attr_offsets[node.attrib] @@ -360,7 +360,8 @@ def visit(self, node: AllocateNode): self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) # Store Class Vtable Ptr - self.mips.load_memory(reg.s0, self.mips.offset(self.vtable_reg, type_descritptor.vtable * self.data_size)) # first function on vtable + print(f"First methohd of class {node.type} {type_descritptor.vtable * self.data_size}") + self.mips.li(reg.s0, type_descritptor.vtable * self.data_size) # first function on vtable self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 3 * self.data_size)) # Reserve Attrs Space @@ -405,15 +406,19 @@ def visit(self, node: DynamicCallNode): type_descritptor = self.global_descriptor.Types[node.type] offset = type_descritptor.get_method_index(node.method) * self.data_size + # print("offset", offset, node.method, node.type, type_descritptor.methods) + # print(node.obj, node.type) self.load_memory(reg.s0, node.obj) # vtable ptr in position 4 (0 .. 3) self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) + self.mips.addi(reg.s2, reg.s1, offset) + self.mips.addu(reg.s3, reg.s2, reg.s7) # retrieve function location - self.mips.load_memory(reg.s2, self.mips.offset(reg.s1, offset)) + self.mips.load_memory(reg.s4, self.mips.offset(reg.s3)) - # store result at v0 - self.mips.jalr(reg.s2) + # retrieve result from v0 + self.mips.jalr(reg.s4) self.store_memory(reg.v0, node.dest) @visitor.when(ArgNode) @@ -586,7 +591,8 @@ def visit(self, node: StringEqualNode): @visitor.when(LoadNode) def visit(self, node: LoadNode): - self.load_memory(reg.t0, node.msg) + self.load_memory(reg.s0, node.msg) + self.store_memory(reg.s0, node.dest) def copy_substr(self, src, dst, length): loop = self.get_label() From 073c43fa570f68f8925bce0a5ff22eb6605d8c31 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Tue, 15 Dec 2020 14:31:13 -0500 Subject: [PATCH 119/191] type work --- src/engine/codegen/mips.py | 51 ++++++++------- src/engine/codegen/to_mips.py | 117 +++++++++++++++------------------- 2 files changed, 77 insertions(+), 91 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index eb335438..2fe5878d 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -6,6 +6,7 @@ string_max_size = 1000 + class GlobalDescriptor: def __init__(self, dottypes: List[TypeNode], name_ptrs): @@ -28,10 +29,10 @@ def __init__(self, dottypes: List[TypeNode], name_ptrs): methds.append(method_name) end_method += 1 - self.Types[dottype.name] = MemoryType(dottype.name, index, dottype.attributes, methds, start_method, name_ptrs[dottype.name]) + self.Types[dottype.name] = MemoryType( + dottype.name, index, dottype.attributes, methds, start_method, name_ptrs[dottype.name]) start_method = end_method - self.vTable = VTable(methods) @@ -39,8 +40,10 @@ def __getitem__(self, id): for mem in self.Types.values(): if mem.id == id: return mem - + raise Exception(f"Class {id} not present") + + class VTable: def __init__(self, methods): @@ -55,6 +58,7 @@ def __getitem__(self, name): def get_index(self, name): return list(self.methods.keys()).index(name) + class MemoryType: def __init__(self, name, _id, attrs, methods, base_index, ptr_name): @@ -70,13 +74,14 @@ def size(self): def get_attr_index(self, attr): return 4 + self.attrs.index(attr) - + def get_method_index(self, method): return self.methods.index(method) def get_ptr_name(self): return self.ptr_name + class Registers: zero = '$zero' # Constant 0 at = '$at' # Reserved for assembler @@ -112,24 +117,24 @@ class Registers: ra = '$ra' # Return address(used by function call) -class TypeData: - def __init__(self, type_number: int, typex: TypeNode): - self.pos = type_number - self.type = typex - self.str: str = typex.name_dir - self.attr_offsets: Dict[str, int] = dict() - self.func_offsets: Dict[str, int] = dict() - self.func_names: Dict[str, str] = dict() - self.set_type() +# class TypeData: + # def __init__(self, type_number: int, typex: TypeNode): + # self.pos = type_number + # self.type = typex + # self.str: str = typex.name_dir + # self.attr_offsets: Dict[str, int] = dict() + # self.func_offsets: Dict[str, int] = dict() + # self.func_names: Dict[str, str] = dict() + # self.set_type() - def set_type(self): - for idx, feature in enumerate(self.type.features): - if isinstance(feature, str): - self.attr_offsets[feature] = idx + 2 - else: - func_name, long_name = feature - self.func_offsets[func_name] = idx + 2 - self.func_names[func_name] = long_name + # def set_type(self): + # for idx, feature in enumerate(self.type.features): + # if isinstance(feature, str): + # self.attr_offsets[feature] = idx + 2 + # else: + # func_name, long_name = feature + # self.func_offsets[func_name] = idx + 2 + # self.func_names[func_name] = long_name class MipsLabel(str, Enum): @@ -522,7 +527,7 @@ def mflo(self, rdest): ''' self._write(f'mflo {rdest}') - #VTble allocate + # VTble allocate def allocate_vtable(self, size, _reg): ''' Allocate Vtable and store its adrress into reg @@ -533,5 +538,3 @@ def allocate_vtable(self, size, _reg): self.li(reg.a0, vtable_size) self.sbrk() self.move(_reg, reg.v0) - - diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index acc7542a..c0848510 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -1,6 +1,6 @@ from .cil_ast import * from ..cp import visitor -from .mips import MipsCode, MemoryType, MipsLabel, VTable, TypeData, GlobalDescriptor, word_size, string_max_size +from .mips import MipsCode, MemoryType, MipsLabel, VTable, GlobalDescriptor, word_size, string_max_size from .mips import Registers as reg from typing import Dict, List @@ -9,7 +9,7 @@ class CIL_TO_MIPS: def __init__(self, data_size=4): self.types = [] - self.types_offsets: Dict[str, MemoryType] = dict() + # self.types_offsets: Dict[str, MemoryType] = dict() self.arguments = {} self.local_vars = {} self.data_segment = [] @@ -23,27 +23,26 @@ def __init__(self, data_size=4): reg.s4, reg.s5, reg.s6, - reg.s7, ] + ] self.label_count = 0 self.vtable_reg = reg.s7 self.mips = MipsCode() - def build_types(self, types): - for idx, typex in enumerate(types): - self.types_offsets[typex.name] = TypeData(idx, typex) + # def build_types(self, types): + # for idx, typex in enumerate(types): + # self.types_offsets[typex.name] = TypeData(idx, typex) def fill_vtable(self): index = 0 self.mips.comment("Build VTable") - for _,tag in self.global_descriptor.vTable.methods.items(): + for _, tag in self.global_descriptor.vTable.methods.items(): self.mips.la(reg.s0, tag) - self.mips.store_memory(reg.s0, self.mips.offset(self.vtable_reg, index*self.data_size)) + self.mips.store_memory(reg.s0, self.mips.offset( + self.vtable_reg, index*self.data_size)) index += 1 - - - def build_tags(self, dottypes: List[TypeData]): + def build_tags(self, dottypes: List[TypeNode]): base_tag = "classname_" tags = dict() @@ -68,21 +67,9 @@ def get_offset(self, arg: str): raise Exception( f"load_memory: The direction {arg} isn't an address") - def get_pc(self, dst): - label = self.get_label() - end = self.get_label() - - self.mips.j(end) - self.mips.label(label) - self.mips.move(dst, reg.ra) - self.mips.jr(reg.ra) - self.mips.label(end) - - return label - def get_label(self): self.label_count += 1 - return f"mip_label_{self.label_count}" + return f"mips_label_{self.label_count}" def load_memory(self, dst, arg: str): if arg in self.arguments or arg in self.local_vars: @@ -122,14 +109,12 @@ def visit(self, node): @visitor.when(ProgramNode) def visit(self, node: ProgramNode): - self.types = node.dottypes - self.build_types(self.types) - tags = self.build_tags(node.dottypes) self.global_descriptor = GlobalDescriptor(node.dottypes, tags) - self.mips.allocate_vtable(self.global_descriptor.vTable.size(), self.vtable_reg) + self.mips.allocate_vtable( + self.global_descriptor.vTable.size(), self.vtable_reg) self.fill_vtable() @@ -201,39 +186,30 @@ def visit(self, node: LocalNode, index=0): @visitor.when(GetAttribNode) def visit(self, node: GetAttribNode): - self.mips.comment(f"GetAttribNode {node.dest} = {node.ojb}.{node.attrib} Type:{node.type}") + self.mips.comment( + f"GetAttribNode {node.dest} = {node.obj}.{node.attrib} Type:{node.type}") self.load_memory(reg.t0, node.obj) # get type info - type_descritptor :MemoryType = self.global_descriptor.Types[node.type] + type_descritptor: MemoryType = self.global_descriptor.Types[node.type] # get attr offset offset = type_descritptor.get_attr_index(node.attrib) # retrieve offset from memory - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, offset * self.data_size)) + self.mips.load_memory(reg.t1, self.mips.offset( + reg.t0, offset * self.data_size)) self.store_memory(reg.t1, node.dest) @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): - self.mips.comment("SetAttribNode") - self.load_memory(reg.t0, node.obj) - type_data = self.types_offsets[node.type] - offset = type_data.attr_offsets[node.attrib] - if node.value in self.local_vars_offsets: - self.load_memory(reg.t1, node.value) - else: - try: - value = int(node.value) - high = value >> 16 - self.mips.li(reg.t2, high) - self.mips.li(reg.t3, value) - self.mips.sll(reg.t4, reg.t2, 16) - self.mips.or_(reg.t1, reg.t2, reg.t4) - except ValueError: - self.mips.la(reg.t1, node.value) - self.mips.store_memory(reg.t1, self.mips.offset(reg.t0, offset)) + pass + # self.mips.comment( + # f"SetAttribNode {node.ojb}.{node.attrib} Type:{node.type} = {node.value}") + # # get type info + # type_descritptor: MemoryType = self.global_descriptor.Types[node.type] + # # get attr offset + # offset = type_descritptor.get_attr_index(node.attrib) @visitor.when(AssignNode) def visit(self, node: AssignNode): - print(node.dest, node.source) self.load_memory(reg.t0, node.source) self.store_memory(reg.t0, node.dest) @@ -330,21 +306,21 @@ def visit(self, node: AllocateNode): # | Attr2 | # .......... # .......... - # - # s1 start addr of the class + # + # s1 start addr of the class # self.mips.comment(f"Allocate space for {node.type}") - type_descritptor :MemoryType = self.global_descriptor.Types[node.type] + type_descritptor: MemoryType = self.global_descriptor.Types[node.type] length = type_descritptor.size() length *= self.data_size - #sbrk call + # sbrk call self.mips.li(reg.a0, length) self.mips.sbrk() self.mips.move(reg.s1, reg.v0) - #pass object reference to node.dest + # pass object reference to node.dest self.store_memory(reg.s1, node.dest) # Store Class ID @@ -353,20 +329,25 @@ def visit(self, node: AllocateNode): # Store Class size self.mips.li(reg.s0, length) - self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, self.data_size)) + self.mips.store_memory( + reg.s0, self.mips.offset(reg.s1, self.data_size)) # Store Class Name Ptr self.mips.la(reg.s0, type_descritptor.ptr_name) - self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) + self.mips.store_memory( + reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) # Store Class Vtable Ptr - self.mips.load_memory(reg.s0, self.mips.offset(self.vtable_reg, type_descritptor.vtable * self.data_size)) # first function on vtable - self.mips.store_memory( reg.s0, self.mips.offset(reg.s1, 3 * self.data_size)) + self.mips.load_memory(reg.s0, self.mips.offset( + self.vtable_reg, type_descritptor.vtable * self.data_size)) # first function on vtable + self.mips.store_memory( + reg.s0, self.mips.offset(reg.s1, 3 * self.data_size)) # Reserve Attrs Space - for number,_ in enumerate(type_descritptor.attrs): + for number, _ in enumerate(type_descritptor.attrs): _offset = 4 + number - self.mips.store_memory(reg.zero, self.mips.offset(reg.s1, _offset * self.data_size)) + self.mips.store_memory(reg.zero, self.mips.offset( + reg.s1, _offset * self.data_size)) @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): @@ -374,7 +355,7 @@ def visit(self, node: TypeOfNode): # Cargar la direccion de memoria self.load_memory(reg.s0, node.obj) # El offset 3 para ptr al name - self.mips.load_memory(reg.s1, self.mips.offset(reg.s0,3)) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, 3)) self.store_memory(reg.s1, node.dest) @visitor.when(LabelNode) @@ -404,11 +385,13 @@ def visit(self, node: DynamicCallNode): self.mips.comment(f"DynamicCallNode {node.type} {node.method}") type_descritptor = self.global_descriptor.Types[node.type] - offset = type_descritptor.get_method_index(node.method) * self.data_size + offset = type_descritptor.get_method_index( + node.method) * self.data_size self.load_memory(reg.s0, node.obj) # vtable ptr in position 4 (0 .. 3) - self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) + self.mips.load_memory( + reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) # retrieve function location self.mips.load_memory(reg.s2, self.mips.offset(reg.s1, offset)) @@ -428,10 +411,10 @@ def visit(self, node: ErrorNode): self.mips.li(reg.a0, 1) self.mips.syscall(17) - @visitor.when(BoxNode) - def visit(self, node: BoxNode): - self.mips.li(reg.s0, node.value) - self.store_memory(reg.s0, node.dest) + # @visitor.when(BoxNode) + # def visit(self, node: BoxNode): + # self.mips.li(reg.s0, node.value) + # self.store_memory(reg.s0, node.dest) @visitor.when(AbortNode) def visit(self, node: AbortNode): From 5c3175ed01e48a4e71d9c224d24f4f82c6ca639c Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Tue, 15 Dec 2020 14:49:59 -0500 Subject: [PATCH 120/191] fix inheritance problem --- src/engine/codegen/cil.py | 2 +- src/engine/codegen/to_cil.py | 4 +- src/engine/cp/semantic.py | 9 +- src/engine/visitors/checker.py | 225 ++++++++++++++++++++------------- 4 files changed, 148 insertions(+), 92 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index d283d2fa..79059341 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -75,7 +75,7 @@ def register_data(self, value): def sort_case_list(self, case_expressions): return sorted(case_expressions, reverse=True, - key=lambda x: self.context.inheritance_deep(x.type)) + key=lambda x: self.context.inheritance_deep(x.type.lex)) ################################### diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 2644fadd..803c7f12 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -30,7 +30,7 @@ def sort_class_declar(self, program: cool.ProgramNode): for declaration in program.declarations if isinstance(declaration, cool.ClassDeclarationNode) ), - reverse=True, + # reverse=True, key=lambda cd: self.context.inheritance_deep(cd.id.lex), ) @@ -45,7 +45,7 @@ def save_attr_initializations(self, node: cool.ProgramNode, scope): self.attr_declarations = dict() self.attr_declarations['Object'] = [] self.attr_declarations['IO'] = [] - + for declaration in node.declarations: self.attr_declarations[declaration.id.lex] = [] if declaration.parent and not declaration.parent.lex in ['IO', 'Int', 'String', 'Bool', 'Object']: diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index 11533c90..e0034bca 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -235,7 +235,9 @@ def get_type(self, name: str): raise SemanticError(f'Type "{name}" is not defined.') def inheritance_deep(self, type_name: str) -> int: - if type_name not in self.inheritance: + if type_name is None: + return -1 + if type_name in ('IO', 'Int', 'String', 'Bool', 'Object'): return 0 return 1 + self.inheritance_deep(self.inheritance[type_name]) @@ -345,11 +347,12 @@ def define_variable(self, vname, vtype, let=False): for i in range(len(self.locals)): if self.locals[i].name == vname: if not let: - raise SemanticError(f'Variable {vname} already exists in the current context') + raise SemanticError( + f'Variable {vname} already exists in the current context') else: self.locals[i] = info break - else: + else: self.locals.append(info) return info diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 00dc8c56..4e0a4946 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -6,6 +6,7 @@ from engine.parser import IntegerNode, IdNode, StringNode, BoolNode from engine.semantic_errors import NON_TYPE_ARGUMENTS, ERROR_ON_LN_COL, WRONG_SIGNATURE, SELF_IS_READONLY, LOCAL_ALREADY_DEFINED, INCOMPATIBLE_TYPES, VARIABLE_NOT_DEFINED, INVALID_OPERATION, CYCLIC_HERITAGE + class Checker: def __init__(self, context, errors=[]): self.context = context @@ -13,7 +14,7 @@ def __init__(self, context, errors=[]): self.current_method = None self.errors = errors - #Tipos Built-in + # Tipos Built-in self.object_type = self.context.get_type('Object') self.io_type = self.context.get_type('IO') self.int_type = self.context.get_type('Int') @@ -23,25 +24,31 @@ def __init__(self, context, errors=[]): @visitor.on('node') def visit(self, node, scope): pass - + @visitor.when(ProgramNode) - def visit(self, node, scope = None): + def visit(self, node, scope=None): scope = Scope() for d in node.declarations: - self.visit(d,scope.create_child()) - return scope - + self.visit(d, scope.create_child()) + return scope, self.context + @visitor.when(ClassDeclarationNode) def visit(self, node, scope): self.current_type = self.context.get_type(node.id.lex) attrs = [] + self.current_type.parent = ( + self.current_type.parent + if self.current_type.parent + else self.context.get_type('Object')) parent = self.current_type.parent - + self.context.inheritance[self.current_type.name] = parent.name + while parent: - + if parent == self.current_type: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + CYCLIC_HERITAGE % (parent.name)) + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "SemanticError: " + CYCLIC_HERITAGE % (parent.name)) self.current_type.parent = self.object_type break attrs += parent.attributes @@ -49,8 +56,10 @@ def visit(self, node, scope): for a in self.current_type.attributes + attrs: if a.name == 'self': - line, column = [ (attrib.line, attrib.column) for attrib in node.features if type(attrib) is AttrDeclarationNode and attrib.id.lex == 'self'][0] - self.errors.append(ERROR_ON_LN_COL % (line, column) + "SemanticError: " + "Incorrect use of self in attribute declaration") + line, column = [(attrib.line, attrib.column) for attrib in node.features if type( + attrib) is AttrDeclarationNode and attrib.id.lex == 'self'][0] + self.errors.append(ERROR_ON_LN_COL % ( + line, column) + "SemanticError: " + "Incorrect use of self in attribute declaration") scope.define_variable(a.name, a.type) @@ -61,14 +70,18 @@ def visit(self, node, scope): def visit(self, node, scope): expr = node.expression if expr: - self.visit(expr, scope.create_child()) + scope_child: Scope = scope.create_child() + scope_child.define_variable('self', self.current_type) + self.visit(expr, scope_child) expr_type = expr.static_type attr = self.current_type.get_attribute(node.id.lex) node_type = attr.type - node_type = self.current_type if isinstance(node_type, SelfType) else node_type + node_type = self.current_type if isinstance( + node_type, SelfType) else node_type if not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) @visitor.when(FuncDeclarationNode) def visit(self, node, scope): @@ -83,28 +96,32 @@ def visit(self, node, scope): pass else: if parent_method.param_types != self.current_method.param_types or parent_method.return_type != self.current_method.return_type: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) - + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + + WRONG_SIGNATURE % (self.current_method.name, self.current_type.name, parent.name)) + scope.define_variable('self', self.current_type) - + for pname, ptype in zip(self.current_method.param_names, self.current_method.param_types): if pname == 'self': - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") - + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "SemanticError: " + "Wrong use of self as method parameter") + try: scope.define_variable(pname, ptype) except SemanticError: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") - - + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "SemanticError: " + f"Parameter {pname} can only be used once") + body = node.body self.visit(body, scope.create_child()) - + body_type = body.static_type - return_type = self.current_type if isinstance(self.current_method.return_type, SelfType) else self.current_method.return_type - + return_type = self.current_type if isinstance( + self.current_method.return_type, SelfType) else self.current_method.return_type + if not body_type.conforms_to(return_type): - self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + "TypeError: " + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) + self.errors.append(ERROR_ON_LN_COL % (body.line, body.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (body_type.name, return_type.name)) @visitor.when(IfThenElseNode) def visit(self, node, scope): @@ -113,7 +130,8 @@ def visit(self, node, scope): condition_type = condition.static_type if not condition_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) self.visit(node.if_body, scope.create_child()) self.visit(node.else_body, scope.create_child()) @@ -129,7 +147,8 @@ def visit(self, node, scope): condition_type = condition.static_type if not condition_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (condition.line, condition.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (condition_type.name, self.bool_type.name)) self.visit(node.body, scope.create_child()) @@ -148,13 +167,16 @@ def visit(self, node, scope): try: node_type = self.context.get_type(typex.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "TypeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + typex.line, typex.column) + "TypeError: " + ex.text) node_type = ErrorType() - - id_type = self.current_type if isinstance(node_type, SelfType) else node_type - + + id_type = self.current_type if isinstance( + node_type, SelfType) else node_type + if idx.lex == 'self': - self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "SemanticError: " + "'self' cannot be bound in a 'let' expression.") + self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + + "SemanticError: " + "'self' cannot be bound in a 'let' expression.") child = scope.create_child() @@ -162,12 +184,14 @@ def visit(self, node, scope): self.visit(expr, child) expr_type = expr.static_type if not expr_type.conforms_to(id_type): - self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) + self.errors.append(ERROR_ON_LN_COL % ( + expr.line, expr.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) try: scope.define_variable(idx.lex, id_type, True) except SemanticError as e: - self.errors.append(ERROR_ON_LN_COL % (idx.line, idx.column) + "SemanticError: " + e.text) + self.errors.append(ERROR_ON_LN_COL % ( + idx.line, idx.column) + "SemanticError: " + e.text) self.visit(node.in_body, scope.create_child()) @@ -178,22 +202,25 @@ def visit(self, node, scope): self.visit(node.expression, scope.create_child()) node.static_type = None - + case_types = [] for idx, typex, expr in node.branches: try: node_type = self.context.get_type(typex.lex) if node_type in case_types: - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "SemanticError: " + f"Duplicate Branch {node_type} in case declaration") + self.errors.append(ERROR_ON_LN_COL % ( + typex.line, typex.column) + "SemanticError: " + f"Duplicate Branch {node_type} in case declaration") else: case_types.append(node_type) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "TypeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + typex.line, typex.column) + "TypeError: " + ex.text) node_type = ErrorType() else: if isinstance(node_type, SelfType): - self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + "SemanticError: " + f'Type "{node_type.name}" can not be used as case type') + self.errors.append(ERROR_ON_LN_COL % ( + typex.line, typex.column) + "SemanticError: " + f'Type "{node_type.name}" can not be used as case type') node_type = ErrorType() id_type = node_type @@ -203,7 +230,8 @@ def visit(self, node, scope): self.visit(expr, child_scope) expr_type = expr.static_type - node.static_type = node.static_type.type_union(expr_type) if node.static_type else expr_type + node.static_type = node.static_type.type_union( + expr_type) if node.static_type else expr_type @visitor.when(AssignNode) def visit(self, node, scope): @@ -212,18 +240,21 @@ def visit(self, node, scope): if scope.is_defined(node.id.lex): var = scope.find_variable(node.id.lex) - node_type = var.type - + node_type = var.type + if var.name == 'self': - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + SELF_IS_READONLY) + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "SemanticError: " + SELF_IS_READONLY) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + + VARIABLE_NOT_DEFINED % (node.id.lex, self.current_method.name)) self.visit(expression, scope.create_child()) expr_type = expression.static_type if not expr_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, node_type.name)) node.static_type = expr_type @@ -234,7 +265,8 @@ def visit(self, node, scope): expr_type = expression.static_type if not expr_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.bool_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.bool_type.name)) node.static_type = self.bool_type @@ -247,7 +279,8 @@ def visit(self, node, scope): right_type = node.right.static_type if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) node.static_type = self.bool_type @@ -258,9 +291,10 @@ def visit(self, node, scope): self.visit(node.right, scope.create_child()) right_type = node.right.static_type - + if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (right_type.name, self.int_type.name)) node.static_type = self.bool_type @@ -273,25 +307,29 @@ def visit(self, node, scope): right_type = node.right.static_type if left_type.conforms_to(self.int_type) ^ right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) elif left_type.conforms_to(self.string_type) ^ right_type.conforms_to(self.string_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) elif left_type.conforms_to(self.bool_type) ^ right_type.conforms_to(self.bool_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) node.static_type = self.bool_type - + @visitor.when(ArithmeticNode) def visit(self, node, scope): self.visit(node.left, scope.create_child()) left_type = node.left.static_type - + self.visit(node.right, scope.create_child()) right_type = node.right.static_type - + if not left_type.conforms_to(self.int_type) or not right_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) - + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "TypeError: " + INVALID_OPERATION % (left_type.name, right_type.name)) + node.static_type = self.int_type @visitor.when(IsVoidNode) @@ -307,7 +345,8 @@ def visit(self, node, scope): expr_type = expression.static_type if not expr_type.conforms_to(self.int_type): - self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.int_type.name)) + self.errors.append(ERROR_ON_LN_COL % (expression.line, expression.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (expr_type.name, self.int_type.name)) node.static_type = self.int_type @@ -315,32 +354,37 @@ def visit(self, node, scope): def visit(self, node, scope): self.visit(node.obj, scope.create_child()) obj_type = node.obj.static_type - + try: if node.type: try: node_type = self.context.get_type(node.type.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "TypeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + node.type.line, node.type.column) + "TypeError: " + ex.text) node_type = ErrorType() return else: if isinstance(node_type, SelfType): - self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + "SemanticError: " + f'Type "{node_type}" cannot be used as type dispatch') + self.errors.append(ERROR_ON_LN_COL % (node.type.line, node.type.column) + + "SemanticError: " + f'Type "{node_type}" cannot be used as type dispatch') node_type = ErrorType() if not obj_type.conforms_to(node_type): - self.errors.append(ERROR_ON_LN_COL % (node.obj.line, node.obj.column) + "TypeError: "+ INCOMPATIBLE_TYPES % (obj_type.name, node_type.name)) - + self.errors.append(ERROR_ON_LN_COL % (node.obj.line, node.obj.column) + + "TypeError: " + INCOMPATIBLE_TYPES % (obj_type.name, node_type.name)) + obj_type = node_type - + obj_method = obj_type.get_method(node.id.lex) - - node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + + node_type = obj_type if isinstance( + obj_method.return_type, SelfType) else obj_method.return_type except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "AttributeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "AttributeError: " + ex.text) node_type = ErrorType() - obj_method = None + obj_method = None else: if obj_method and len(node.args) == len(obj_method.param_types): @@ -349,22 +393,26 @@ def visit(self, node, scope): arg_type = arg.static_type if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + self.errors.append(ERROR_ON_LN_COL % ( + arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') - + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') + node.static_type = node_type @visitor.when(MemberCallNode) def visit(self, node, scope): obj_type = self.current_type - + try: obj_method = obj_type.get_method(node.id.lex) - - node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type + + node_type = obj_type if isinstance( + obj_method.return_type, SelfType) else obj_method.return_type except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "AttributeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "AttributeError: " + ex.text) node_type = ErrorType() obj_method = None @@ -373,12 +421,14 @@ def visit(self, node, scope): for arg, param_type in zip(node.args, obj_method.param_types): self.visit(arg, scope.create_child()) arg_type = arg.static_type - + if not arg_type.conforms_to(param_type): - self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) + self.errors.append(ERROR_ON_LN_COL % ( + arg.line, arg.column) + "TypeError: " + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') - + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + + "SemanticError: " + f'Method "{node.id.lex}" can not be dispatched') + node.static_type = node_type @visitor.when(NewNode) @@ -386,9 +436,10 @@ def visit(self, node, scope): try: node_type = self.context.get_type(node.type.lex) except SemanticError as ex: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "TypeError: " + ex.text) + self.errors.append(ERROR_ON_LN_COL % ( + node.line, node.column) + "TypeError: " + ex.text) node_type = ErrorType() - + node.static_type = node_type @visitor.when(IntegerNode) @@ -403,13 +454,15 @@ def visit(self, node, scope): def visit(self, node, scope): if scope.is_defined(node.token.lex): var = scope.find_variable(node.token.lex) - node_type = var.type + node_type = var.type else: - self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name)) + + self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + "NameError: " + + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name if self.current_method else '')) node_type = ErrorType() - + node.static_type = node_type - + @visitor.when(BoolNode) def visit(self, node, scope): - node.static_type = self.bool_type \ No newline at end of file + node.static_type = self.bool_type From 3d4d8c9733fd3207e3ca1a4d287295a7f91bbcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 14:59:04 -0500 Subject: [PATCH 121/191] Fix load memory addressing --- src/engine/codegen/to_mips.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index e067afa8..d3a4a400 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -85,9 +85,10 @@ def get_label(self): return f"mip_label_{self.label_count}" def load_memory(self, dst, arg: str): + self.mips.comment(f"Load from {arg} to {dst}") if arg in self.arguments or arg in self.local_vars: offset = ( - self.arguments[arg] + 1 + self.arguments[arg] if arg in self.arguments else -self.local_vars[arg] ) * self.data_size @@ -423,7 +424,7 @@ def visit(self, node: DynamicCallNode): @visitor.when(ArgNode) def visit(self, node: ArgNode): - self.mips.comment("ArgNode") + self.mips.comment(f"ArgNode {node.name} to s0") self.load_memory(reg.s0, node.name) self.mips.push(reg.s0) From e9df30cfccb85d78700705ecc5eaddced8838f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 15:35:36 -0500 Subject: [PATCH 122/191] Change vtable initialization --- src/engine/codegen/to_mips.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 53c516a0..f3c79423 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -114,16 +114,15 @@ def visit(self, node: ProgramNode): self.global_descriptor = GlobalDescriptor(node.dottypes, tags) - self.mips.allocate_vtable( - self.global_descriptor.vTable.size(), self.vtable_reg) - - self.fill_vtable() - for data in node.dotdata: self.visit(data) self.data_segment.append(data.name) self.mips.label('main') + self.mips.allocate_vtable( + self.global_descriptor.vTable.size(), self.vtable_reg) + + self.fill_vtable() self.mips.jal('entry') self.mips.empty_line() self.mips.exit() @@ -386,7 +385,10 @@ def visit(self, node: StaticCallNode): @visitor.when(DynamicCallNode) def visit(self, node: DynamicCallNode): self.mips.comment(f"DynamicCallNode {node.type} {node.method}") - type_descritptor = self.global_descriptor.Types[node.type] + type_descritptor: MemoryType = self.global_descriptor.Types[node.type] + + # self.mips.move(reg.a0, reg.s7) + # self.mips.syscall(1) offset = type_descritptor.get_method_index( node.method) * self.data_size From 200f231af19a8319f0dad03db29a08cc16ac9b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 16:04:17 -0500 Subject: [PATCH 123/191] Fix missing function parameters --- src/engine/codegen/cil_ast.py | 6 ++++++ src/engine/codegen/to_mips.py | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index ec1a2ffa..2e6d91e3 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -57,6 +57,12 @@ class LocalNode(Node): def __init__(self, name): self.name = name + def __str__(self): + return self.name + + def __repr__(self): + return str(self) + class InstructionNode(Node): pass diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index f3c79423..4f84adf5 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -96,6 +96,7 @@ def store_memory(self, dst, arg: str): f"store_memory: The direction {arg} isn't an address") def store_registers(self): + self.mips.comment("Saving Registers") for reg in self.registers_to_save: self.mips.push(reg) @@ -142,15 +143,20 @@ def visit(self, node: FunctionNode): self.mips.push(reg.fp) self.mips.move(reg.fp, reg.sp) self.mips.empty_line() + self.arguments = dict() for idx, param in enumerate(node.params): self.visit(param, index=idx) self.mips.comment("Allocate memory for Local variables") + localvars_count = len(node.localvars) + self.mips.addi(reg.sp, reg.sp, - self.data_size * localvars_count) for idx, local in enumerate(node.localvars): self.visit(local, index=idx) + self.mips.empty_line() + self.store_registers() self.mips.empty_line() self.mips.comment("Generating body code") @@ -399,8 +405,11 @@ def visit(self, node: DynamicCallNode): # vtable ptr in position 4 (0 .. 3) self.mips.load_memory( reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) + + print(type_descritptor.get_method_index(node.method)) self.mips.addi(reg.s2, reg.s1, offset) self.mips.addu(reg.s3, reg.s2, reg.s7) + # retrieve function location self.mips.load_memory(reg.s4, self.mips.offset(reg.s3)) @@ -633,6 +642,7 @@ def visit(self, node): @visitor.when(PrintStrNode) def visit(self, node: PrintStrNode): + self.mips.comment(f"Print str {node.str_addr}") self.load_memory(reg.a0, node.str_addr) self.mips.print_str(node.str_addr) From 7153b785f3117ba0cd3ce860dc2aa5097a9f22b5 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Tue, 15 Dec 2020 16:11:30 -0500 Subject: [PATCH 124/191] returnnode and parameter passing --- src/engine/codegen/cil.py | 6 +++++- src/test.mips | 13 +++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index be8eeb64..192dfb25 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -198,8 +198,10 @@ def define_io_type(self): type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) - str_val = self.define_internal_local() + self_local = self.register_param(VariableInfo("self", None)) + str_val = self.register_param(VariableInfo('str_val', None)) self.register_instruction(PrintStrNode(str_val)) + self.register_instruction(ReturnNode(self_local)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_string') @@ -215,8 +217,10 @@ def define_io_type(self): type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) + self_local = self.register_param(VariableInfo("self", None)) int_val = self.register_param(VariableInfo('int_val', None)) self.register_instruction(PrintIntNode(int_val)) + self.register_instruction(ReturnNode(self_local)) self.current_method = self.current_function = None self.current_method = self.current_type.get_method('in_int') diff --git a/src/test.mips b/src/test.mips index 07e08c87..6435b9e5 100644 --- a/src/test.mips +++ b/src/test.mips @@ -60,7 +60,8 @@ data_1 = "\n" data_2 = "Invalid substring start" data_3 = "Invalid substring length" data_4 = "Invalid substring" -data_5 = "Hello, World.n" +data_5 = "Hello, World. +" .CODE function function_abort_at_Object { @@ -151,11 +152,13 @@ function function_substr_at_String { RETURN local_substr_at_String_internal_0 } function function_out_string_at_IO { - + PARAM self + PARAM str_val - LOCAL local_out_string_at_IO_internal_0 + - PRINTSTR local_out_string_at_IO_internal_0 + PRINTSTR str_val + RETURN self } function function_in_string_at_IO { @@ -166,11 +169,13 @@ function function_in_string_at_IO { RETURN local_in_string_at_IO_internal_0 } function function_out_int_at_IO { + PARAM self PARAM int_val PRINTINT int_val + RETURN self } function function_in_int_at_IO { From 91615dfff46ee38a9efa98de76e0e86ceb24e76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 16:43:27 -0500 Subject: [PATCH 125/191] First test passed !!!! --- src/engine/codegen/to_mips.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 4f84adf5..24628c16 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -152,11 +152,11 @@ def visit(self, node: FunctionNode): self.mips.comment("Allocate memory for Local variables") localvars_count = len(node.localvars) self.mips.addi(reg.sp, reg.sp, - self.data_size * localvars_count) + self.mips.empty_line() for idx, local in enumerate(node.localvars): self.visit(local, index=idx) self.mips.empty_line() - self.store_registers() self.mips.empty_line() self.mips.comment("Generating body code") @@ -164,10 +164,13 @@ def visit(self, node: FunctionNode): self.visit(instruction) self.mips.empty_line() + self.mips.comment("Restore registers") self.load_registers() + self.mips.empty_line() self.mips.comment("Clean stack variable space") - self.mips.addi(reg.sp, reg.sp, len(node.localvars) * self.data_size) + print(localvars_count, node.name) + self.mips.addi(reg.sp, reg.sp, localvars_count * self.data_size) self.arguments = None self.mips.comment("Return") self.mips.pop(reg.fp) @@ -184,7 +187,6 @@ def visit(self, node: ParamNode, index=0): @visitor.when(LocalNode) def visit(self, node: LocalNode, index=0): - self.mips.push(reg.zero) if node.name in self.local_vars: pass else: From ffae3f67323396344353f92f0dcb5e237bd3bd31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 16:48:25 -0500 Subject: [PATCH 126/191] Fix main --- src/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.py b/src/main.py index 0c84fe30..96e52196 100644 --- a/src/main.py +++ b/src/main.py @@ -72,11 +72,11 @@ cil = COOL_TO_CIL(checker.context) cil_ast = cil.visit(ast) -# emsamb = CIL_TO_MIPS() -# emsamb.visit(cil_ast) +emsamb = CIL_TO_MIPS() +emsamb.visit(cil_ast) -# f_ast = emsamb.mips.compile() -f_ast = CIL_FORMATTER().visit(cil_ast) +f_ast = emsamb.mips.compile() +#f_ast = CIL_FORMATTER().visit(cil_ast) string_formatted = str(f_ast) output_file.write(string_formatted) From 2c7cb89c65b10d70609f25e2c2538fedffd0d69a Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Tue, 15 Dec 2020 16:55:02 -0500 Subject: [PATCH 127/191] info about cil updated --- Informe/informe.pdf | Bin 120864 -> 148011 bytes Informe/informe.tex | 16 +++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Informe/informe.pdf b/Informe/informe.pdf index a79194961a1e66eed55cb025cefbb1b900b3ddaa..cd2ad3b8d3528910a2b484b94311e8036bbada41 100644 GIT binary patch delta 100118 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 z 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 OH8kc@Rdw}u;{pKA%AYa- delta 73072 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 Date: Tue, 15 Dec 2020 17:03:07 -0500 Subject: [PATCH 128/191] Fix new semantic errors --- src/engine/visitors/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/visitors/checker.py b/src/engine/visitors/checker.py index 4e0a4946..261a8300 100644 --- a/src/engine/visitors/checker.py +++ b/src/engine/visitors/checker.py @@ -30,7 +30,7 @@ def visit(self, node, scope=None): scope = Scope() for d in node.declarations: self.visit(d, scope.create_child()) - return scope, self.context + return scope @visitor.when(ClassDeclarationNode) def visit(self, node, scope): From 08ef387f6e7ecf08c6ec3da052f0bd323e5123e7 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Tue, 15 Dec 2020 17:17:26 -0500 Subject: [PATCH 129/191] fix errors ordering in type collector --- src/engine/visitors/collector.py | 1 - src/main.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/engine/visitors/collector.py b/src/engine/visitors/collector.py index 9fd1e43f..33fb333e 100644 --- a/src/engine/visitors/collector.py +++ b/src/engine/visitors/collector.py @@ -48,7 +48,6 @@ def visit(self, node): if declaration.parent != None and declaration.parent.lex in self.parents.keys() and self.ciclic_heritage(declaration.id.lex, declaration.parent.lex): self.errors.append(ERROR_ON_LN_COL % ( declaration.line, declaration.column) + "SemanticError: " + CYCLIC_HERITAGE % (declaration.id.lex)) - break @visitor.when(ClassDeclarationNode) def visit(self, node): diff --git a/src/main.py b/src/main.py index 96e52196..ab8e4234 100644 --- a/src/main.py +++ b/src/main.py @@ -42,7 +42,7 @@ collect.visit(ast) if len(collect_errors): - for e in collect_errors: + for e in collect_errors[::-1]: print(e) exit(1) From 7982f7b1904430a64190232e6485e5922d599575 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Tue, 15 Dec 2020 17:22:05 -0500 Subject: [PATCH 130/191] void and boxing node --- src/engine/codegen/cil_ast.py | 14 +- src/engine/codegen/cil_format.py | 6 +- src/engine/codegen/to_cil.py | 18 +- src/engine/codegen/to_mips.py | 19 +- src/test.cl | 6 +- src/test.mips | 1594 ++++++++++++++++++++++++++---- 6 files changed, 1415 insertions(+), 242 deletions(-) diff --git a/src/engine/codegen/cil_ast.py b/src/engine/codegen/cil_ast.py index 2e6d91e3..fbd12051 100644 --- a/src/engine/codegen/cil_ast.py +++ b/src/engine/codegen/cil_ast.py @@ -26,14 +26,15 @@ def __str__(self): for attr in self.attributes: string_base += str(attr) + "\n" - + string_base += "Methods \n" for methos in self.methods: string_base += str(methos) + "\n" - + return string_base + class DataNode(Node): def __init__(self, vname, value): self.name = vname @@ -287,10 +288,7 @@ class ReadStrNode(InstructionNode): def __init__(self, dest): self.dest = dest -################# nodes que me tengo que definir ############## -# class ConformNode(InstructionNode): -# def __init__(self, dest, obj, typex): -# self.dest = dest -# self.obj = obj -# self.type = typex +class VoidNode(InstructionNode): + def __init__(self, dest): + self.dest = dest diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 3ef91a56..91e0efcd 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -159,8 +159,6 @@ def visit(self, node: IsVoidNode): def visit(self, node: LessEqNode): return f'{node.dest} = {node.left} <= {node.right}' -###################### nodes to throw ####################### - @visitor.when(EqualNode) def visit(self, node: EqualNode): return f'{node.dest} = {node.left} == {node.right}' @@ -177,6 +175,10 @@ def visit(self, node: BoxNode): def visit(self, node: AbortNode): return f'ABORT' + @visitor.when(VoidNode) + def visit(self, node: VoidNode): + return f'VOID' + @visitor.when(ConformsNode) def visit(self, node: ConformsNode): return f'{node.dest} = COMFORM {node.expr} {node.type}' diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 803c7f12..644ce39f 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -39,7 +39,7 @@ def init_class_attr(self, scope: Scope, class_id, self_inst): for attr in attr_nodes: attr_scope = scope.create_child() attr_scope.define_variable('self', self_inst) - self.visit(attr, attr_scope) + self.visit(attr, attr_scope, typex=class_id) def save_attr_initializations(self, node: cool.ProgramNode, scope): self.attr_declarations = dict() @@ -66,7 +66,7 @@ def create_constructor(self, attr_declarations: List[cool.AttrDeclarationNode], scope = Scope() scope.define_variable('self', instance) for attr in attr_declarations: - self.visit(attr, scope) + self.visit(attr, scope, typex=self.current_type.name) self.register_instruction(ReturnNode(instance)) @@ -145,12 +145,18 @@ def visit(self, node: cool.FuncDeclarationNode, scope: Scope): self.current_method = None @visitor.when(cool.AttrDeclarationNode) - def visit(self, node: cool.AttrDeclarationNode, scope): - # typex = self.context.get_type(type_name) - result = self.visit(node.expression, scope) if node.expression else 0 + def visit(self, node: cool.AttrDeclarationNode, scope: Scope, typex): + result = None + if node.expression: + result = self.visit(node.expression, scope) + elif node.type == 'String': + result = self.register_data("").name + else: + result = self.define_internal_local() + self.register_instruction(VoidNode(result)) self_inst = scope.find_variable('self').name self.register_instruction( - SetAttribNode(self_inst, node.id.lex, result, self.current_type.name)) + SetAttribNode(self_inst, node.id.lex, result, typex)) @visitor.when(cool.BlockNode) def visit(self, node: cool.BlockNode, scope): diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 24628c16..f16b3229 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -169,7 +169,6 @@ def visit(self, node: FunctionNode): self.mips.empty_line() self.mips.comment("Clean stack variable space") - print(localvars_count, node.name) self.mips.addi(reg.sp, reg.sp, localvars_count * self.data_size) self.arguments = None self.mips.comment("Return") @@ -346,8 +345,6 @@ def visit(self, node: AllocateNode): reg.s0, self.mips.offset(reg.s1, 2 * self.data_size)) # Store Class Vtable Ptr - print( - f"First methohd of class {node.type} {type_descritptor.vtable * self.data_size}") self.mips.li(reg.s0, type_descritptor.vtable * self.data_size) # first function on vtable self.mips.store_memory( @@ -408,10 +405,10 @@ def visit(self, node: DynamicCallNode): self.mips.load_memory( reg.s1, self.mips.offset(reg.s0, 3 * self.data_size)) - print(type_descritptor.get_method_index(node.method)) + # print(type_descritptor.get_method_index(node.method)) self.mips.addi(reg.s2, reg.s1, offset) self.mips.addu(reg.s3, reg.s2, reg.s7) - + # retrieve function location self.mips.load_memory(reg.s4, self.mips.offset(reg.s3)) @@ -431,10 +428,10 @@ def visit(self, node: ErrorNode): self.mips.li(reg.a0, 1) self.mips.syscall(17) - # @visitor.when(BoxNode) - # def visit(self, node: BoxNode): - # self.mips.li(reg.s0, node.value) - # self.store_memory(reg.s0, node.dest) + @visitor.when(BoxNode) + def visit(self, node: BoxNode): + self.mips.li(reg.s0, node.value) + self.store_memory(reg.s0, node.dest) @visitor.when(AbortNode) def visit(self, node: AbortNode): @@ -666,3 +663,7 @@ def visit(self, node: EmptyArgs): def visit(self, node: ReturnNode): self.mips.comment("ReturnNode") self.load_memory(reg.v0, node.value) + + @visitor.when(VoidNode) + def visit(self, node: VoidNode): + self.store_memory(reg.zero, node.dest) diff --git a/src/test.cl b/src/test.cl index 0c818f90..0dd94a40 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,5 +1,9 @@ class Main inherits IO { + a : Int; main(): IO { - out_string("Hello, World.\n") + { + a <- 34; + out_string("Hello, World.\n"); + } }; }; diff --git a/src/test.mips b/src/test.mips index 6435b9e5..602f67a7 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,218 +1,1380 @@ -.TYPES -type Object { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type String { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method length: function_length_at_String - method concat: function_concat_at_String - method substr: function_substr_at_String -} -type IO { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO -} -type Int { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type Bool { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type Main { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method main: function_main_at_Main -} - -.DATA -data_0 = "Abort called from class " -data_1 = "\n" -data_2 = "Invalid substring start" -data_3 = "Invalid substring length" -data_4 = "Invalid substring" -data_5 = "Hello, World. +.data +classname_Object: +.asciiz "Object" +classname_String: +.asciiz "String" +classname_IO: +.asciiz "IO" +classname_Int: +.asciiz "Int" +classname_Bool: +.asciiz "Bool" +classname_Main: +.asciiz "Main" +data_0: +.asciiz "Abort called from class " +data_1: +.asciiz "\n" +data_2: +.asciiz "Invalid substring start" +data_3: +.asciiz "Invalid substring length" +data_4: +.asciiz "Invalid substring" +data_5: +.asciiz "Hello, World. " +.text +main: +# Allocate Vtable +li $a0, 120 +li $v0, 9 +syscall +move $s7, $v0 +# Build VTable +la $s0, function_abort_at_Object +sw $s0, 0($s7) +la $s0, function_type_name_at_Object +sw $s0, 4($s7) +la $s0, function_copy_at_Object +sw $s0, 8($s7) +la $s0, function_abort_at_Object +sw $s0, 12($s7) +la $s0, function_type_name_at_Object +sw $s0, 16($s7) +la $s0, function_copy_at_Object +sw $s0, 20($s7) +la $s0, function_length_at_String +sw $s0, 24($s7) +la $s0, function_concat_at_String +sw $s0, 28($s7) +la $s0, function_substr_at_String +sw $s0, 32($s7) +la $s0, function_abort_at_Object +sw $s0, 36($s7) +la $s0, function_type_name_at_Object +sw $s0, 40($s7) +la $s0, function_copy_at_Object +sw $s0, 44($s7) +la $s0, function_out_string_at_IO +sw $s0, 48($s7) +la $s0, function_out_int_at_IO +sw $s0, 52($s7) +la $s0, function_in_string_at_IO +sw $s0, 56($s7) +la $s0, function_in_int_at_IO +sw $s0, 60($s7) +la $s0, function_abort_at_Object +sw $s0, 64($s7) +la $s0, function_type_name_at_Object +sw $s0, 68($s7) +la $s0, function_copy_at_Object +sw $s0, 72($s7) +la $s0, function_abort_at_Object +sw $s0, 76($s7) +la $s0, function_type_name_at_Object +sw $s0, 80($s7) +la $s0, function_copy_at_Object +sw $s0, 84($s7) +la $s0, function_abort_at_Object +sw $s0, 88($s7) +la $s0, function_type_name_at_Object +sw $s0, 92($s7) +la $s0, function_copy_at_Object +sw $s0, 96($s7) +la $s0, function_out_string_at_IO +sw $s0, 100($s7) +la $s0, function_out_int_at_IO +sw $s0, 104($s7) +la $s0, function_in_string_at_IO +sw $s0, 108($s7) +la $s0, function_in_int_at_IO +sw $s0, 112($s7) +la $s0, function_main_at_Main +sw $s0, 116($s7) +jal entry -.CODE -function function_abort_at_Object { - PARAM self - - LOCAL local_abort_at_Object_internal_0 - LOCAL local_abort_at_Object_internal_1 - LOCAL local_abort_at_Object_internal_2 - - local_abort_at_Object_internal_0 = TYPENAME self - local_abort_at_Object_internal_1 = CONCAT data_0 local_abort_at_Object_internal_0 - local_abort_at_Object_internal_2 = CONCAT local_abort_at_Object_internal_1 data_1 - PRINTSTR local_abort_at_Object_internal_2 - ABORT -} -function function_copy_at_Object { - PARAM self - - LOCAL local_copy_at_Object_internal_0 - - local_copy_at_Object_internal_0 = COPY self - RETURN local_copy_at_Object_internal_0 -} -function function_type_name_at_Object { - PARAM self - - LOCAL local_type_name_at_Object_internal_0 - LOCAL local_type_name_at_Object_internal_1 - - local_type_name_at_Object_internal_1 = TYPEOF self - local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 - RETURN local_type_name_at_Object_internal_0 -} -function function_length_at_String { - PARAM self - - LOCAL local_length_at_String_internal_0 - - local_length_at_String_internal_0 = LENGTH self - RETURN local_length_at_String_internal_0 -} -function function_concat_at_String { - PARAM self - PARAM string - - LOCAL local_concat_at_String_internal_0 - - local_concat_at_String_internal_0 = CONCAT self string - RETURN local_concat_at_String_internal_0 -} -function function_substr_at_String { - PARAM self - PARAM start - PARAM length - - LOCAL local_substr_at_String_internal_0 - LOCAL local_substr_at_String_internal_1 - LOCAL local_substr_at_String_internal_2 - LOCAL local_substr_at_String_internal_3 - LOCAL local_substr_at_String_internal_4 - LOCAL local_substr_at_String_internal_5 - LOCAL local_substr_at_String_internal_6 - LOCAL local_substr_at_String_internal_7 - LOCAL local_substr_at_String_internal_8 - - local_substr_at_String_internal_3 = 0 - local_substr_at_String_internal_2 = LENGTH self - local_substr_at_String_internal_5 = local_substr_at_String_internal_3 <= start - IF local_substr_at_String_internal_5 GOTO error1 - local_substr_at_String_internal_8 = CONCAT data_2 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error1 - local_substr_at_String_internal_6 = local_substr_at_String_internal_3 <= length - IF local_substr_at_String_internal_6 GOTO error2 - local_substr_at_String_internal_8 = CONCAT data_3 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error2 - local_substr_at_String_internal_4 = start + length - local_substr_at_String_internal_7 = local_substr_at_String_internal_4 <= local_substr_at_String_internal_2 - IF local_substr_at_String_internal_7 GOTO error3 - local_substr_at_String_internal_8 = CONCAT data_4 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error3 - local_substr_at_String_internal_0 = SUBSTRING self start length - RETURN local_substr_at_String_internal_0 -} -function function_out_string_at_IO { - PARAM self - PARAM str_val - - - - PRINTSTR str_val - RETURN self -} -function function_in_string_at_IO { - - - LOCAL local_in_string_at_IO_internal_0 - - local_in_string_at_IO_internal_0 = READSTR - RETURN local_in_string_at_IO_internal_0 -} -function function_out_int_at_IO { - PARAM self - PARAM int_val - - - - PRINTINT int_val - RETURN self -} -function function_in_int_at_IO { - - - LOCAL local_in_int_at_IO_internal_0 - - local_in_int_at_IO_internal_0 = READINT - RETURN local_in_int_at_IO_internal_0 -} -function ctor_Main { - PARAM self - - - - RETURN self -} -function entry { - - - LOCAL local__internal_0 - LOCAL local__internal_1 - - local__internal_0 = ALLOCATE Main - ARG local__internal_0 - local__internal_1 = CALL function_main_at_Main - CLEAR 1 ARGS -} -function function_main_at_Main { - PARAM self - - LOCAL local_main_at_Main_internal_0 - LOCAL local_main_at_Main_internal_1 - - local_main_at_Main_internal_1 = LOAD data_5 - ARG local_main_at_Main_internal_1 - ARG self - local_main_at_Main_internal_0 = VCALL Main out_string - CLEAR 2 ARGS - RETURN local_main_at_Main_internal_0 -} \ No newline at end of file +li $v0, 10 +syscall +function_abort_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -12 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# TypeNameNode +# Load from self to $t0 +lw $t0, 4($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) +# Load from data_0 to $s0 +la $s0, data_0 +# Load from local_abort_at_Object_internal_0 to $s1 +lw $s1, 4($fp) +move $t0, $s0 +li $t1, 0 +mips_label_1: +lb $t3, 0($t0) +beqz $t3, mips_label_2 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_1 +mips_label_2: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_3: +lb $t3, 0($t0) +beqz $t3, mips_label_4 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_3 +mips_label_4: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_5: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_6 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_5 +mips_label_6: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_7: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_8 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_7 +mips_label_8: +move $v0, $t1 +sw $s3, 8($fp) +# Load from local_abort_at_Object_internal_1 to $s0 +lw $s0, 8($fp) +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_9: +lb $t3, 0($t0) +beqz $t3, mips_label_10 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_9 +mips_label_10: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_11: +lb $t3, 0($t0) +beqz $t3, mips_label_12 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_11 +mips_label_12: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_13: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_14 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_13 +mips_label_14: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_15: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_16 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_15 +mips_label_16: +move $v0, $t1 +sw $s3, 12($fp) +# Print str local_abort_at_Object_internal_2 +# Load from local_abort_at_Object_internal_2 to $a0 +lw $a0, 12($fp) +li $v0, 4 +syscall +li $v0, 10 +syscall + + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 12 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_copy_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +la $s1, -4($fp) +li $s3, 0 +move $t0, $s0 +move $t1, $s1 +move $t3, $s3 +mips_label_17: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 2 +addi $t1, $t1, 2 +addi $t3, $t3, -1 +beqz $t3, mips_label_18 +j mips_label_17 +mips_label_18: +# ReturnNode +# Load from local_copy_at_Object_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_type_name_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# TypeOfNode of self +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 3($s0) +sw $s1, 8($fp) +# TypeNameNode +# Load from local_type_name_at_Object_internal_1 to $t0 +lw $t0, 8($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) +# ReturnNode +# Load from local_type_name_at_Object_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_length_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# LengthNode +# Load from self to $s1 +lw $s1, 4($fp) +move $t0, $s1 +li $t1, 0 +mips_label_19: +lb $t3, 0($t0) +beqz $t3, mips_label_20 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_19 +mips_label_20: +move $s0, $t1 +sw $s0, 4($fp) +# ReturnNode +# Load from local_length_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_concat_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from self to $s0 +lw $s0, 4($fp) +# Load from string to $s1 +lw $s1, 8($fp) +move $t0, $s0 +li $t1, 0 +mips_label_21: +lb $t3, 0($t0) +beqz $t3, mips_label_22 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_21 +mips_label_22: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_23: +lb $t3, 0($t0) +beqz $t3, mips_label_24 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_23 +mips_label_24: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_25: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_26 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_25 +mips_label_26: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_27: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_28 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_27 +mips_label_28: +move $v0, $t1 +sw $s3, 4($fp) +# ReturnNode +# Load from local_concat_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_substr_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -36 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 16($fp) +# LengthNode +# Load from self to $s1 +lw $s1, 4($fp) +move $t0, $s1 +li $t1, 0 +mips_label_29: +lb $t3, 0($t0) +beqz $t3, mips_label_30 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_29 +mips_label_30: +move $s0, $t1 +sw $s0, 12($fp) +# Load from local_substr_at_String_internal_3 to $t0 +lw $t0, 16($fp) +# Load from start to $t1 +lw $t1, 8($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 24($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_5 to $t0 +lw $t0, 24($fp) +li $t1, 0 +bne $t0, $t1, error1 +# Load from data_2 to $s0 +la $s0, data_2 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_31: +lb $t3, 0($t0) +beqz $t3, mips_label_32 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_31 +mips_label_32: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_33: +lb $t3, 0($t0) +beqz $t3, mips_label_34 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_33 +mips_label_34: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_35: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_36 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_35 +mips_label_36: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_37: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_38 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_37 +mips_label_38: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error1: +# Load from local_substr_at_String_internal_3 to $t0 +lw $t0, 16($fp) +# Load from length to $t1 +lw $t1, 12($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 28($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_6 to $t0 +lw $t0, 28($fp) +li $t1, 0 +bne $t0, $t1, error2 +# Load from data_3 to $s0 +la $s0, data_3 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_39: +lb $t3, 0($t0) +beqz $t3, mips_label_40 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_39 +mips_label_40: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_41: +lb $t3, 0($t0) +beqz $t3, mips_label_42 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_41 +mips_label_42: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_43: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_44 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_43 +mips_label_44: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_45: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_46 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_45 +mips_label_46: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error2: +# Load from start to $t0 +lw $t0, 8($fp) +# Load from length to $t1 +lw $t1, 12($fp) +add $t2, $t0, $t1 +sw $t2, 20($fp) +# Load from local_substr_at_String_internal_4 to $t0 +lw $t0, 20($fp) +# Load from local_substr_at_String_internal_2 to $t1 +lw $t1, 12($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 32($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, error3 +# Load from data_4 to $s0 +la $s0, data_4 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_47: +lb $t3, 0($t0) +beqz $t3, mips_label_48 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_47 +mips_label_48: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_49: +lb $t3, 0($t0) +beqz $t3, mips_label_50 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_49 +mips_label_50: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_51: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_52 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_51 +mips_label_52: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_53: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_54 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_53 +mips_label_54: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error3: +# Load from self to $s0 +lw $s0, 4($fp) +# Load from length to $s1 +lw $s1, 12($fp) +# Load from start to $s3 +lw $s3, 8($fp) +add $s0, $s0, $s3 +move $a0, $s1 +li $v0, 9 +syscall +move $t0, $s0 +move $t1, $v0 +move $t3, $s1 +mips_label_55: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 1 +addi $t1, $t1, 1 +addi $t3, $t3, -1 +beqz $t3, mips_label_56 +j mips_label_55 +mips_label_56: +move $t2, $zero +sb $t2, 0($t1) +sw $v0, 4($fp) +# ReturnNode +# Load from local_substr_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 36 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_out_string_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Print str str_val +# Load from str_val to $a0 +lw $a0, 8($fp) +li $v0, 4 +syscall +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_in_string_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $a0, 1024 +li $v0, 9 +syscall +move $a0, $v0 +sw $v0, 4($fp) +li $a1, 1024 +li $v0, 8 +syscall +# ReturnNode +# Load from local_in_string_at_IO_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_out_int_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from int_val to $a0 +lw $a0, 8($fp) +li $v0, 1 +syscall +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_in_int_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $v0, 5 +syscall +sw $v0, 4($fp) +# ReturnNode +# Load from local_in_int_at_IO_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +sw $zero, 4($fp) +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +entry: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -12 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Allocate space for Main +li $a0, 20 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 4($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 20 +sw $s0, 4($s1) +la $s0, classname_Main +sw $s0, 8($s1) +li $s0, 88 +sw $s0, 12($s1) +sw $zero, 16($s1) +sw $zero, 12($fp) +# ArgNode local__internal_0 to s0 +# Load from local__internal_0 to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal function_main_at_Main +sw $v0, 8($fp) +addi $sp, $sp, 4 + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 12 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -16 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 34 +sw $s0, 8($fp) +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 16($fp) +# ArgNode local_main_at_Main_internal_3 to s0 +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 12($fp) +addi $sp, $sp, 8 +# Load from local_main_at_Main_internal_2 to $t0 +lw $t0, 12($fp) +sw $t0, 4($fp) +# ReturnNode +# Load from local_main_at_Main_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 16 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra \ No newline at end of file From 63f2698aa4540cdfc08bb81582ad230419f71cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Tue, 15 Dec 2020 17:44:45 -0500 Subject: [PATCH 131/191] Define Setattribute node --- src/engine/codegen/to_mips.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index f16b3229..874a8e81 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -207,13 +207,30 @@ def visit(self, node: GetAttribNode): @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): - pass - # self.mips.comment( - # f"SetAttribNode {node.ojb}.{node.attrib} Type:{node.type} = {node.value}") - # # get type info - # type_descritptor: MemoryType = self.global_descriptor.Types[node.type] - # # get attr offset - # offset = type_descritptor.get_attr_index(node.attrib) + self.mips.comment( + f"SetAttribNode {node.ojb}.{node.attrib} Type:{node.type} = {node.value}") + # get type info + type_descritptor: MemoryType = self.global_descriptor.Types[node.type] + # get attr offset + offset = type_descritptor.get_attr_index(node.attrib) + # get object reference into s0 + self.load_memory(reg.s0, node.obj) + + if node.value in self.local_vars or node.value in self.arguments: + self.mips.comment(f"SET local var {node.value}") + self.load_memory(reg.s1, node.value) + else: + try: + value = int(node.value) + self.mips.li(reg.s1,value) + except ValueError: + if node.value in self.data_segment: + self.mips.comment(f"SET data {node.value}") + self.mips.la(reg.s1, node.value) + else: + raise Exception(f"Setattr: label {node.value} not found") + + self.mips.store_memory(reg.s1, self.mips.offset(reg.s0, offset * self.data_size)) @visitor.when(AssignNode) def visit(self, node: AssignNode): From b453d8b64c26b8b78fa4a70f7d8eeaeb5f6a8017 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Tue, 15 Dec 2020 17:58:50 -0500 Subject: [PATCH 132/191] let scope done --- src/engine/codegen/to_cil.py | 12 ++-- src/engine/cp/semantic.py | 1 + src/test.cl | 128 ++++++++++++++++++++++++++++++++--- 3 files changed, 126 insertions(+), 15 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 644ce39f..7cb6a33f 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -290,7 +290,6 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_t def visit(self, node: cool.LetInNode, scope: Scope): let_scope = scope.create_child() for var_decl in node.let_body: - let_scope.define_variable(var_decl.id.lex, var_decl.type) self.visit(var_decl, let_scope) result = self.visit(node.in_body, let_scope) @@ -298,13 +297,12 @@ def visit(self, node: cool.LetInNode, scope: Scope): @visitor.when(cool.LetVariableDeclaration) def visit(self, node: cool.LetVariableDeclaration, scope: Scope): - var_info = scope.find_variable(node.id.lex) - local_var = self.register_local(var_info) - + var_info = scope.define_variable(node.id.lex, node.type) + var_info.real_name = self.register_local(var_info) value = self.visit(node.expression, scope) - self.register_instruction(AssignNode(local_var, value)) - return local_var + self.register_instruction(AssignNode(var_info.real_name, value)) + return var_info.real_name @visitor.when(cool.FunctionCallNode) def visit(self, node: cool.FunctionCallNode, scope): @@ -408,7 +406,7 @@ def visit(self, node: cool.IdNode, scope: Scope): self.register_instruction( GetAttribNode(nvar, selfx, node.token.lex, self.current_type.name)) else: - nvar = nvar.name + nvar = nvar.real_name return nvar @visitor.when(cool.BoolNode) diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index e0034bca..c66fe86f 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -250,6 +250,7 @@ def __repr__(self): class VariableInfo: def __init__(self, name, vtype): + self.real_name = None self.name = name self.type = vtype self.calls = [] diff --git a/src/test.cl b/src/test.cl index 0dd94a40..f4125a2f 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,9 +1,121 @@ -class Main inherits IO { - a : Int; - main(): IO { - { - a <- 34; - out_string("Hello, World.\n"); - } - }; +(* + The class A2I provides integer-to-string and string-to-integer +conversion routines. To use these routines, either inherit them +in the class where needed, have a dummy variable bound to +something of type A2I, or simpl write (new A2I).method(argument). +*) + + +(* + c2i Converts a 1-character string to an integer. Aborts + if the string is not "0" through "9" +*) +class A2I { + + c2i(char : String) : Int { + if char = "0" then 0 else + if char = "1" then 1 else + if char = "2" then 2 else + if char = "3" then 3 else + if char = "4" then 4 else + if char = "5" then 5 else + if char = "6" then 6 else + if char = "7" then 7 else + if char = "8" then 8 else + if char = "9" then 9 else + { abort(); 0; } -- the 0 is needed to satisfy the typchecker + fi fi fi fi fi fi fi fi fi fi + }; + +(* + i2c is the inverse of c2i. +*) + i2c(i : Int) : String { + if i = 0 then "0" else + if i = 1 then "1" else + if i = 2 then "2" else + if i = 3 then "3" else + if i = 4 then "4" else + if i = 5 then "5" else + if i = 6 then "6" else + if i = 7 then "7" else + if i = 8 then "8" else + if i = 9 then "9" else + { abort(); ""; } -- the "" is needed to satisfy the typchecker + fi fi fi fi fi fi fi fi fi fi + }; + +(* + a2i converts an ASCII string into an integer. The empty string +is converted to 0. Signed and unsigned strings are handled. The +method aborts if the string does not represent an integer. Very +long strings of digits produce strange answers because of arithmetic +overflow. + +*) + a2i(s : String) : Int { + if s.length() = 0 then 0 else + if s.substr(0,1) = "-" then ~a2i_aux(s.substr(1,s.length()-1)) else + if s.substr(0,1) = "+" then a2i_aux(s.substr(1,s.length()-1)) else + a2i_aux(s) + fi fi fi + }; + +(* + a2i_aux converts the usigned portion of the string. As a programming +example, this method is written iteratively. +*) + a2i_aux(s : String) : Int { + (let int : Int <- 0 in + { + (let j : Int <- s.length() in + (let i : Int <- 0 in + while i < j loop + { + int <- int * 10 + c2i(s.substr(i,1)); + i <- i + 1; + } + pool + ) + ); + int; + } + ) + }; + +(* + i2a converts an integer to a string. Positive and negative +numbers are handled correctly. +*) + i2a(i : Int) : String { + if i = 0 then "0" else + if 0 < i then i2a_aux(i) else + "-".concat(i2a_aux(i * ~1)) + fi fi + }; + +(* + i2a_aux is an example using recursion. +*) + i2a_aux(i : Int) : String { + if i = 0 then "" else + (let next : Int <- i / 10 in + i2a_aux(next).concat(i2c(i - next * 10)) + ) + fi + }; + }; + +class Main inherits IO { + main () : Object { + let a : Int <- (new A2I).a2i("678987"), + b : String <- (new A2I).i2a(678987) in + { + out_int(a) ; + out_string(" == ") ; + out_string(b) ; + out_string("\n"); + } + } ; +} ; From 5aa869d5b86633e0ecfc7f09c5936998ed5c4509 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Tue, 15 Dec 2020 22:43:16 -0500 Subject: [PATCH 133/191] 2nd test written --- src/engine/codegen/to_cil.py | 9 +- src/engine/codegen/to_mips.py | 7 +- src/engine/cp/semantic.py | 2 +- src/main.py | 2 +- src/test.mips | 2343 ++++++++++++++++++++++++++++++++- 5 files changed, 2318 insertions(+), 45 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 7cb6a33f..dbb8f975 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -160,10 +160,10 @@ def visit(self, node: cool.AttrDeclarationNode, scope: Scope, typex): @visitor.when(cool.BlockNode) def visit(self, node: cool.BlockNode, scope): - result = self.define_internal_local() + result = None for expr in node.expressions: - val = self.visit(expr, scope) - self.register_instruction(AssignNode(result, val)) + result = self.visit(expr, scope) + # self.register_instruction(AssignNode(result, val)) return result @visitor.when(cool.AssignNode) @@ -175,7 +175,7 @@ def visit(self, node: cool.AssignNode, scope: Scope): self.register_instruction(SetAttribNode( selfx, node.id.lex, expr, self.current_type.name)) else: - var_info = var_info.name + var_info = var_info.real_name self.register_instruction(AssignNode(var_info, expr)) return 0 @@ -227,6 +227,7 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(IfGotoNode(cond, continue_label.label)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) + print(node.body) self.visit(node.body, while_scope) label_counter = self.label_counter_gen() self.register_instruction(GotoNode(start_label.label)) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 874a8e81..c70fef1a 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -222,15 +222,16 @@ def visit(self, node: SetAttribNode): else: try: value = int(node.value) - self.mips.li(reg.s1,value) + self.mips.li(reg.s1, value) except ValueError: if node.value in self.data_segment: self.mips.comment(f"SET data {node.value}") self.mips.la(reg.s1, node.value) else: raise Exception(f"Setattr: label {node.value} not found") - - self.mips.store_memory(reg.s1, self.mips.offset(reg.s0, offset * self.data_size)) + + self.mips.store_memory(reg.s1, self.mips.offset( + reg.s0, offset * self.data_size)) @visitor.when(AssignNode) def visit(self, node: AssignNode): diff --git a/src/engine/cp/semantic.py b/src/engine/cp/semantic.py index c66fe86f..97832cc5 100644 --- a/src/engine/cp/semantic.py +++ b/src/engine/cp/semantic.py @@ -250,7 +250,7 @@ def __repr__(self): class VariableInfo: def __init__(self, name, vtype): - self.real_name = None + self.real_name = name self.name = name self.type = vtype self.calls = [] diff --git a/src/main.py b/src/main.py index ab8e4234..2291a5cc 100644 --- a/src/main.py +++ b/src/main.py @@ -76,7 +76,7 @@ emsamb.visit(cil_ast) f_ast = emsamb.mips.compile() -#f_ast = CIL_FORMATTER().visit(cil_ast) +# f_ast = CIL_FORMATTER().visit(cil_ast) string_formatted = str(f_ast) output_file.write(string_formatted) diff --git a/src/test.mips b/src/test.mips index 602f67a7..fcb063ae 100644 --- a/src/test.mips +++ b/src/test.mips @@ -9,6 +9,8 @@ classname_Int: .asciiz "Int" classname_Bool: .asciiz "Bool" +classname_A2I: +.asciiz "A2I" classname_Main: .asciiz "Main" data_0: @@ -22,12 +24,42 @@ data_3: data_4: .asciiz "Invalid substring" data_5: -.asciiz "Hello, World. +.asciiz "0" +data_6: +.asciiz "1" +data_7: +.asciiz "2" +data_8: +.asciiz "3" +data_9: +.asciiz "4" +data_10: +.asciiz "5" +data_11: +.asciiz "6" +data_12: +.asciiz "7" +data_13: +.asciiz "8" +data_14: +.asciiz "9" +data_15: +.asciiz "" +data_16: +.asciiz "-" +data_17: +.asciiz "+" +data_18: +.asciiz "678987" +data_19: +.asciiz " == " +data_20: +.asciiz " " .text main: # Allocate Vtable -li $a0, 120 +li $a0, 156 li $v0, 9 syscall move $s7, $v0 @@ -82,16 +114,34 @@ la $s0, function_type_name_at_Object sw $s0, 92($s7) la $s0, function_copy_at_Object sw $s0, 96($s7) -la $s0, function_out_string_at_IO +la $s0, function_c2i_at_A2I sw $s0, 100($s7) -la $s0, function_out_int_at_IO +la $s0, function_i2c_at_A2I sw $s0, 104($s7) -la $s0, function_in_string_at_IO +la $s0, function_a2i_at_A2I sw $s0, 108($s7) -la $s0, function_in_int_at_IO +la $s0, function_a2i_aux_at_A2I sw $s0, 112($s7) -la $s0, function_main_at_Main +la $s0, function_i2a_at_A2I sw $s0, 116($s7) +la $s0, function_i2a_aux_at_A2I +sw $s0, 120($s7) +la $s0, function_abort_at_Object +sw $s0, 124($s7) +la $s0, function_type_name_at_Object +sw $s0, 128($s7) +la $s0, function_copy_at_Object +sw $s0, 132($s7) +la $s0, function_out_string_at_IO +sw $s0, 136($s7) +la $s0, function_out_int_at_IO +sw $s0, 140($s7) +la $s0, function_in_string_at_IO +sw $s0, 144($s7) +la $s0, function_in_int_at_IO +sw $s0, 148($s7) +la $s0, function_main_at_Main +sw $s0, 152($s7) jal entry li $v0, 10 @@ -1156,14 +1206,14 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra -ctor_Main: +ctor_A2I: # Set stack frame addi $sp, $sp, -4 sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -4 +addi $sp, $sp, 0 # Saving Registers @@ -1185,7 +1235,6 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code -sw $zero, 4($fp) # ReturnNode # Load from self to $v0 lw $v0, 4($fp) @@ -1209,7 +1258,64 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 # Return lw $fp, 0($sp) addi $sp, $sp, 4 @@ -1221,7 +1327,7 @@ sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -12 +addi $sp, $sp, -8 # Saving Registers @@ -1244,21 +1350,19 @@ sw $s6, 0($sp) # Generating body code # Allocate space for Main -li $a0, 20 +li $a0, 16 li $v0, 9 syscall move $s1, $v0 sw $s1, 4($fp) li $s0, 0 sw $s0, 0($s1) -li $s0, 20 +li $s0, 16 sw $s0, 4($s1) la $s0, classname_Main sw $s0, 8($s1) -li $s0, 88 +li $s0, 124 sw $s0, 12($s1) -sw $zero, 16($s1) -sw $zero, 12($fp) # ArgNode local__internal_0 to s0 # Load from local__internal_0 to $s0 lw $s0, 4($fp) @@ -1288,19 +1392,19 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 12 +addi $sp, $sp, 8 # Return lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra -function_main_at_Main: +function_c2i_at_A2I: # Set stack frame addi $sp, $sp, -4 sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -16 +addi $sp, $sp, -168 # Saving Registers @@ -1322,37 +1426,2204 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code -li $s0, 34 -sw $s0, 8($fp) # Load from data_5 to $s0 la $s0, data_5 +sw $s0, 4($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_0 to $s1 +lw $s1, 4($fp) +move $t0, $s0 +li $t1, 0 +mips_label_60: +lb $t3, 0($t0) +beqz $t3, mips_label_61 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_60 +mips_label_61: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_62: +lb $t3, 0($t0) +beqz $t3, mips_label_63 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_62 +mips_label_63: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_57 +move $s2, $s0 +move $s3, $s1 +mips_label_59: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_57 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_58 +j mips_label_59 +mips_label_58: +li $v0, 1 +mips_label_57: +sw $v0, 8($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_1 +# Load from data_6 to $s0 +la $s0, data_6 sw $s0, 16($fp) -# ArgNode local_main_at_Main_internal_3 to s0 -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_3 to $s1 +lw $s1, 16($fp) +move $t0, $s0 +li $t1, 0 +mips_label_67: +lb $t3, 0($t0) +beqz $t3, mips_label_68 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_67 +mips_label_68: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_69: +lb $t3, 0($t0) +beqz $t3, mips_label_70 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_69 +mips_label_70: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_64 +move $s2, $s0 +move $s3, $s1 +mips_label_66: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_64 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_65 +j mips_label_66 +mips_label_65: +li $v0, 1 +mips_label_64: +sw $v0, 20($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +li $t1, 0 +bne $t0, $t1, TRUE_2 +# Load from data_7 to $s0 +la $s0, data_7 +sw $s0, 28($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_6 to $s1 +lw $s1, 28($fp) +move $t0, $s0 +li $t1, 0 +mips_label_74: +lb $t3, 0($t0) +beqz $t3, mips_label_75 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_74 +mips_label_75: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_76: +lb $t3, 0($t0) +beqz $t3, mips_label_77 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_76 +mips_label_77: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_71 +move $s2, $s0 +move $s3, $s1 +mips_label_73: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_71 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_72 +j mips_label_73 +mips_label_72: +li $v0, 1 +mips_label_71: +sw $v0, 32($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, TRUE_3 +# Load from data_8 to $s0 +la $s0, data_8 +sw $s0, 40($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_9 to $s1 +lw $s1, 40($fp) +move $t0, $s0 +li $t1, 0 +mips_label_81: +lb $t3, 0($t0) +beqz $t3, mips_label_82 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_81 +mips_label_82: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_83: +lb $t3, 0($t0) +beqz $t3, mips_label_84 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_83 +mips_label_84: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_78 +move $s2, $s0 +move $s3, $s1 +mips_label_80: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_78 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_79 +j mips_label_80 +mips_label_79: +li $v0, 1 +mips_label_78: +sw $v0, 44($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +li $t1, 0 +bne $t0, $t1, TRUE_4 +# Load from data_9 to $s0 +la $s0, data_9 +sw $s0, 52($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_12 to $s1 +lw $s1, 52($fp) +move $t0, $s0 +li $t1, 0 +mips_label_88: +lb $t3, 0($t0) +beqz $t3, mips_label_89 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_88 +mips_label_89: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_90: +lb $t3, 0($t0) +beqz $t3, mips_label_91 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_90 +mips_label_91: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_85 +move $s2, $s0 +move $s3, $s1 +mips_label_87: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_85 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_86 +j mips_label_87 +mips_label_86: +li $v0, 1 +mips_label_85: +sw $v0, 56($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +li $t1, 0 +bne $t0, $t1, TRUE_5 +# Load from data_10 to $s0 +la $s0, data_10 +sw $s0, 64($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_15 to $s1 +lw $s1, 64($fp) +move $t0, $s0 +li $t1, 0 +mips_label_95: +lb $t3, 0($t0) +beqz $t3, mips_label_96 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_95 +mips_label_96: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_97: +lb $t3, 0($t0) +beqz $t3, mips_label_98 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_97 +mips_label_98: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_92 +move $s2, $s0 +move $s3, $s1 +mips_label_94: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_92 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_93 +j mips_label_94 +mips_label_93: +li $v0, 1 +mips_label_92: +sw $v0, 68($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +li $t1, 0 +bne $t0, $t1, TRUE_6 +# Load from data_11 to $s0 +la $s0, data_11 +sw $s0, 76($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_18 to $s1 +lw $s1, 76($fp) +move $t0, $s0 +li $t1, 0 +mips_label_102: +lb $t3, 0($t0) +beqz $t3, mips_label_103 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_102 +mips_label_103: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_104: +lb $t3, 0($t0) +beqz $t3, mips_label_105 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_104 +mips_label_105: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_99 +move $s2, $s0 +move $s3, $s1 +mips_label_101: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_99 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_100 +j mips_label_101 +mips_label_100: +li $v0, 1 +mips_label_99: +sw $v0, 80($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_19 to $t0 +lw $t0, 80($fp) +li $t1, 0 +bne $t0, $t1, TRUE_7 +# Load from data_12 to $s0 +la $s0, data_12 +sw $s0, 88($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_21 to $s1 +lw $s1, 88($fp) +move $t0, $s0 +li $t1, 0 +mips_label_109: +lb $t3, 0($t0) +beqz $t3, mips_label_110 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_109 +mips_label_110: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_111: +lb $t3, 0($t0) +beqz $t3, mips_label_112 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_111 +mips_label_112: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_106 +move $s2, $s0 +move $s3, $s1 +mips_label_108: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_106 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_107 +j mips_label_108 +mips_label_107: +li $v0, 1 +mips_label_106: +sw $v0, 92($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_22 to $t0 +lw $t0, 92($fp) +li $t1, 0 +bne $t0, $t1, TRUE_8 +# Load from data_13 to $s0 +la $s0, data_13 +sw $s0, 100($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_24 to $s1 +lw $s1, 100($fp) +move $t0, $s0 +li $t1, 0 +mips_label_116: +lb $t3, 0($t0) +beqz $t3, mips_label_117 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_116 +mips_label_117: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_118: +lb $t3, 0($t0) +beqz $t3, mips_label_119 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_118 +mips_label_119: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_113 +move $s2, $s0 +move $s3, $s1 +mips_label_115: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_113 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_114 +j mips_label_115 +mips_label_114: +li $v0, 1 +mips_label_113: +sw $v0, 104($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_25 to $t0 +lw $t0, 104($fp) +li $t1, 0 +bne $t0, $t1, TRUE_9 +# Load from data_14 to $s0 +la $s0, data_14 +sw $s0, 112($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_27 to $s1 +lw $s1, 112($fp) +move $t0, $s0 +li $t1, 0 +mips_label_123: +lb $t3, 0($t0) +beqz $t3, mips_label_124 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_123 +mips_label_124: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_125: +lb $t3, 0($t0) +beqz $t3, mips_label_126 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_125 +mips_label_126: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_120 +move $s2, $s0 +move $s3, $s1 +mips_label_122: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_120 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_121 +j mips_label_122 +mips_label_121: +li $v0, 1 +mips_label_120: +sw $v0, 116($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +li $t1, 0 +bne $t0, $t1, TRUE_10 # ArgNode self to s0 # Load from self to $s0 lw $s0, 4($fp) addi $sp, $sp, -4 sw $s0, 0($sp) -# DynamicCallNode Main out_string +# DynamicCallNode A2I abort # Load from self to $s0 lw $s0, 4($fp) lw $s1, 12($s0) -addi $s2, $s1, 12 +addi $s2, $s1, 0 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 12($fp) -addi $sp, $sp, 8 -# Load from local_main_at_Main_internal_2 to $t0 -lw $t0, 12($fp) -sw $t0, 4($fp) +sw $v0, 124($fp) +addi $sp, $sp, 4 +li $s0, 0 +sw $s0, 128($fp) +# Load from local_c2i_at_A2I_internal_31 to $t0 +lw $t0, 128($fp) +sw $t0, 120($fp) +# GotoNode +j END_10 +TRUE_10: +li $s0, 9 +sw $s0, 132($fp) +# Load from local_c2i_at_A2I_internal_32 to $t0 +lw $t0, 132($fp) +sw $t0, 120($fp) +END_10: +# Load from local_c2i_at_A2I_internal_29 to $t0 +lw $t0, 120($fp) +sw $t0, 108($fp) +# GotoNode +j END_9 +TRUE_9: +li $s0, 8 +sw $s0, 136($fp) +# Load from local_c2i_at_A2I_internal_33 to $t0 +lw $t0, 136($fp) +sw $t0, 108($fp) +END_9: +# Load from local_c2i_at_A2I_internal_26 to $t0 +lw $t0, 108($fp) +sw $t0, 96($fp) +# GotoNode +j END_8 +TRUE_8: +li $s0, 7 +sw $s0, 140($fp) +# Load from local_c2i_at_A2I_internal_34 to $t0 +lw $t0, 140($fp) +sw $t0, 96($fp) +END_8: +# Load from local_c2i_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 84($fp) +# GotoNode +j END_7 +TRUE_7: +li $s0, 6 +sw $s0, 144($fp) +# Load from local_c2i_at_A2I_internal_35 to $t0 +lw $t0, 144($fp) +sw $t0, 84($fp) +END_7: +# Load from local_c2i_at_A2I_internal_20 to $t0 +lw $t0, 84($fp) +sw $t0, 72($fp) +# GotoNode +j END_6 +TRUE_6: +li $s0, 5 +sw $s0, 148($fp) +# Load from local_c2i_at_A2I_internal_36 to $t0 +lw $t0, 148($fp) +sw $t0, 72($fp) +END_6: +# Load from local_c2i_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 60($fp) +# GotoNode +j END_5 +TRUE_5: +li $s0, 4 +sw $s0, 152($fp) +# Load from local_c2i_at_A2I_internal_37 to $t0 +lw $t0, 152($fp) +sw $t0, 60($fp) +END_5: +# Load from local_c2i_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +sw $t0, 48($fp) +# GotoNode +j END_4 +TRUE_4: +li $s0, 3 +sw $s0, 156($fp) +# Load from local_c2i_at_A2I_internal_38 to $t0 +lw $t0, 156($fp) +sw $t0, 48($fp) +END_4: +# Load from local_c2i_at_A2I_internal_11 to $t0 +lw $t0, 48($fp) +sw $t0, 36($fp) +# GotoNode +j END_3 +TRUE_3: +li $s0, 2 +sw $s0, 160($fp) +# Load from local_c2i_at_A2I_internal_39 to $t0 +lw $t0, 160($fp) +sw $t0, 36($fp) +END_3: +# Load from local_c2i_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +sw $t0, 24($fp) +# GotoNode +j END_2 +TRUE_2: +li $s0, 1 +sw $s0, 164($fp) +# Load from local_c2i_at_A2I_internal_40 to $t0 +lw $t0, 164($fp) +sw $t0, 24($fp) +END_2: +# Load from local_c2i_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_1 +TRUE_1: +li $s0, 0 +sw $s0, 168($fp) +# Load from local_c2i_at_A2I_internal_41 to $t0 +lw $t0, 168($fp) +sw $t0, 12($fp) +END_1: # ReturnNode -# Load from local_main_at_Main_internal_0 to $v0 -lw $v0, 4($fp) +# Load from local_c2i_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 168 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2c_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -168 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_21 +li $s0, 1 +sw $s0, 16($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_3 to $t1 +lw $t1, 16($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 20($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +li $t1, 0 +bne $t0, $t1, TRUE_22 +li $s0, 2 +sw $s0, 28($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_6 to $t1 +lw $t1, 28($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 32($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, TRUE_23 +li $s0, 3 +sw $s0, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 44($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +li $t1, 0 +bne $t0, $t1, TRUE_24 +li $s0, 4 +sw $s0, 52($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_12 to $t1 +lw $t1, 52($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 56($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +li $t1, 0 +bne $t0, $t1, TRUE_25 +li $s0, 5 +sw $s0, 64($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_15 to $t1 +lw $t1, 64($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 68($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +li $t1, 0 +bne $t0, $t1, TRUE_26 +li $s0, 6 +sw $s0, 76($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_18 to $t1 +lw $t1, 76($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 80($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_19 to $t0 +lw $t0, 80($fp) +li $t1, 0 +bne $t0, $t1, TRUE_27 +li $s0, 7 +sw $s0, 88($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_21 to $t1 +lw $t1, 88($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 92($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_22 to $t0 +lw $t0, 92($fp) +li $t1, 0 +bne $t0, $t1, TRUE_28 +li $s0, 8 +sw $s0, 100($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_24 to $t1 +lw $t1, 100($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 104($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_25 to $t0 +lw $t0, 104($fp) +li $t1, 0 +bne $t0, $t1, TRUE_29 +li $s0, 9 +sw $s0, 112($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_27 to $t1 +lw $t1, 112($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 116($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +li $t1, 0 +bne $t0, $t1, TRUE_30 +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I abort +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 0 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 124($fp) +addi $sp, $sp, 4 +# Load from data_15 to $s0 +la $s0, data_15 +sw $s0, 128($fp) +# Load from local_i2c_at_A2I_internal_31 to $t0 +lw $t0, 128($fp) +sw $t0, 120($fp) +# GotoNode +j END_30 +TRUE_30: +# Load from data_14 to $s0 +la $s0, data_14 +sw $s0, 132($fp) +# Load from local_i2c_at_A2I_internal_32 to $t0 +lw $t0, 132($fp) +sw $t0, 120($fp) +END_30: +# Load from local_i2c_at_A2I_internal_29 to $t0 +lw $t0, 120($fp) +sw $t0, 108($fp) +# GotoNode +j END_29 +TRUE_29: +# Load from data_13 to $s0 +la $s0, data_13 +sw $s0, 136($fp) +# Load from local_i2c_at_A2I_internal_33 to $t0 +lw $t0, 136($fp) +sw $t0, 108($fp) +END_29: +# Load from local_i2c_at_A2I_internal_26 to $t0 +lw $t0, 108($fp) +sw $t0, 96($fp) +# GotoNode +j END_28 +TRUE_28: +# Load from data_12 to $s0 +la $s0, data_12 +sw $s0, 140($fp) +# Load from local_i2c_at_A2I_internal_34 to $t0 +lw $t0, 140($fp) +sw $t0, 96($fp) +END_28: +# Load from local_i2c_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 84($fp) +# GotoNode +j END_27 +TRUE_27: +# Load from data_11 to $s0 +la $s0, data_11 +sw $s0, 144($fp) +# Load from local_i2c_at_A2I_internal_35 to $t0 +lw $t0, 144($fp) +sw $t0, 84($fp) +END_27: +# Load from local_i2c_at_A2I_internal_20 to $t0 +lw $t0, 84($fp) +sw $t0, 72($fp) +# GotoNode +j END_26 +TRUE_26: +# Load from data_10 to $s0 +la $s0, data_10 +sw $s0, 148($fp) +# Load from local_i2c_at_A2I_internal_36 to $t0 +lw $t0, 148($fp) +sw $t0, 72($fp) +END_26: +# Load from local_i2c_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 60($fp) +# GotoNode +j END_25 +TRUE_25: +# Load from data_9 to $s0 +la $s0, data_9 +sw $s0, 152($fp) +# Load from local_i2c_at_A2I_internal_37 to $t0 +lw $t0, 152($fp) +sw $t0, 60($fp) +END_25: +# Load from local_i2c_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +sw $t0, 48($fp) +# GotoNode +j END_24 +TRUE_24: +# Load from data_8 to $s0 +la $s0, data_8 +sw $s0, 156($fp) +# Load from local_i2c_at_A2I_internal_38 to $t0 +lw $t0, 156($fp) +sw $t0, 48($fp) +END_24: +# Load from local_i2c_at_A2I_internal_11 to $t0 +lw $t0, 48($fp) +sw $t0, 36($fp) +# GotoNode +j END_23 +TRUE_23: +# Load from data_7 to $s0 +la $s0, data_7 +sw $s0, 160($fp) +# Load from local_i2c_at_A2I_internal_39 to $t0 +lw $t0, 160($fp) +sw $t0, 36($fp) +END_23: +# Load from local_i2c_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +sw $t0, 24($fp) +# GotoNode +j END_22 +TRUE_22: +# Load from data_6 to $s0 +la $s0, data_6 +sw $s0, 164($fp) +# Load from local_i2c_at_A2I_internal_40 to $t0 +lw $t0, 164($fp) +sw $t0, 24($fp) +END_22: +# Load from local_i2c_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_21 +TRUE_21: +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 168($fp) +# Load from local_i2c_at_A2I_internal_41 to $t0 +lw $t0, 168($fp) +sw $t0, 12($fp) +END_21: +# ReturnNode +# Load from local_i2c_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 168 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_a2i_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -124 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 4($fp) +addi $sp, $sp, 4 +li $s0, 0 +sw $s0, 8($fp) +# Load from local_a2i_at_A2I_internal_0 to $t0 +lw $t0, 4($fp) +# Load from local_a2i_at_A2I_internal_1 to $t1 +lw $t1, 8($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 12($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_2 to $t0 +lw $t0, 12($fp) +li $t1, 0 +bne $t0, $t1, TRUE_41 +li $s0, 0 +sw $s0, 24($fp) +li $s0, 1 +sw $s0, 28($fp) +# ArgNode local_a2i_at_A2I_internal_6 to s0 +# Load from local_a2i_at_A2I_internal_6 to $s0 +lw $s0, 28($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_5 to s0 +# Load from local_a2i_at_A2I_internal_5 to $s0 +lw $s0, 24($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 20($fp) +addi $sp, $sp, 12 +# Load from data_16 to $s0 +la $s0, data_16 +sw $s0, 32($fp) +# Load from local_a2i_at_A2I_internal_4 to $s0 +lw $s0, 20($fp) +# Load from local_a2i_at_A2I_internal_7 to $s1 +lw $s1, 32($fp) +move $t0, $s0 +li $t1, 0 +mips_label_130: +lb $t3, 0($t0) +beqz $t3, mips_label_131 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_130 +mips_label_131: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_132: +lb $t3, 0($t0) +beqz $t3, mips_label_133 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_132 +mips_label_133: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_127 +move $s2, $s0 +move $s3, $s1 +mips_label_129: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_127 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_128 +j mips_label_129 +mips_label_128: +li $v0, 1 +mips_label_127: +sw $v0, 36($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +li $t1, 0 +bne $t0, $t1, TRUE_42 +li $s0, 0 +sw $s0, 48($fp) +li $s0, 1 +sw $s0, 52($fp) +# ArgNode local_a2i_at_A2I_internal_12 to s0 +# Load from local_a2i_at_A2I_internal_12 to $s0 +lw $s0, 52($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_11 to s0 +# Load from local_a2i_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 44($fp) +addi $sp, $sp, 12 +# Load from data_17 to $s0 +la $s0, data_17 +sw $s0, 56($fp) +# Load from local_a2i_at_A2I_internal_10 to $s0 +lw $s0, 44($fp) +# Load from local_a2i_at_A2I_internal_13 to $s1 +lw $s1, 56($fp) +move $t0, $s0 +li $t1, 0 +mips_label_137: +lb $t3, 0($t0) +beqz $t3, mips_label_138 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_137 +mips_label_138: +move $s2, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_139: +lb $t3, 0($t0) +beqz $t3, mips_label_140 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_139 +mips_label_140: +move $s3, $t1 +move $v0, $zero +bne $s2, $s3, mips_label_134 +move $s2, $s0 +move $s3, $s1 +mips_label_136: +lb $s4, 0($s2) +lb $s5, 0($s3) +bne $s4, $s5, mips_label_134 +addi $s2, $s2, 1 +addi $s3, $s3, 1 +beqz $s4, mips_label_135 +j mips_label_136 +mips_label_135: +li $v0, 1 +mips_label_134: +sw $v0, 60($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +li $t1, 0 +bne $t0, $t1, TRUE_43 +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 68($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +sw $t0, 64($fp) +# GotoNode +j END_43 +TRUE_43: +li $s0, 1 +sw $s0, 80($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 88($fp) +addi $sp, $sp, 4 +li $s0, 1 +sw $s0, 92($fp) +# Load from local_a2i_at_A2I_internal_21 to $t0 +lw $t0, 88($fp) +# Load from local_a2i_at_A2I_internal_22 to $t1 +lw $t1, 92($fp) +sub $t2, $t0, $t1 +sw $t2, 84($fp) +# ArgNode local_a2i_at_A2I_internal_20 to s0 +# Load from local_a2i_at_A2I_internal_20 to $s0 +lw $s0, 84($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_19 to s0 +# Load from local_a2i_at_A2I_internal_19 to $s0 +lw $s0, 80($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 76($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_at_A2I_internal_18 to s0 +# Load from local_a2i_at_A2I_internal_18 to $s0 +lw $s0, 76($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 72($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 64($fp) +END_43: +# Load from local_a2i_at_A2I_internal_15 to $t0 +lw $t0, 64($fp) +sw $t0, 40($fp) +# GotoNode +j END_42 +TRUE_42: +li $s0, 1 +sw $s0, 108($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 116($fp) +addi $sp, $sp, 4 +li $s0, 1 +sw $s0, 120($fp) +# Load from local_a2i_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +# Load from local_a2i_at_A2I_internal_29 to $t1 +lw $t1, 120($fp) +sub $t2, $t0, $t1 +sw $t2, 112($fp) +# ArgNode local_a2i_at_A2I_internal_27 to s0 +# Load from local_a2i_at_A2I_internal_27 to $s0 +lw $s0, 112($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_26 to s0 +# Load from local_a2i_at_A2I_internal_26 to $s0 +lw $s0, 108($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 104($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_at_A2I_internal_25 to s0 +# Load from local_a2i_at_A2I_internal_25 to $s0 +lw $s0, 104($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 100($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_24 to $t0 +lw $t0, 100($fp) +nor $t1, $t0, $t0 +sw $t1, 96($fp) +# Load from local_a2i_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 40($fp) +END_42: +# Load from local_a2i_at_A2I_internal_9 to $t0 +lw $t0, 40($fp) +sw $t0, 16($fp) +# GotoNode +j END_41 +TRUE_41: +li $s0, 0 +sw $s0, 124($fp) +# Load from local_a2i_at_A2I_internal_30 to $t0 +lw $t0, 124($fp) +sw $t0, 16($fp) +END_41: +# ReturnNode +# Load from local_a2i_at_A2I_internal_3 to $v0 +lw $v0, 16($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 124 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_a2i_aux_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -60 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 8($fp) +# Load from local_a2i_aux_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +sw $t0, 4($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 16($fp) +addi $sp, $sp, 4 +# Load from local_a2i_aux_at_A2I_internal_3 to $t0 +lw $t0, 16($fp) +sw $t0, 12($fp) +li $s0, 0 +sw $s0, 24($fp) +# Load from local_a2i_aux_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 20($fp) +START_47: +# Load from local_a2i_aux_at_A2I_i_4 to $t0 +lw $t0, 20($fp) +# Load from local_a2i_aux_at_A2I_j_2 to $t1 +lw $t1, 12($fp) +slt $t2, $t0, $t1 +sw $t2, 28($fp) +# IfGotoNode +# Load from local_a2i_aux_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +li $t1, 0 +bne $t0, $t1, CONTINUE_47 +# GotoNode +j END_47 +CONTINUE_47: +li $s0, 10 +sw $s0, 40($fp) +# Load from local_a2i_aux_at_A2I_int_0 to $t0 +lw $t0, 4($fp) +# Load from local_a2i_aux_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 36($fp) +li $s0, 1 +sw $s0, 52($fp) +# ArgNode local_a2i_aux_at_A2I_internal_12 to s0 +# Load from local_a2i_aux_at_A2I_internal_12 to $s0 +lw $s0, 52($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_aux_at_A2I_i_4 to s0 +# Load from local_a2i_aux_at_A2I_i_4 to $s0 +lw $s0, 20($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_aux_at_A2I_internal_11 to s0 +# Load from local_a2i_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I c2i +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 44($fp) +addi $sp, $sp, 8 +# Load from local_a2i_aux_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +# Load from local_a2i_aux_at_A2I_internal_10 to $t1 +lw $t1, 44($fp) +add $t2, $t0, $t1 +sw $t2, 32($fp) +# Load from local_a2i_aux_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +sw $t0, 4($fp) +li $s0, 1 +sw $s0, 60($fp) +# Load from local_a2i_aux_at_A2I_i_4 to $t0 +lw $t0, 20($fp) +# Load from local_a2i_aux_at_A2I_internal_14 to $t1 +lw $t1, 60($fp) +add $t2, $t0, $t1 +sw $t2, 56($fp) +# Load from local_a2i_aux_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +sw $t0, 20($fp) +# GotoNode +j START_47 +END_47: +# ReturnNode +# Load from local_a2i_aux_at_A2I_int_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 60 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2a_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -56 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2a_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_49 +li $s0, 0 +sw $s0, 20($fp) +# Load from local_i2a_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +# Load from i to $t1 +lw $t1, 8($fp) +slt $t2, $t0, $t1 +sw $t2, 16($fp) +# IfGotoNode +# Load from local_i2a_at_A2I_internal_3 to $t0 +lw $t0, 16($fp) +li $t1, 0 +bne $t0, $t1, TRUE_50 +li $s0, 1 +sw $s0, 44($fp) +# Load from local_i2a_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +nor $t1, $t0, $t0 +sw $t1, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 36($fp) +# ArgNode local_i2a_at_A2I_internal_8 to s0 +# Load from local_i2a_at_A2I_internal_8 to $s0 +lw $s0, 36($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 32($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_at_A2I_internal_7 to s0 +# Load from local_i2a_at_A2I_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Load from data_16 to $s0 +la $s0, data_16 +sw $s0, 48($fp) +# ArgNode local_i2a_at_A2I_internal_11 to s0 +# Load from local_i2a_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String concat +# Load from local_i2a_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 28($fp) +addi $sp, $sp, 8 +# Load from local_i2a_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +sw $t0, 24($fp) +# GotoNode +j END_50 +TRUE_50: +# ArgNode i to s0 +# Load from i to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 52($fp) +addi $sp, $sp, 8 +# Load from local_i2a_at_A2I_internal_12 to $t0 +lw $t0, 52($fp) +sw $t0, 24($fp) +END_50: +# Load from local_i2a_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_49 +TRUE_49: +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 56($fp) +# Load from local_i2a_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +sw $t0, 12($fp) +END_49: +# ReturnNode +# Load from local_i2a_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 56 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2a_aux_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -52 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2a_aux_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_53 +li $s0, 10 +sw $s0, 24($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_5 to $t1 +lw $t1, 24($fp) +div $t2, $t0, $t1 +mflo $t0 +sw $t0, 20($fp) +# Load from local_i2a_aux_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +sw $t0, 16($fp) +li $s0, 10 +sw $s0, 44($fp) +# Load from local_i2a_aux_at_A2I_next_3 to $t0 +lw $t0, 16($fp) +# Load from local_i2a_aux_at_A2I_internal_10 to $t1 +lw $t1, 44($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +sub $t2, $t0, $t1 +sw $t2, 36($fp) +# ArgNode local_i2a_aux_at_A2I_internal_8 to s0 +# Load from local_i2a_aux_at_A2I_internal_8 to $s0 +lw $s0, 36($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2c +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 32($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_aux_at_A2I_internal_7 to s0 +# Load from local_i2a_aux_at_A2I_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_i2a_aux_at_A2I_next_3 to s0 +# Load from local_i2a_aux_at_A2I_next_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_aux_at_A2I_internal_11 to s0 +# Load from local_i2a_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String concat +# Load from local_i2a_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 28($fp) +addi $sp, $sp, 8 +# Load from local_i2a_aux_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +sw $t0, 12($fp) +# GotoNode +j END_53 +TRUE_53: +# Load from data_15 to $s0 +la $s0, data_15 +sw $s0, 52($fp) +# Load from local_i2a_aux_at_A2I_internal_12 to $t0 +lw $t0, 52($fp) +sw $t0, 12($fp) +END_53: +# ReturnNode +# Load from local_i2a_aux_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 52 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -56 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from data_18 to $s0 +la $s0, data_18 +sw $s0, 12($fp) +# ArgNode local_main_at_Main_internal_2 to s0 +# Load from local_main_at_Main_internal_2 to $s0 +lw $s0, 12($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Allocate space for A2I +li $a0, 16 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 16($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 16 +sw $s0, 4($s1) +la $s0, classname_A2I +sw $s0, 8($s1) +li $s0, 88 +sw $s0, 12($s1) +# ArgNode local_main_at_Main_internal_3 to s0 +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal ctor_A2I +sw $v0, 16($fp) +# ArgNode local_main_at_Main_internal_3 to s0 +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 8($fp) +addi $sp, $sp, 8 +# Load from local_main_at_Main_internal_1 to $t0 +lw $t0, 8($fp) +sw $t0, 4($fp) +li $s0, 678987 +sw $s0, 28($fp) +# ArgNode local_main_at_Main_internal_6 to s0 +# Load from local_main_at_Main_internal_6 to $s0 +lw $s0, 28($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Allocate space for A2I +li $a0, 16 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 32($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 16 +sw $s0, 4($s1) +la $s0, classname_A2I +sw $s0, 8($s1) +li $s0, 88 +sw $s0, 12($s1) +# ArgNode local_main_at_Main_internal_7 to s0 +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal ctor_A2I +sw $v0, 32($fp) +# ArgNode local_main_at_Main_internal_7 to s0 +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +lw $s1, 12($s0) +addi $s2, $s1, 28 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 24($fp) +addi $sp, $sp, 8 +# Load from local_main_at_Main_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 20($fp) +# ArgNode local_main_at_Main_a_0 to s0 +# Load from local_main_at_Main_a_0 to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_int +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 36($fp) +addi $sp, $sp, 8 +# Load from data_19 to $s0 +la $s0, data_19 +sw $s0, 44($fp) +# ArgNode local_main_at_Main_internal_10 to s0 +# Load from local_main_at_Main_internal_10 to $s0 +lw $s0, 44($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 40($fp) +addi $sp, $sp, 8 +# ArgNode local_main_at_Main_b_4 to s0 +# Load from local_main_at_Main_b_4 to $s0 +lw $s0, 20($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 8 +# Load from data_20 to $s0 +la $s0, data_20 +sw $s0, 56($fp) +# ArgNode local_main_at_Main_internal_13 to s0 +# Load from local_main_at_Main_internal_13 to $s0 +lw $s0, 56($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 52($fp) +addi $sp, $sp, 8 +# ReturnNode +# Load from local_main_at_Main_internal_12 to $v0 +lw $v0, 52($fp) # Restore registers lw $s6, 0($sp) @@ -1373,7 +3644,7 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 16 +addi $sp, $sp, 56 # Return lw $fp, 0($sp) addi $sp, $sp, 4 From 18036b20eeb9bd8a2fe2b8471600a426fcce5736 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 09:41:47 -0500 Subject: [PATCH 134/191] ctors for builtins --- src/engine/codegen/cil.py | 26 ++++++++++++++++++++++++++ src/engine/codegen/to_cil.py | 12 ++++++++++++ src/engine/parser/ast_parser.py | 12 +++++++----- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 3c625be3..9aab493b 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -110,6 +110,16 @@ def define_string_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods + # self.current_method = self.current_type.get_method('ctor_String') + # type_name = self.current_type.name + # self.current_function = self.register_function( + # self.to_function_name(self.current_method.name, type_name)) + # self_local = self.register_param(VariableInfo("self", None)) + # self.register_instruction( + # SetAttribNode(self_local, node.id.lex, result, typex)) + # self.register_instruction(ReturnNode(self_local)) + # self.current_method = self.current_function = None + self.current_method = self.current_type.get_method('length') type_name = self.current_type.name self.current_function = self.register_function( @@ -194,6 +204,14 @@ def define_io_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods + # self.current_method = self.current_type.get_method('ctor_IO') + # type_name = self.current_type.name + # self.current_function = self.register_function( + # self.to_function_name(self.current_method.name, type_name)) + # self_local = self.register_param(VariableInfo("self", None)) + # self.register_instruction(ReturnNode(self_local)) + # self.current_method = self.current_function = None + self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name self.current_function = self.register_function( @@ -242,6 +260,14 @@ def define_object_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods + # self.current_method = self.current_type.get_method('ctor_Object') + # type_name = self.current_type.name + # self.current_function = self.register_function( + # self.to_function_name(self.current_method.name, type_name)) + # self_local = self.register_param(VariableInfo("self", None)) + # self.register_instruction(ReturnNode(self_local)) + # self.current_method = self.current_function = None + self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name self.current_function = self.register_function( diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 7cb6a33f..81e08bb8 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -45,6 +45,18 @@ def save_attr_initializations(self, node: cool.ProgramNode, scope): self.attr_declarations = dict() self.attr_declarations['Object'] = [] self.attr_declarations['IO'] = [] + self.attr_declarations['Int'] = [ + cool.AttrDeclarationNode("value") + ] + self.attr_declarations['String'] = [ + cool.AttrDeclarationNode("value") + ] + self.attr_declarations['Bool'] = [ + cool.AttrDeclarationNode("value") + ] + + for built_in in ['IO', 'Int', 'String', 'Bool', 'Object']: + self.create_constructor(self.attr_declarations[built_in], built_in) for declaration in node.declarations: self.attr_declarations[declaration.id.lex] = [] diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py index 6123ffd4..e4d7cdbd 100644 --- a/src/engine/parser/ast_parser.py +++ b/src/engine/parser/ast_parser.py @@ -1,5 +1,7 @@ - +from engine.cp.utils import Token # AST Classes + + class Node: def __init__(self): self.line = 0 @@ -55,12 +57,12 @@ def __init__(self, idx, features, parent=None): class AttrDeclarationNode(DeclarationNode): - def __init__(self, idx, typex, expression=None): - self.id = idx + def __init__(self, idx, typex=None, expression=None): + self.id = Token(idx, 'ID', 0, 0) if isinstance(idx, str) else idx self.type = typex self.expression = expression - self.line = idx.line - self.column = idx.column + self.line = self.id.line + self.column = self.id.column def __iter__(self): yield from (self.id, self.type, self.expression) From 4588e10683ca19f0b9bd712f8f5ee416fcb3eddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 16 Dec 2020 10:40:36 -0500 Subject: [PATCH 135/191] Fix missing class index --- src/engine/codegen/mips.py | 1 + src/engine/codegen/to_mips.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 708cc528..6d0fede1 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -34,6 +34,7 @@ def __init__(self, dottypes: List[TypeNode], name_ptrs): dottype.name, index, dottype.attributes, methds, start_method, name_ptrs[dottype.name]) start_method = end_method + index += 1 self.vTable = VTable(methods) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 874a8e81..4720adf9 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -36,7 +36,8 @@ def fill_vtable(self): index = 0 self.mips.comment("Build VTable") - for _, tag in self.global_descriptor.vTable.methods.items(): + for name, tag in self.global_descriptor.vTable.methods.items(): + self.mips.comment(name) self.mips.la(reg.s0, tag) self.mips.store_memory(reg.s0, self.mips.offset( self.vtable_reg, index*self.data_size)) @@ -208,7 +209,7 @@ def visit(self, node: GetAttribNode): @visitor.when(SetAttribNode) def visit(self, node: SetAttribNode): self.mips.comment( - f"SetAttribNode {node.ojb}.{node.attrib} Type:{node.type} = {node.value}") + f"SetAttribNode {node.obj}.{node.attrib} Type:{node.type} = {node.value}") # get type info type_descritptor: MemoryType = self.global_descriptor.Types[node.type] # get attr offset From 47da1e04a4ad38927c6d04b288dbe2ddfe8e5d14 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 16 Dec 2020 11:02:58 -0500 Subject: [PATCH 136/191] last commit --- src/engine/codegen/mips.py | 8 +- src/engine/codegen/to_mips.py | 36 +- src/test.mips | 614 ++++++++++++---------------------- 3 files changed, 237 insertions(+), 421 deletions(-) diff --git a/src/engine/codegen/mips.py b/src/engine/codegen/mips.py index 708cc528..4acbaaab 100644 --- a/src/engine/codegen/mips.py +++ b/src/engine/codegen/mips.py @@ -441,10 +441,16 @@ def beqz(self, rsrc1, label): def bne(self, rsrc1, src2, label): ''' - Branch on Not Equal Zero + Branch on Not Equal ''' self._write(f'bne {rsrc1}, {src2}, {label}') + def bnez(self, rsrc1, label): + ''' + Branch on Not Equal Zero + ''' + self._write(f'bnez {rsrc1}, {label}') + def j(self, label): ''' Jump diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index c70fef1a..375f72fa 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -568,38 +568,40 @@ def visit(self, node: ConcatNode): def visit(self, node: StringEqualNode): end_label = self.get_label() end_ok_label = self.get_label() + end_wrong_label = self.get_label() loop_label = self.get_label() self.load_memory(reg.s0, node.msg1) self.load_memory(reg.s1, node.msg2) - self.get_string_length(reg.s0, reg.s2) - self.get_string_length(reg.s1, reg.s3) - - self.mips.move(reg.v0, reg.zero) - self.mips.bne(reg.s2, reg.s3, end_label) - - self.mips.move(reg.s2, reg.s0) - self.mips.move(reg.s3, reg.s1) + self.mips.move(reg.t8, reg.s0) + self.mips.move(reg.t9, reg.s1) self.mips.label(loop_label) + # me parece q aki esta fallando xq esta cargando un "0" + # en $t8, y cuando le pide el offset, no tiene nada, hay q ver ahi + # pero con el "1" hace lo mismo - self.mips.lb(reg.s4, self.mips.offset(reg.s2)) - self.mips.lb(reg.s5, self.mips.offset(reg.s3)) + self.mips.lb(reg.a0, self.mips.offset(reg.t8)) + self.mips.lb(reg.a1, self.mips.offset(reg.t9)) - self.mips.bne(reg.s4, reg.s5, end_label) + self.mips.beqz(reg.a0, end_ok_label) + self.mips.beqz(reg.a1, end_wrong_label) + self.mips.seq(reg.v0, reg.a0, reg.a1) + self.mips.beqz(reg.v0, end_wrong_label) - self.mips.addi(reg.s2, reg.s2, 1) - self.mips.addi(reg.s3, reg.s3, 1) - - self.mips.beqz( - reg.s4, end_ok_label - ) + self.mips.addi(reg.t8, reg.t8, 1) + self.mips.addi(reg.t9, reg.t9, 1) self.mips.j(loop_label) + self.mips.label(end_wrong_label) + self.mips.li(reg.v0, 0) + self.mips.j(end_label) self.mips.label(end_ok_label) + self.mips.bnez(reg.a1, end_wrong_label) self.mips.li(reg.v0, 1) self.mips.label(end_label) + self.store_memory(reg.v0, node.dest) @visitor.when(LoadNode) diff --git a/src/test.mips b/src/test.mips index fcb063ae..69e2d5de 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1433,39 +1433,23 @@ sw $s0, 4($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_0 to $s1 lw $s1, 4($fp) -move $t0, $s0 -li $t1, 0 +move $t8, $s0 +move $t9, $s1 mips_label_60: -lb $t3, 0($t0) -beqz $t3, mips_label_61 -addi $t1, $t1, 1 -addi $t0, $t0, 1 +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_58 +beqz $a1, mips_label_59 +seq $v0, $a0, $a1 +beqz $v0, mips_label_59 +addi $t8, $t8, 1 +addi $t9, $t9, 1 j mips_label_60 -mips_label_61: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_62: -lb $t3, 0($t0) -beqz $t3, mips_label_63 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_62 -mips_label_63: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_57 -move $s2, $s0 -move $s3, $s1 mips_label_59: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_57 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_58 -j mips_label_59 +li $v0, 0 +j mips_label_57 mips_label_58: +bnez $a1, mips_label_59 li $v0, 1 mips_label_57: sw $v0, 8($fp) @@ -1481,41 +1465,25 @@ sw $s0, 16($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_3 to $s1 lw $s1, 16($fp) -move $t0, $s0 -li $t1, 0 -mips_label_67: -lb $t3, 0($t0) -beqz $t3, mips_label_68 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_67 -mips_label_68: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_69: -lb $t3, 0($t0) -beqz $t3, mips_label_70 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_69 -mips_label_70: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_64 -move $s2, $s0 -move $s3, $s1 -mips_label_66: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_64 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_65 -j mips_label_66 -mips_label_65: -li $v0, 1 +move $t8, $s0 +move $t9, $s1 mips_label_64: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_62 +beqz $a1, mips_label_63 +seq $v0, $a0, $a1 +beqz $v0, mips_label_63 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_64 +mips_label_63: +li $v0, 0 +j mips_label_61 +mips_label_62: +bnez $a1, mips_label_63 +li $v0, 1 +mips_label_61: sw $v0, 20($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_4 to $t0 @@ -1529,41 +1497,25 @@ sw $s0, 28($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_6 to $s1 lw $s1, 28($fp) -move $t0, $s0 -li $t1, 0 -mips_label_74: -lb $t3, 0($t0) -beqz $t3, mips_label_75 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_74 -mips_label_75: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_76: -lb $t3, 0($t0) -beqz $t3, mips_label_77 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_76 -mips_label_77: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_71 -move $s2, $s0 -move $s3, $s1 -mips_label_73: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_71 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_72 -j mips_label_73 -mips_label_72: +move $t8, $s0 +move $t9, $s1 +mips_label_68: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_66 +beqz $a1, mips_label_67 +seq $v0, $a0, $a1 +beqz $v0, mips_label_67 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_68 +mips_label_67: +li $v0, 0 +j mips_label_65 +mips_label_66: +bnez $a1, mips_label_67 li $v0, 1 -mips_label_71: +mips_label_65: sw $v0, 32($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_7 to $t0 @@ -1577,41 +1529,25 @@ sw $s0, 40($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_9 to $s1 lw $s1, 40($fp) -move $t0, $s0 -li $t1, 0 -mips_label_81: -lb $t3, 0($t0) -beqz $t3, mips_label_82 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_81 -mips_label_82: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_83: -lb $t3, 0($t0) -beqz $t3, mips_label_84 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_83 -mips_label_84: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_78 -move $s2, $s0 -move $s3, $s1 -mips_label_80: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_78 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_79 -j mips_label_80 -mips_label_79: +move $t8, $s0 +move $t9, $s1 +mips_label_72: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_70 +beqz $a1, mips_label_71 +seq $v0, $a0, $a1 +beqz $v0, mips_label_71 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_72 +mips_label_71: +li $v0, 0 +j mips_label_69 +mips_label_70: +bnez $a1, mips_label_71 li $v0, 1 -mips_label_78: +mips_label_69: sw $v0, 44($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_10 to $t0 @@ -1625,41 +1561,25 @@ sw $s0, 52($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_12 to $s1 lw $s1, 52($fp) -move $t0, $s0 -li $t1, 0 -mips_label_88: -lb $t3, 0($t0) -beqz $t3, mips_label_89 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_88 -mips_label_89: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_90: -lb $t3, 0($t0) -beqz $t3, mips_label_91 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_90 -mips_label_91: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_85 -move $s2, $s0 -move $s3, $s1 -mips_label_87: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_85 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_86 -j mips_label_87 -mips_label_86: +move $t8, $s0 +move $t9, $s1 +mips_label_76: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_74 +beqz $a1, mips_label_75 +seq $v0, $a0, $a1 +beqz $v0, mips_label_75 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_76 +mips_label_75: +li $v0, 0 +j mips_label_73 +mips_label_74: +bnez $a1, mips_label_75 li $v0, 1 -mips_label_85: +mips_label_73: sw $v0, 56($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_13 to $t0 @@ -1673,41 +1593,25 @@ sw $s0, 64($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_15 to $s1 lw $s1, 64($fp) -move $t0, $s0 -li $t1, 0 -mips_label_95: -lb $t3, 0($t0) -beqz $t3, mips_label_96 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_95 -mips_label_96: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_97: -lb $t3, 0($t0) -beqz $t3, mips_label_98 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_97 -mips_label_98: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_92 -move $s2, $s0 -move $s3, $s1 -mips_label_94: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_92 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_93 -j mips_label_94 -mips_label_93: +move $t8, $s0 +move $t9, $s1 +mips_label_80: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_78 +beqz $a1, mips_label_79 +seq $v0, $a0, $a1 +beqz $v0, mips_label_79 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_80 +mips_label_79: +li $v0, 0 +j mips_label_77 +mips_label_78: +bnez $a1, mips_label_79 li $v0, 1 -mips_label_92: +mips_label_77: sw $v0, 68($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_16 to $t0 @@ -1721,41 +1625,25 @@ sw $s0, 76($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_18 to $s1 lw $s1, 76($fp) -move $t0, $s0 -li $t1, 0 -mips_label_102: -lb $t3, 0($t0) -beqz $t3, mips_label_103 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_102 -mips_label_103: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_104: -lb $t3, 0($t0) -beqz $t3, mips_label_105 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_104 -mips_label_105: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_99 -move $s2, $s0 -move $s3, $s1 -mips_label_101: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_99 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_100 -j mips_label_101 -mips_label_100: +move $t8, $s0 +move $t9, $s1 +mips_label_84: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_82 +beqz $a1, mips_label_83 +seq $v0, $a0, $a1 +beqz $v0, mips_label_83 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_84 +mips_label_83: +li $v0, 0 +j mips_label_81 +mips_label_82: +bnez $a1, mips_label_83 li $v0, 1 -mips_label_99: +mips_label_81: sw $v0, 80($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_19 to $t0 @@ -1769,41 +1657,25 @@ sw $s0, 88($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_21 to $s1 lw $s1, 88($fp) -move $t0, $s0 -li $t1, 0 -mips_label_109: -lb $t3, 0($t0) -beqz $t3, mips_label_110 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_109 -mips_label_110: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_111: -lb $t3, 0($t0) -beqz $t3, mips_label_112 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_111 -mips_label_112: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_106 -move $s2, $s0 -move $s3, $s1 -mips_label_108: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_106 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_107 -j mips_label_108 -mips_label_107: +move $t8, $s0 +move $t9, $s1 +mips_label_88: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_86 +beqz $a1, mips_label_87 +seq $v0, $a0, $a1 +beqz $v0, mips_label_87 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_88 +mips_label_87: +li $v0, 0 +j mips_label_85 +mips_label_86: +bnez $a1, mips_label_87 li $v0, 1 -mips_label_106: +mips_label_85: sw $v0, 92($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_22 to $t0 @@ -1817,41 +1689,25 @@ sw $s0, 100($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_24 to $s1 lw $s1, 100($fp) -move $t0, $s0 -li $t1, 0 -mips_label_116: -lb $t3, 0($t0) -beqz $t3, mips_label_117 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_116 -mips_label_117: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_118: -lb $t3, 0($t0) -beqz $t3, mips_label_119 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_118 -mips_label_119: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_113 -move $s2, $s0 -move $s3, $s1 -mips_label_115: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_113 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_114 -j mips_label_115 -mips_label_114: +move $t8, $s0 +move $t9, $s1 +mips_label_92: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_90 +beqz $a1, mips_label_91 +seq $v0, $a0, $a1 +beqz $v0, mips_label_91 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_92 +mips_label_91: +li $v0, 0 +j mips_label_89 +mips_label_90: +bnez $a1, mips_label_91 li $v0, 1 -mips_label_113: +mips_label_89: sw $v0, 104($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_25 to $t0 @@ -1865,41 +1721,25 @@ sw $s0, 112($fp) lw $s0, 8($fp) # Load from local_c2i_at_A2I_internal_27 to $s1 lw $s1, 112($fp) -move $t0, $s0 -li $t1, 0 -mips_label_123: -lb $t3, 0($t0) -beqz $t3, mips_label_124 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_123 -mips_label_124: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_125: -lb $t3, 0($t0) -beqz $t3, mips_label_126 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_125 -mips_label_126: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_120 -move $s2, $s0 -move $s3, $s1 -mips_label_122: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_120 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_121 -j mips_label_122 -mips_label_121: +move $t8, $s0 +move $t9, $s1 +mips_label_96: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_94 +beqz $a1, mips_label_95 +seq $v0, $a0, $a1 +beqz $v0, mips_label_95 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_96 +mips_label_95: +li $v0, 0 +j mips_label_93 +mips_label_94: +bnez $a1, mips_label_95 li $v0, 1 -mips_label_120: +mips_label_93: sw $v0, 116($fp) # IfGotoNode # Load from local_c2i_at_A2I_internal_28 to $t0 @@ -2532,41 +2372,25 @@ sw $s0, 32($fp) lw $s0, 20($fp) # Load from local_a2i_at_A2I_internal_7 to $s1 lw $s1, 32($fp) -move $t0, $s0 -li $t1, 0 -mips_label_130: -lb $t3, 0($t0) -beqz $t3, mips_label_131 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_130 -mips_label_131: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_132: -lb $t3, 0($t0) -beqz $t3, mips_label_133 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_132 -mips_label_133: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_127 -move $s2, $s0 -move $s3, $s1 -mips_label_129: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_127 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_128 -j mips_label_129 -mips_label_128: +move $t8, $s0 +move $t9, $s1 +mips_label_100: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_98 +beqz $a1, mips_label_99 +seq $v0, $a0, $a1 +beqz $v0, mips_label_99 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_100 +mips_label_99: +li $v0, 0 +j mips_label_97 +mips_label_98: +bnez $a1, mips_label_99 li $v0, 1 -mips_label_127: +mips_label_97: sw $v0, 36($fp) # IfGotoNode # Load from local_a2i_at_A2I_internal_8 to $t0 @@ -2609,41 +2433,25 @@ sw $s0, 56($fp) lw $s0, 44($fp) # Load from local_a2i_at_A2I_internal_13 to $s1 lw $s1, 56($fp) -move $t0, $s0 -li $t1, 0 -mips_label_137: -lb $t3, 0($t0) -beqz $t3, mips_label_138 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_137 -mips_label_138: -move $s2, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_139: -lb $t3, 0($t0) -beqz $t3, mips_label_140 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_139 -mips_label_140: -move $s3, $t1 -move $v0, $zero -bne $s2, $s3, mips_label_134 -move $s2, $s0 -move $s3, $s1 -mips_label_136: -lb $s4, 0($s2) -lb $s5, 0($s3) -bne $s4, $s5, mips_label_134 -addi $s2, $s2, 1 -addi $s3, $s3, 1 -beqz $s4, mips_label_135 -j mips_label_136 -mips_label_135: +move $t8, $s0 +move $t9, $s1 +mips_label_104: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_102 +beqz $a1, mips_label_103 +seq $v0, $a0, $a1 +beqz $v0, mips_label_103 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_104 +mips_label_103: +li $v0, 0 +j mips_label_101 +mips_label_102: +bnez $a1, mips_label_103 li $v0, 1 -mips_label_134: +mips_label_101: sw $v0, 60($fp) # IfGotoNode # Load from local_a2i_at_A2I_internal_14 to $t0 From d324b660d8e18052c632c1f60ee16ee11bf7c5d6 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 16 Dec 2020 11:25:02 -0500 Subject: [PATCH 137/191] ctor fixed --- src/engine/codegen/to_cil.py | 7 +- src/test.cl | 202 +- src/test.mips | 3890 ++++------------------------------ 3 files changed, 528 insertions(+), 3571 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 7f9b5ce0..a6be26f4 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -72,11 +72,12 @@ def save_attr_initializations(self, node: cool.ProgramNode, scope): def create_constructor(self, attr_declarations: List[cool.AttrDeclarationNode], type_name): self.current_function = self.register_function(f'ctor_{type_name}') + print(self.current_function.name) self.current_type = self.context.get_type(type_name) instance = self.register_param(VariableInfo('self', self.current_type)) - + print(self.current_type.name) scope = Scope() - scope.define_variable('self', instance) + scope.define_variable('self', self.current_type.name) for attr in attr_declarations: self.visit(attr, scope, typex=self.current_type.name) @@ -167,6 +168,7 @@ def visit(self, node: cool.AttrDeclarationNode, scope: Scope, typex): result = self.define_internal_local() self.register_instruction(VoidNode(result)) self_inst = scope.find_variable('self').name + print(scope) self.register_instruction( SetAttribNode(self_inst, node.id.lex, result, typex)) @@ -239,7 +241,6 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(IfGotoNode(cond, continue_label.label)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) - print(node.body) self.visit(node.body, while_scope) label_counter = self.label_counter_gen() self.register_instruction(GotoNode(start_label.label)) diff --git a/src/test.cl b/src/test.cl index f4125a2f..7f0de869 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,121 +1,103 @@ (* - The class A2I provides integer-to-string and string-to-integer -conversion routines. To use these routines, either inherit them -in the class where needed, have a dummy variable bound to -something of type A2I, or simpl write (new A2I).method(argument). -*) + * 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. + * + *) -(* - c2i Converts a 1-character string to an integer. Aborts - if the string is not "0" through "9" -*) -class A2I { - - c2i(char : String) : Int { - if char = "0" then 0 else - if char = "1" then 1 else - if char = "2" then 2 else - if char = "3" then 3 else - if char = "4" then 4 else - if char = "5" then 5 else - if char = "6" then 6 else - if char = "7" then 7 else - if char = "8" then 8 else - if char = "9" then 9 else - { abort(); 0; } -- the 0 is needed to satisfy the typchecker - fi fi fi fi fi fi fi fi fi fi - }; +class A { -(* - i2c is the inverse of c2i. -*) - i2c(i : Int) : String { - if i = 0 then "0" else - if i = 1 then "1" else - if i = 2 then "2" else - if i = 3 then "3" else - if i = 4 then "4" else - if i = 5 then "5" else - if i = 6 then "6" else - if i = 7 then "7" else - if i = 8 then "8" else - if i = 9 then "9" else - { abort(); ""; } -- the "" is needed to satisfy the typchecker - fi fi fi fi fi fi fi fi fi fi - }; + -- Let's assume that we don't want A to not inherit from IO. -(* - a2i converts an ASCII string into an integer. The empty string -is converted to 0. Signed and unsigned strings are handled. The -method aborts if the string does not represent an integer. Very -long strings of digits produce strange answers because of arithmetic -overflow. - -*) - a2i(s : String) : Int { - if s.length() = 0 then 0 else - if s.substr(0,1) = "-" then ~a2i_aux(s.substr(1,s.length()-1)) else - if s.substr(0,1) = "+" then a2i_aux(s.substr(1,s.length()-1)) else - a2i_aux(s) - fi fi fi - }; + io : IO <- new IO; -(* - a2i_aux converts the usigned portion of the string. As a programming -example, this method is written iteratively. -*) - a2i_aux(s : String) : Int { - (let int : Int <- 0 in - { - (let j : Int <- s.length() in - (let i : Int <- 0 in - while i < j loop - { - int <- int * 10 + c2i(s.substr(i,1)); - i <- i + 1; - } - pool - ) - ); - int; - } - ) - }; + out_a() : Object { io.out_string("A: Hello world\n") }; + +}; -(* - i2a converts an integer to a string. Positive and negative -numbers are handled correctly. -*) - i2a(i : Int) : String { - if i = 0 then "0" else - if 0 < i then i2a_aux(i) else - "-".concat(i2a_aux(i * ~1)) - fi fi - }; - -(* - i2a_aux is an example using recursion. -*) - i2a_aux(i : Int) : String { - if i = 0 then "" else - (let next : Int <- i / 10 in - i2a_aux(next).concat(i2c(i - next * 10)) - ) - fi - }; + +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 () : Object { - let a : Int <- (new A2I).a2i("678987"), - b : String <- (new A2I).i2a(678987) in - { - out_int(a) ; - out_string(" == ") ; - out_string(b) ; - out_string("\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 69e2d5de..a1a46134 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,3459 +1,433 @@ -.data -classname_Object: -.asciiz "Object" -classname_String: -.asciiz "String" -classname_IO: -.asciiz "IO" -classname_Int: -.asciiz "Int" -classname_Bool: -.asciiz "Bool" -classname_A2I: -.asciiz "A2I" -classname_Main: -.asciiz "Main" -data_0: -.asciiz "Abort called from class " -data_1: -.asciiz "\n" -data_2: -.asciiz "Invalid substring start" -data_3: -.asciiz "Invalid substring length" -data_4: -.asciiz "Invalid substring" -data_5: -.asciiz "0" -data_6: -.asciiz "1" -data_7: -.asciiz "2" -data_8: -.asciiz "3" -data_9: -.asciiz "4" -data_10: -.asciiz "5" -data_11: -.asciiz "6" -data_12: -.asciiz "7" -data_13: -.asciiz "8" -data_14: -.asciiz "9" -data_15: -.asciiz "" -data_16: -.asciiz "-" -data_17: -.asciiz "+" -data_18: -.asciiz "678987" -data_19: -.asciiz " == " -data_20: -.asciiz " +.TYPES +type Object { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type String { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method length: function_length_at_String + method concat: function_concat_at_String + method substr: function_substr_at_String +} +type IO { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO +} +type Int { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type Bool { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type A { + attribute io + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_a: function_out_a_at_A +} +type C { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method out_c: function_out_c_at_C +} +type Main { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method main: function_main_at_Main +} +type B { + attribute io + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_a: function_out_a_at_A + method out_b: function_out_b_at_B +} +type D { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method out_c: function_out_c_at_C + method out_d: function_out_d_at_D +} + +.DATA +data_0 = "Abort called from class " +data_1 = "\n" +data_2 = "Invalid substring start" +data_3 = "Invalid substring length" +data_4 = "Invalid substring" +data_5 = "A: Hello world " -.text -main: -# Allocate Vtable -li $a0, 156 -li $v0, 9 -syscall -move $s7, $v0 -# Build VTable -la $s0, function_abort_at_Object -sw $s0, 0($s7) -la $s0, function_type_name_at_Object -sw $s0, 4($s7) -la $s0, function_copy_at_Object -sw $s0, 8($s7) -la $s0, function_abort_at_Object -sw $s0, 12($s7) -la $s0, function_type_name_at_Object -sw $s0, 16($s7) -la $s0, function_copy_at_Object -sw $s0, 20($s7) -la $s0, function_length_at_String -sw $s0, 24($s7) -la $s0, function_concat_at_String -sw $s0, 28($s7) -la $s0, function_substr_at_String -sw $s0, 32($s7) -la $s0, function_abort_at_Object -sw $s0, 36($s7) -la $s0, function_type_name_at_Object -sw $s0, 40($s7) -la $s0, function_copy_at_Object -sw $s0, 44($s7) -la $s0, function_out_string_at_IO -sw $s0, 48($s7) -la $s0, function_out_int_at_IO -sw $s0, 52($s7) -la $s0, function_in_string_at_IO -sw $s0, 56($s7) -la $s0, function_in_int_at_IO -sw $s0, 60($s7) -la $s0, function_abort_at_Object -sw $s0, 64($s7) -la $s0, function_type_name_at_Object -sw $s0, 68($s7) -la $s0, function_copy_at_Object -sw $s0, 72($s7) -la $s0, function_abort_at_Object -sw $s0, 76($s7) -la $s0, function_type_name_at_Object -sw $s0, 80($s7) -la $s0, function_copy_at_Object -sw $s0, 84($s7) -la $s0, function_abort_at_Object -sw $s0, 88($s7) -la $s0, function_type_name_at_Object -sw $s0, 92($s7) -la $s0, function_copy_at_Object -sw $s0, 96($s7) -la $s0, function_c2i_at_A2I -sw $s0, 100($s7) -la $s0, function_i2c_at_A2I -sw $s0, 104($s7) -la $s0, function_a2i_at_A2I -sw $s0, 108($s7) -la $s0, function_a2i_aux_at_A2I -sw $s0, 112($s7) -la $s0, function_i2a_at_A2I -sw $s0, 116($s7) -la $s0, function_i2a_aux_at_A2I -sw $s0, 120($s7) -la $s0, function_abort_at_Object -sw $s0, 124($s7) -la $s0, function_type_name_at_Object -sw $s0, 128($s7) -la $s0, function_copy_at_Object -sw $s0, 132($s7) -la $s0, function_out_string_at_IO -sw $s0, 136($s7) -la $s0, function_out_int_at_IO -sw $s0, 140($s7) -la $s0, function_in_string_at_IO -sw $s0, 144($s7) -la $s0, function_in_int_at_IO -sw $s0, 148($s7) -la $s0, function_main_at_Main -sw $s0, 152($s7) -jal entry - -li $v0, 10 -syscall -function_abort_at_Object: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -12 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# TypeNameNode -# Load from self to $t0 -lw $t0, 4($fp) -lw $t1, 4($t0) -sw $t1, 4($fp) -# Load from data_0 to $s0 -la $s0, data_0 -# Load from local_abort_at_Object_internal_0 to $s1 -lw $s1, 4($fp) -move $t0, $s0 -li $t1, 0 -mips_label_1: -lb $t3, 0($t0) -beqz $t3, mips_label_2 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_1 -mips_label_2: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_3: -lb $t3, 0($t0) -beqz $t3, mips_label_4 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_3 -mips_label_4: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_5: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_6 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_5 -mips_label_6: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_7: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_8 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_7 -mips_label_8: -move $v0, $t1 -sw $s3, 8($fp) -# Load from local_abort_at_Object_internal_1 to $s0 -lw $s0, 8($fp) -# Load from data_1 to $s1 -la $s1, data_1 -move $t0, $s0 -li $t1, 0 -mips_label_9: -lb $t3, 0($t0) -beqz $t3, mips_label_10 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_9 -mips_label_10: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_11: -lb $t3, 0($t0) -beqz $t3, mips_label_12 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_11 -mips_label_12: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_13: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_14 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_13 -mips_label_14: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_15: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_16 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_15 -mips_label_16: -move $v0, $t1 -sw $s3, 12($fp) -# Print str local_abort_at_Object_internal_2 -# Load from local_abort_at_Object_internal_2 to $a0 -lw $a0, 12($fp) -li $v0, 4 -syscall -li $v0, 10 -syscall - - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 12 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_copy_at_Object: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -4 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -la $s1, -4($fp) -li $s3, 0 -move $t0, $s0 -move $t1, $s1 -move $t3, $s3 -mips_label_17: -lb $t2, 0($t0) -sb $t2, 0($t1) -addi $t0, $t0, 2 -addi $t1, $t1, 2 -addi $t3, $t3, -1 -beqz $t3, mips_label_18 -j mips_label_17 -mips_label_18: -# ReturnNode -# Load from local_copy_at_Object_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 4 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_type_name_at_Object: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# TypeOfNode of self -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 3($s0) -sw $s1, 8($fp) -# TypeNameNode -# Load from local_type_name_at_Object_internal_1 to $t0 -lw $t0, 8($fp) -lw $t1, 4($t0) -sw $t1, 4($fp) -# ReturnNode -# Load from local_type_name_at_Object_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_length_at_String: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -4 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# LengthNode -# Load from self to $s1 -lw $s1, 4($fp) -move $t0, $s1 -li $t1, 0 -mips_label_19: -lb $t3, 0($t0) -beqz $t3, mips_label_20 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_19 -mips_label_20: -move $s0, $t1 -sw $s0, 4($fp) -# ReturnNode -# Load from local_length_at_String_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 4 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_concat_at_String: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -4 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Load from self to $s0 -lw $s0, 4($fp) -# Load from string to $s1 -lw $s1, 8($fp) -move $t0, $s0 -li $t1, 0 -mips_label_21: -lb $t3, 0($t0) -beqz $t3, mips_label_22 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_21 -mips_label_22: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_23: -lb $t3, 0($t0) -beqz $t3, mips_label_24 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_23 -mips_label_24: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_25: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_26 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_25 -mips_label_26: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_27: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_28 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_27 -mips_label_28: -move $v0, $t1 -sw $s3, 4($fp) -# ReturnNode -# Load from local_concat_at_String_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 4 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_substr_at_String: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -36 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -sw $s0, 16($fp) -# LengthNode -# Load from self to $s1 -lw $s1, 4($fp) -move $t0, $s1 -li $t1, 0 -mips_label_29: -lb $t3, 0($t0) -beqz $t3, mips_label_30 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_29 -mips_label_30: -move $s0, $t1 -sw $s0, 12($fp) -# Load from local_substr_at_String_internal_3 to $t0 -lw $t0, 16($fp) -# Load from start to $t1 -lw $t1, 8($fp) -slt $t2, $t1, $t0 -li $t3, 1 -sub $t0, $t3, $t2 -sw $t0, 24($fp) -# IfGotoNode -# Load from local_substr_at_String_internal_5 to $t0 -lw $t0, 24($fp) -li $t1, 0 -bne $t0, $t1, error1 -# Load from data_2 to $s0 -la $s0, data_2 -# Load from data_1 to $s1 -la $s1, data_1 -move $t0, $s0 -li $t1, 0 -mips_label_31: -lb $t3, 0($t0) -beqz $t3, mips_label_32 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_31 -mips_label_32: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_33: -lb $t3, 0($t0) -beqz $t3, mips_label_34 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_33 -mips_label_34: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_35: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_36 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_35 -mips_label_36: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_37: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_38 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_37 -mips_label_38: -move $v0, $t1 -sw $s3, 36($fp) -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) -li $v0, 4 -syscall -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall -error1: -# Load from local_substr_at_String_internal_3 to $t0 -lw $t0, 16($fp) -# Load from length to $t1 -lw $t1, 12($fp) -slt $t2, $t1, $t0 -li $t3, 1 -sub $t0, $t3, $t2 -sw $t0, 28($fp) -# IfGotoNode -# Load from local_substr_at_String_internal_6 to $t0 -lw $t0, 28($fp) -li $t1, 0 -bne $t0, $t1, error2 -# Load from data_3 to $s0 -la $s0, data_3 -# Load from data_1 to $s1 -la $s1, data_1 -move $t0, $s0 -li $t1, 0 -mips_label_39: -lb $t3, 0($t0) -beqz $t3, mips_label_40 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_39 -mips_label_40: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_41: -lb $t3, 0($t0) -beqz $t3, mips_label_42 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_41 -mips_label_42: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_43: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_44 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_43 -mips_label_44: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_45: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_46 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_45 -mips_label_46: -move $v0, $t1 -sw $s3, 36($fp) -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) -li $v0, 4 -syscall -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall -error2: -# Load from start to $t0 -lw $t0, 8($fp) -# Load from length to $t1 -lw $t1, 12($fp) -add $t2, $t0, $t1 -sw $t2, 20($fp) -# Load from local_substr_at_String_internal_4 to $t0 -lw $t0, 20($fp) -# Load from local_substr_at_String_internal_2 to $t1 -lw $t1, 12($fp) -slt $t2, $t1, $t0 -li $t3, 1 -sub $t0, $t3, $t2 -sw $t0, 32($fp) -# IfGotoNode -# Load from local_substr_at_String_internal_7 to $t0 -lw $t0, 32($fp) -li $t1, 0 -bne $t0, $t1, error3 -# Load from data_4 to $s0 -la $s0, data_4 -# Load from data_1 to $s1 -la $s1, data_1 -move $t0, $s0 -li $t1, 0 -mips_label_47: -lb $t3, 0($t0) -beqz $t3, mips_label_48 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_47 -mips_label_48: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_49: -lb $t3, 0($t0) -beqz $t3, mips_label_50 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_49 -mips_label_50: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_51: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_52 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_51 -mips_label_52: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_53: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_54 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_53 -mips_label_54: -move $v0, $t1 -sw $s3, 36($fp) -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) -li $v0, 4 -syscall -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall -error3: -# Load from self to $s0 -lw $s0, 4($fp) -# Load from length to $s1 -lw $s1, 12($fp) -# Load from start to $s3 -lw $s3, 8($fp) -add $s0, $s0, $s3 -move $a0, $s1 -li $v0, 9 -syscall -move $t0, $s0 -move $t1, $v0 -move $t3, $s1 -mips_label_55: -lb $t2, 0($t0) -sb $t2, 0($t1) -addi $t0, $t0, 1 -addi $t1, $t1, 1 -addi $t3, $t3, -1 -beqz $t3, mips_label_56 -j mips_label_55 -mips_label_56: -move $t2, $zero -sb $t2, 0($t1) -sw $v0, 4($fp) -# ReturnNode -# Load from local_substr_at_String_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 36 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_out_string_at_IO: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, 0 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Print str str_val -# Load from str_val to $a0 -lw $a0, 8($fp) -li $v0, 4 -syscall -# ReturnNode -# Load from self to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_in_string_at_IO: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -4 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $a0, 1024 -li $v0, 9 -syscall -move $a0, $v0 -sw $v0, 4($fp) -li $a1, 1024 -li $v0, 8 -syscall -# ReturnNode -# Load from local_in_string_at_IO_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 4 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_out_int_at_IO: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, 0 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Load from int_val to $a0 -lw $a0, 8($fp) -li $v0, 1 -syscall -# ReturnNode -# Load from self to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_in_int_at_IO: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -4 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $v0, 5 -syscall -sw $v0, 4($fp) -# ReturnNode -# Load from local_in_int_at_IO_internal_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 4 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -ctor_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, 0 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# ReturnNode -# Load from self to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -ctor_Main: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, 0 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# ReturnNode -# Load from self to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -entry: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -8 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Allocate space for Main -li $a0, 16 -li $v0, 9 -syscall -move $s1, $v0 -sw $s1, 4($fp) -li $s0, 0 -sw $s0, 0($s1) -li $s0, 16 -sw $s0, 4($s1) -la $s0, classname_Main -sw $s0, 8($s1) -li $s0, 124 -sw $s0, 12($s1) -# ArgNode local__internal_0 to s0 -# Load from local__internal_0 to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# StaticCallNode -jal function_main_at_Main -sw $v0, 8($fp) -addi $sp, $sp, 4 - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 8 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_c2i_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -168 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Load from data_5 to $s0 -la $s0, data_5 -sw $s0, 4($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_0 to $s1 -lw $s1, 4($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_60: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_58 -beqz $a1, mips_label_59 -seq $v0, $a0, $a1 -beqz $v0, mips_label_59 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_60 -mips_label_59: -li $v0, 0 -j mips_label_57 -mips_label_58: -bnez $a1, mips_label_59 -li $v0, 1 -mips_label_57: -sw $v0, 8($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_1 -# Load from data_6 to $s0 -la $s0, data_6 -sw $s0, 16($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_3 to $s1 -lw $s1, 16($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_64: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_62 -beqz $a1, mips_label_63 -seq $v0, $a0, $a1 -beqz $v0, mips_label_63 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_64 -mips_label_63: -li $v0, 0 -j mips_label_61 -mips_label_62: -bnez $a1, mips_label_63 -li $v0, 1 -mips_label_61: -sw $v0, 20($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) -li $t1, 0 -bne $t0, $t1, TRUE_2 -# Load from data_7 to $s0 -la $s0, data_7 -sw $s0, 28($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_6 to $s1 -lw $s1, 28($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_68: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_66 -beqz $a1, mips_label_67 -seq $v0, $a0, $a1 -beqz $v0, mips_label_67 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_68 -mips_label_67: -li $v0, 0 -j mips_label_65 -mips_label_66: -bnez $a1, mips_label_67 -li $v0, 1 -mips_label_65: -sw $v0, 32($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) -li $t1, 0 -bne $t0, $t1, TRUE_3 -# Load from data_8 to $s0 -la $s0, data_8 -sw $s0, 40($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_9 to $s1 -lw $s1, 40($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_72: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_70 -beqz $a1, mips_label_71 -seq $v0, $a0, $a1 -beqz $v0, mips_label_71 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_72 -mips_label_71: -li $v0, 0 -j mips_label_69 -mips_label_70: -bnez $a1, mips_label_71 -li $v0, 1 -mips_label_69: -sw $v0, 44($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) -li $t1, 0 -bne $t0, $t1, TRUE_4 -# Load from data_9 to $s0 -la $s0, data_9 -sw $s0, 52($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_12 to $s1 -lw $s1, 52($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_76: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_74 -beqz $a1, mips_label_75 -seq $v0, $a0, $a1 -beqz $v0, mips_label_75 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_76 -mips_label_75: -li $v0, 0 -j mips_label_73 -mips_label_74: -bnez $a1, mips_label_75 -li $v0, 1 -mips_label_73: -sw $v0, 56($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -li $t1, 0 -bne $t0, $t1, TRUE_5 -# Load from data_10 to $s0 -la $s0, data_10 -sw $s0, 64($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_15 to $s1 -lw $s1, 64($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_80: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_78 -beqz $a1, mips_label_79 -seq $v0, $a0, $a1 -beqz $v0, mips_label_79 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_80 -mips_label_79: -li $v0, 0 -j mips_label_77 -mips_label_78: -bnez $a1, mips_label_79 -li $v0, 1 -mips_label_77: -sw $v0, 68($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) -li $t1, 0 -bne $t0, $t1, TRUE_6 -# Load from data_11 to $s0 -la $s0, data_11 -sw $s0, 76($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_18 to $s1 -lw $s1, 76($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_84: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_82 -beqz $a1, mips_label_83 -seq $v0, $a0, $a1 -beqz $v0, mips_label_83 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_84 -mips_label_83: -li $v0, 0 -j mips_label_81 -mips_label_82: -bnez $a1, mips_label_83 -li $v0, 1 -mips_label_81: -sw $v0, 80($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_19 to $t0 -lw $t0, 80($fp) -li $t1, 0 -bne $t0, $t1, TRUE_7 -# Load from data_12 to $s0 -la $s0, data_12 -sw $s0, 88($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_21 to $s1 -lw $s1, 88($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_88: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_86 -beqz $a1, mips_label_87 -seq $v0, $a0, $a1 -beqz $v0, mips_label_87 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_88 -mips_label_87: -li $v0, 0 -j mips_label_85 -mips_label_86: -bnez $a1, mips_label_87 -li $v0, 1 -mips_label_85: -sw $v0, 92($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_22 to $t0 -lw $t0, 92($fp) -li $t1, 0 -bne $t0, $t1, TRUE_8 -# Load from data_13 to $s0 -la $s0, data_13 -sw $s0, 100($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_24 to $s1 -lw $s1, 100($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_92: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_90 -beqz $a1, mips_label_91 -seq $v0, $a0, $a1 -beqz $v0, mips_label_91 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_92 -mips_label_91: -li $v0, 0 -j mips_label_89 -mips_label_90: -bnez $a1, mips_label_91 -li $v0, 1 -mips_label_89: -sw $v0, 104($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_25 to $t0 -lw $t0, 104($fp) -li $t1, 0 -bne $t0, $t1, TRUE_9 -# Load from data_14 to $s0 -la $s0, data_14 -sw $s0, 112($fp) -# Load from char to $s0 -lw $s0, 8($fp) -# Load from local_c2i_at_A2I_internal_27 to $s1 -lw $s1, 112($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_96: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_94 -beqz $a1, mips_label_95 -seq $v0, $a0, $a1 -beqz $v0, mips_label_95 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_96 -mips_label_95: -li $v0, 0 -j mips_label_93 -mips_label_94: -bnez $a1, mips_label_95 -li $v0, 1 -mips_label_93: -sw $v0, 116($fp) -# IfGotoNode -# Load from local_c2i_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) -li $t1, 0 -bne $t0, $t1, TRUE_10 -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I abort -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 0 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 124($fp) -addi $sp, $sp, 4 -li $s0, 0 -sw $s0, 128($fp) -# Load from local_c2i_at_A2I_internal_31 to $t0 -lw $t0, 128($fp) -sw $t0, 120($fp) -# GotoNode -j END_10 -TRUE_10: -li $s0, 9 -sw $s0, 132($fp) -# Load from local_c2i_at_A2I_internal_32 to $t0 -lw $t0, 132($fp) -sw $t0, 120($fp) -END_10: -# Load from local_c2i_at_A2I_internal_29 to $t0 -lw $t0, 120($fp) -sw $t0, 108($fp) -# GotoNode -j END_9 -TRUE_9: -li $s0, 8 -sw $s0, 136($fp) -# Load from local_c2i_at_A2I_internal_33 to $t0 -lw $t0, 136($fp) -sw $t0, 108($fp) -END_9: -# Load from local_c2i_at_A2I_internal_26 to $t0 -lw $t0, 108($fp) -sw $t0, 96($fp) -# GotoNode -j END_8 -TRUE_8: -li $s0, 7 -sw $s0, 140($fp) -# Load from local_c2i_at_A2I_internal_34 to $t0 -lw $t0, 140($fp) -sw $t0, 96($fp) -END_8: -# Load from local_c2i_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 84($fp) -# GotoNode -j END_7 -TRUE_7: -li $s0, 6 -sw $s0, 144($fp) -# Load from local_c2i_at_A2I_internal_35 to $t0 -lw $t0, 144($fp) -sw $t0, 84($fp) -END_7: -# Load from local_c2i_at_A2I_internal_20 to $t0 -lw $t0, 84($fp) -sw $t0, 72($fp) -# GotoNode -j END_6 -TRUE_6: -li $s0, 5 -sw $s0, 148($fp) -# Load from local_c2i_at_A2I_internal_36 to $t0 -lw $t0, 148($fp) -sw $t0, 72($fp) -END_6: -# Load from local_c2i_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 60($fp) -# GotoNode -j END_5 -TRUE_5: -li $s0, 4 -sw $s0, 152($fp) -# Load from local_c2i_at_A2I_internal_37 to $t0 -lw $t0, 152($fp) -sw $t0, 60($fp) -END_5: -# Load from local_c2i_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) -sw $t0, 48($fp) -# GotoNode -j END_4 -TRUE_4: -li $s0, 3 -sw $s0, 156($fp) -# Load from local_c2i_at_A2I_internal_38 to $t0 -lw $t0, 156($fp) -sw $t0, 48($fp) -END_4: -# Load from local_c2i_at_A2I_internal_11 to $t0 -lw $t0, 48($fp) -sw $t0, 36($fp) -# GotoNode -j END_3 -TRUE_3: -li $s0, 2 -sw $s0, 160($fp) -# Load from local_c2i_at_A2I_internal_39 to $t0 -lw $t0, 160($fp) -sw $t0, 36($fp) -END_3: -# Load from local_c2i_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -sw $t0, 24($fp) -# GotoNode -j END_2 -TRUE_2: -li $s0, 1 -sw $s0, 164($fp) -# Load from local_c2i_at_A2I_internal_40 to $t0 -lw $t0, 164($fp) -sw $t0, 24($fp) -END_2: -# Load from local_c2i_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) -# GotoNode -j END_1 -TRUE_1: -li $s0, 0 -sw $s0, 168($fp) -# Load from local_c2i_at_A2I_internal_41 to $t0 -lw $t0, 168($fp) -sw $t0, 12($fp) -END_1: -# ReturnNode -# Load from local_c2i_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 168 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2c_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -168 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -sw $s0, 4($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 8($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_21 -li $s0, 1 -sw $s0, 16($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_3 to $t1 -lw $t1, 16($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 20($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) -li $t1, 0 -bne $t0, $t1, TRUE_22 -li $s0, 2 -sw $s0, 28($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_6 to $t1 -lw $t1, 28($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 32($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) -li $t1, 0 -bne $t0, $t1, TRUE_23 -li $s0, 3 -sw $s0, 40($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 44($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) -li $t1, 0 -bne $t0, $t1, TRUE_24 -li $s0, 4 -sw $s0, 52($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_12 to $t1 -lw $t1, 52($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 56($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -li $t1, 0 -bne $t0, $t1, TRUE_25 -li $s0, 5 -sw $s0, 64($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_15 to $t1 -lw $t1, 64($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 68($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) -li $t1, 0 -bne $t0, $t1, TRUE_26 -li $s0, 6 -sw $s0, 76($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_18 to $t1 -lw $t1, 76($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 80($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_19 to $t0 -lw $t0, 80($fp) -li $t1, 0 -bne $t0, $t1, TRUE_27 -li $s0, 7 -sw $s0, 88($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_21 to $t1 -lw $t1, 88($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 92($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_22 to $t0 -lw $t0, 92($fp) -li $t1, 0 -bne $t0, $t1, TRUE_28 -li $s0, 8 -sw $s0, 100($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_24 to $t1 -lw $t1, 100($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 104($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_25 to $t0 -lw $t0, 104($fp) -li $t1, 0 -bne $t0, $t1, TRUE_29 -li $s0, 9 -sw $s0, 112($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_27 to $t1 -lw $t1, 112($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 116($fp) -# IfGotoNode -# Load from local_i2c_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) -li $t1, 0 -bne $t0, $t1, TRUE_30 -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I abort -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 0 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 124($fp) -addi $sp, $sp, 4 -# Load from data_15 to $s0 -la $s0, data_15 -sw $s0, 128($fp) -# Load from local_i2c_at_A2I_internal_31 to $t0 -lw $t0, 128($fp) -sw $t0, 120($fp) -# GotoNode -j END_30 -TRUE_30: -# Load from data_14 to $s0 -la $s0, data_14 -sw $s0, 132($fp) -# Load from local_i2c_at_A2I_internal_32 to $t0 -lw $t0, 132($fp) -sw $t0, 120($fp) -END_30: -# Load from local_i2c_at_A2I_internal_29 to $t0 -lw $t0, 120($fp) -sw $t0, 108($fp) -# GotoNode -j END_29 -TRUE_29: -# Load from data_13 to $s0 -la $s0, data_13 -sw $s0, 136($fp) -# Load from local_i2c_at_A2I_internal_33 to $t0 -lw $t0, 136($fp) -sw $t0, 108($fp) -END_29: -# Load from local_i2c_at_A2I_internal_26 to $t0 -lw $t0, 108($fp) -sw $t0, 96($fp) -# GotoNode -j END_28 -TRUE_28: -# Load from data_12 to $s0 -la $s0, data_12 -sw $s0, 140($fp) -# Load from local_i2c_at_A2I_internal_34 to $t0 -lw $t0, 140($fp) -sw $t0, 96($fp) -END_28: -# Load from local_i2c_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 84($fp) -# GotoNode -j END_27 -TRUE_27: -# Load from data_11 to $s0 -la $s0, data_11 -sw $s0, 144($fp) -# Load from local_i2c_at_A2I_internal_35 to $t0 -lw $t0, 144($fp) -sw $t0, 84($fp) -END_27: -# Load from local_i2c_at_A2I_internal_20 to $t0 -lw $t0, 84($fp) -sw $t0, 72($fp) -# GotoNode -j END_26 -TRUE_26: -# Load from data_10 to $s0 -la $s0, data_10 -sw $s0, 148($fp) -# Load from local_i2c_at_A2I_internal_36 to $t0 -lw $t0, 148($fp) -sw $t0, 72($fp) -END_26: -# Load from local_i2c_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 60($fp) -# GotoNode -j END_25 -TRUE_25: -# Load from data_9 to $s0 -la $s0, data_9 -sw $s0, 152($fp) -# Load from local_i2c_at_A2I_internal_37 to $t0 -lw $t0, 152($fp) -sw $t0, 60($fp) -END_25: -# Load from local_i2c_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) -sw $t0, 48($fp) -# GotoNode -j END_24 -TRUE_24: -# Load from data_8 to $s0 -la $s0, data_8 -sw $s0, 156($fp) -# Load from local_i2c_at_A2I_internal_38 to $t0 -lw $t0, 156($fp) -sw $t0, 48($fp) -END_24: -# Load from local_i2c_at_A2I_internal_11 to $t0 -lw $t0, 48($fp) -sw $t0, 36($fp) -# GotoNode -j END_23 -TRUE_23: -# Load from data_7 to $s0 -la $s0, data_7 -sw $s0, 160($fp) -# Load from local_i2c_at_A2I_internal_39 to $t0 -lw $t0, 160($fp) -sw $t0, 36($fp) -END_23: -# Load from local_i2c_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -sw $t0, 24($fp) -# GotoNode -j END_22 -TRUE_22: -# Load from data_6 to $s0 -la $s0, data_6 -sw $s0, 164($fp) -# Load from local_i2c_at_A2I_internal_40 to $t0 -lw $t0, 164($fp) -sw $t0, 24($fp) -END_22: -# Load from local_i2c_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) -# GotoNode -j END_21 -TRUE_21: -# Load from data_5 to $s0 -la $s0, data_5 -sw $s0, 168($fp) -# Load from local_i2c_at_A2I_internal_41 to $t0 -lw $t0, 168($fp) -sw $t0, 12($fp) -END_21: -# ReturnNode -# Load from local_i2c_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 168 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_a2i_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -124 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 4($fp) -addi $sp, $sp, 4 -li $s0, 0 -sw $s0, 8($fp) -# Load from local_a2i_at_A2I_internal_0 to $t0 -lw $t0, 4($fp) -# Load from local_a2i_at_A2I_internal_1 to $t1 -lw $t1, 8($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 12($fp) -# IfGotoNode -# Load from local_a2i_at_A2I_internal_2 to $t0 -lw $t0, 12($fp) -li $t1, 0 -bne $t0, $t1, TRUE_41 -li $s0, 0 -sw $s0, 24($fp) -li $s0, 1 -sw $s0, 28($fp) -# ArgNode local_a2i_at_A2I_internal_6 to s0 -# Load from local_a2i_at_A2I_internal_6 to $s0 -lw $s0, 28($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_5 to s0 -# Load from local_a2i_at_A2I_internal_5 to $s0 -lw $s0, 24($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 20($fp) -addi $sp, $sp, 12 -# Load from data_16 to $s0 -la $s0, data_16 -sw $s0, 32($fp) -# Load from local_a2i_at_A2I_internal_4 to $s0 -lw $s0, 20($fp) -# Load from local_a2i_at_A2I_internal_7 to $s1 -lw $s1, 32($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_100: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_98 -beqz $a1, mips_label_99 -seq $v0, $a0, $a1 -beqz $v0, mips_label_99 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_100 -mips_label_99: -li $v0, 0 -j mips_label_97 -mips_label_98: -bnez $a1, mips_label_99 -li $v0, 1 -mips_label_97: -sw $v0, 36($fp) -# IfGotoNode -# Load from local_a2i_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -li $t1, 0 -bne $t0, $t1, TRUE_42 -li $s0, 0 -sw $s0, 48($fp) -li $s0, 1 -sw $s0, 52($fp) -# ArgNode local_a2i_at_A2I_internal_12 to s0 -# Load from local_a2i_at_A2I_internal_12 to $s0 -lw $s0, 52($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_11 to s0 -# Load from local_a2i_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 44($fp) -addi $sp, $sp, 12 -# Load from data_17 to $s0 -la $s0, data_17 -sw $s0, 56($fp) -# Load from local_a2i_at_A2I_internal_10 to $s0 -lw $s0, 44($fp) -# Load from local_a2i_at_A2I_internal_13 to $s1 -lw $s1, 56($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_104: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_102 -beqz $a1, mips_label_103 -seq $v0, $a0, $a1 -beqz $v0, mips_label_103 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_104 -mips_label_103: -li $v0, 0 -j mips_label_101 -mips_label_102: -bnez $a1, mips_label_103 -li $v0, 1 -mips_label_101: -sw $v0, 60($fp) -# IfGotoNode -# Load from local_a2i_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) -li $t1, 0 -bne $t0, $t1, TRUE_43 -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 68($fp) -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) -sw $t0, 64($fp) -# GotoNode -j END_43 -TRUE_43: -li $s0, 1 -sw $s0, 80($fp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 88($fp) -addi $sp, $sp, 4 -li $s0, 1 -sw $s0, 92($fp) -# Load from local_a2i_at_A2I_internal_21 to $t0 -lw $t0, 88($fp) -# Load from local_a2i_at_A2I_internal_22 to $t1 -lw $t1, 92($fp) -sub $t2, $t0, $t1 -sw $t2, 84($fp) -# ArgNode local_a2i_at_A2I_internal_20 to s0 -# Load from local_a2i_at_A2I_internal_20 to $s0 -lw $s0, 84($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_19 to s0 -# Load from local_a2i_at_A2I_internal_19 to $s0 -lw $s0, 80($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 76($fp) -addi $sp, $sp, 12 -# ArgNode local_a2i_at_A2I_internal_18 to s0 -# Load from local_a2i_at_A2I_internal_18 to $s0 -lw $s0, 76($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 72($fp) -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 64($fp) -END_43: -# Load from local_a2i_at_A2I_internal_15 to $t0 -lw $t0, 64($fp) -sw $t0, 40($fp) -# GotoNode -j END_42 -TRUE_42: -li $s0, 1 -sw $s0, 108($fp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 116($fp) -addi $sp, $sp, 4 -li $s0, 1 -sw $s0, 120($fp) -# Load from local_a2i_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) -# Load from local_a2i_at_A2I_internal_29 to $t1 -lw $t1, 120($fp) -sub $t2, $t0, $t1 -sw $t2, 112($fp) -# ArgNode local_a2i_at_A2I_internal_27 to s0 -# Load from local_a2i_at_A2I_internal_27 to $s0 -lw $s0, 112($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_26 to s0 -# Load from local_a2i_at_A2I_internal_26 to $s0 -lw $s0, 108($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 104($fp) -addi $sp, $sp, 12 -# ArgNode local_a2i_at_A2I_internal_25 to s0 -# Load from local_a2i_at_A2I_internal_25 to $s0 -lw $s0, 104($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 100($fp) -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_24 to $t0 -lw $t0, 100($fp) -nor $t1, $t0, $t0 -sw $t1, 96($fp) -# Load from local_a2i_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 40($fp) -END_42: -# Load from local_a2i_at_A2I_internal_9 to $t0 -lw $t0, 40($fp) -sw $t0, 16($fp) -# GotoNode -j END_41 -TRUE_41: -li $s0, 0 -sw $s0, 124($fp) -# Load from local_a2i_at_A2I_internal_30 to $t0 -lw $t0, 124($fp) -sw $t0, 16($fp) -END_41: -# ReturnNode -# Load from local_a2i_at_A2I_internal_3 to $v0 -lw $v0, 16($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 124 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_a2i_aux_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -60 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -sw $s0, 8($fp) -# Load from local_a2i_aux_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -sw $t0, 4($fp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 16($fp) -addi $sp, $sp, 4 -# Load from local_a2i_aux_at_A2I_internal_3 to $t0 -lw $t0, 16($fp) -sw $t0, 12($fp) -li $s0, 0 -sw $s0, 24($fp) -# Load from local_a2i_aux_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 20($fp) -START_47: -# Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, 20($fp) -# Load from local_a2i_aux_at_A2I_j_2 to $t1 -lw $t1, 12($fp) -slt $t2, $t0, $t1 -sw $t2, 28($fp) -# IfGotoNode -# Load from local_a2i_aux_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) -li $t1, 0 -bne $t0, $t1, CONTINUE_47 -# GotoNode -j END_47 -CONTINUE_47: -li $s0, 10 -sw $s0, 40($fp) -# Load from local_a2i_aux_at_A2I_int_0 to $t0 -lw $t0, 4($fp) -# Load from local_a2i_aux_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) -mult $t0, $t1 -mflo $t0 -sw $t0, 36($fp) -li $s0, 1 -sw $s0, 52($fp) -# ArgNode local_a2i_aux_at_A2I_internal_12 to s0 -# Load from local_a2i_aux_at_A2I_internal_12 to $s0 -lw $s0, 52($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_aux_at_A2I_i_4 to s0 -# Load from local_a2i_aux_at_A2I_i_4 to $s0 -lw $s0, 20($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 48($fp) -addi $sp, $sp, 12 -# ArgNode local_a2i_aux_at_A2I_internal_11 to s0 -# Load from local_a2i_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I c2i -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 44($fp) -addi $sp, $sp, 8 -# Load from local_a2i_aux_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -# Load from local_a2i_aux_at_A2I_internal_10 to $t1 -lw $t1, 44($fp) -add $t2, $t0, $t1 -sw $t2, 32($fp) -# Load from local_a2i_aux_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) -sw $t0, 4($fp) -li $s0, 1 -sw $s0, 60($fp) -# Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, 20($fp) -# Load from local_a2i_aux_at_A2I_internal_14 to $t1 -lw $t1, 60($fp) -add $t2, $t0, $t1 -sw $t2, 56($fp) -# Load from local_a2i_aux_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -sw $t0, 20($fp) -# GotoNode -j START_47 -END_47: -# ReturnNode -# Load from local_a2i_aux_at_A2I_int_0 to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 60 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2a_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -56 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -sw $s0, 4($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 8($fp) -# IfGotoNode -# Load from local_i2a_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_49 -li $s0, 0 -sw $s0, 20($fp) -# Load from local_i2a_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) -# Load from i to $t1 -lw $t1, 8($fp) -slt $t2, $t0, $t1 -sw $t2, 16($fp) -# IfGotoNode -# Load from local_i2a_at_A2I_internal_3 to $t0 -lw $t0, 16($fp) -li $t1, 0 -bne $t0, $t1, TRUE_50 -li $s0, 1 -sw $s0, 44($fp) -# Load from local_i2a_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) -nor $t1, $t0, $t0 -sw $t1, 40($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) -mult $t0, $t1 -mflo $t0 -sw $t0, 36($fp) -# ArgNode local_i2a_at_A2I_internal_8 to s0 -# Load from local_i2a_at_A2I_internal_8 to $s0 -lw $s0, 36($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 32($fp) -addi $sp, $sp, 8 -# ArgNode local_i2a_at_A2I_internal_7 to s0 -# Load from local_i2a_at_A2I_internal_7 to $s0 -lw $s0, 32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Load from data_16 to $s0 -la $s0, data_16 -sw $s0, 48($fp) -# ArgNode local_i2a_at_A2I_internal_11 to s0 -# Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String concat -# Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 28($fp) -addi $sp, $sp, 8 -# Load from local_i2a_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) -sw $t0, 24($fp) -# GotoNode -j END_50 -TRUE_50: -# ArgNode i to s0 -# Load from i to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 52($fp) -addi $sp, $sp, 8 -# Load from local_i2a_at_A2I_internal_12 to $t0 -lw $t0, 52($fp) -sw $t0, 24($fp) -END_50: -# Load from local_i2a_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) -# GotoNode -j END_49 -TRUE_49: -# Load from data_5 to $s0 -la $s0, data_5 -sw $s0, 56($fp) -# Load from local_i2a_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -sw $t0, 12($fp) -END_49: -# ReturnNode -# Load from local_i2a_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 56 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2a_aux_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -52 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -sw $s0, 4($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -sw $t1, 8($fp) -# IfGotoNode -# Load from local_i2a_aux_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_53 -li $s0, 10 -sw $s0, 24($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_5 to $t1 -lw $t1, 24($fp) -div $t2, $t0, $t1 -mflo $t0 -sw $t0, 20($fp) -# Load from local_i2a_aux_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) -sw $t0, 16($fp) -li $s0, 10 -sw $s0, 44($fp) -# Load from local_i2a_aux_at_A2I_next_3 to $t0 -lw $t0, 16($fp) -# Load from local_i2a_aux_at_A2I_internal_10 to $t1 -lw $t1, 44($fp) -mult $t0, $t1 -mflo $t0 -sw $t0, 40($fp) -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) -sub $t2, $t0, $t1 -sw $t2, 36($fp) -# ArgNode local_i2a_aux_at_A2I_internal_8 to s0 -# Load from local_i2a_aux_at_A2I_internal_8 to $s0 -lw $s0, 36($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2c -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 32($fp) -addi $sp, $sp, 8 -# ArgNode local_i2a_aux_at_A2I_internal_7 to s0 -# Load from local_i2a_aux_at_A2I_internal_7 to $s0 -lw $s0, 32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_i2a_aux_at_A2I_next_3 to s0 -# Load from local_i2a_aux_at_A2I_next_3 to $s0 -lw $s0, 16($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 48($fp) -addi $sp, $sp, 8 -# ArgNode local_i2a_aux_at_A2I_internal_11 to s0 -# Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String concat -# Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 28($fp) -addi $sp, $sp, 8 -# Load from local_i2a_aux_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) -sw $t0, 12($fp) -# GotoNode -j END_53 -TRUE_53: -# Load from data_15 to $s0 -la $s0, data_15 -sw $s0, 52($fp) -# Load from local_i2a_aux_at_A2I_internal_12 to $t0 -lw $t0, 52($fp) -sw $t0, 12($fp) -END_53: -# ReturnNode -# Load from local_i2a_aux_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 52 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_main_at_Main: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -56 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Load from data_18 to $s0 -la $s0, data_18 -sw $s0, 12($fp) -# ArgNode local_main_at_Main_internal_2 to s0 -# Load from local_main_at_Main_internal_2 to $s0 -lw $s0, 12($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Allocate space for A2I -li $a0, 16 -li $v0, 9 -syscall -move $s1, $v0 -sw $s1, 16($fp) -li $s0, 0 -sw $s0, 0($s1) -li $s0, 16 -sw $s0, 4($s1) -la $s0, classname_A2I -sw $s0, 8($s1) -li $s0, 88 -sw $s0, 12($s1) -# ArgNode local_main_at_Main_internal_3 to s0 -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# StaticCallNode -jal ctor_A2I -sw $v0, 16($fp) -# ArgNode local_main_at_Main_internal_3 to s0 -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 8($fp) -addi $sp, $sp, 8 -# Load from local_main_at_Main_internal_1 to $t0 -lw $t0, 8($fp) -sw $t0, 4($fp) -li $s0, 678987 -sw $s0, 28($fp) -# ArgNode local_main_at_Main_internal_6 to s0 -# Load from local_main_at_Main_internal_6 to $s0 -lw $s0, 28($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Allocate space for A2I -li $a0, 16 -li $v0, 9 -syscall -move $s1, $v0 -sw $s1, 32($fp) -li $s0, 0 -sw $s0, 0($s1) -li $s0, 16 -sw $s0, 4($s1) -la $s0, classname_A2I -sw $s0, 8($s1) -li $s0, 88 -sw $s0, 12($s1) -# ArgNode local_main_at_Main_internal_7 to s0 -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# StaticCallNode -jal ctor_A2I -sw $v0, 32($fp) -# ArgNode local_main_at_Main_internal_7 to s0 -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) -lw $s1, 12($s0) -addi $s2, $s1, 28 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 24($fp) -addi $sp, $sp, 8 -# Load from local_main_at_Main_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 20($fp) -# ArgNode local_main_at_Main_a_0 to s0 -# Load from local_main_at_Main_a_0 to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_int -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 36($fp) -addi $sp, $sp, 8 -# Load from data_19 to $s0 -la $s0, data_19 -sw $s0, 44($fp) -# ArgNode local_main_at_Main_internal_10 to s0 -# Load from local_main_at_Main_internal_10 to $s0 -lw $s0, 44($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_string -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 40($fp) -addi $sp, $sp, 8 -# ArgNode local_main_at_Main_b_4 to s0 -# Load from local_main_at_Main_b_4 to $s0 -lw $s0, 20($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_string -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 48($fp) -addi $sp, $sp, 8 -# Load from data_20 to $s0 -la $s0, data_20 -sw $s0, 56($fp) -# ArgNode local_main_at_Main_internal_13 to s0 -# Load from local_main_at_Main_internal_13 to $s0 -lw $s0, 56($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_string -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -sw $v0, 52($fp) -addi $sp, $sp, 8 -# ReturnNode -# Load from local_main_at_Main_internal_12 to $v0 -lw $v0, 52($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 56 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra \ No newline at end of file +data_6 = "C: Hello world +" +data_7 = "Done. +" +data_8 = "B: Hello world +" +data_9 = "D: Hello world +" + +.CODE +function function_abort_at_Object { + PARAM self + + LOCAL local_abort_at_Object_internal_0 + LOCAL local_abort_at_Object_internal_1 + LOCAL local_abort_at_Object_internal_2 + + local_abort_at_Object_internal_0 = TYPENAME self + local_abort_at_Object_internal_1 = CONCAT data_0 local_abort_at_Object_internal_0 + local_abort_at_Object_internal_2 = CONCAT local_abort_at_Object_internal_1 data_1 + PRINTSTR local_abort_at_Object_internal_2 + ABORT +} +function function_copy_at_Object { + PARAM self + + LOCAL local_copy_at_Object_internal_0 + + local_copy_at_Object_internal_0 = COPY self + RETURN local_copy_at_Object_internal_0 +} +function function_type_name_at_Object { + PARAM self + + LOCAL local_type_name_at_Object_internal_0 + LOCAL local_type_name_at_Object_internal_1 + + local_type_name_at_Object_internal_1 = TYPEOF self + local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 + RETURN local_type_name_at_Object_internal_0 +} +function function_length_at_String { + PARAM self + + LOCAL local_length_at_String_internal_0 + + local_length_at_String_internal_0 = LENGTH self + RETURN local_length_at_String_internal_0 +} +function function_concat_at_String { + PARAM self + PARAM string + + LOCAL local_concat_at_String_internal_0 + + local_concat_at_String_internal_0 = CONCAT self string + RETURN local_concat_at_String_internal_0 +} +function function_substr_at_String { + PARAM self + PARAM start + PARAM length + + LOCAL local_substr_at_String_internal_0 + LOCAL local_substr_at_String_internal_1 + LOCAL local_substr_at_String_internal_2 + LOCAL local_substr_at_String_internal_3 + LOCAL local_substr_at_String_internal_4 + LOCAL local_substr_at_String_internal_5 + LOCAL local_substr_at_String_internal_6 + LOCAL local_substr_at_String_internal_7 + LOCAL local_substr_at_String_internal_8 + + local_substr_at_String_internal_3 = 0 + local_substr_at_String_internal_2 = LENGTH self + local_substr_at_String_internal_5 = local_substr_at_String_internal_3 <= start + IF local_substr_at_String_internal_5 GOTO error1 + local_substr_at_String_internal_8 = CONCAT data_2 data_1 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error1 + local_substr_at_String_internal_6 = local_substr_at_String_internal_3 <= length + IF local_substr_at_String_internal_6 GOTO error2 + local_substr_at_String_internal_8 = CONCAT data_3 data_1 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error2 + local_substr_at_String_internal_4 = start + length + local_substr_at_String_internal_7 = local_substr_at_String_internal_4 <= local_substr_at_String_internal_2 + IF local_substr_at_String_internal_7 GOTO error3 + local_substr_at_String_internal_8 = CONCAT data_4 data_1 + PRINTSTR local_substr_at_String_internal_8 + ERROR 0 + LABEL error3 + local_substr_at_String_internal_0 = SUBSTRING self start length + RETURN local_substr_at_String_internal_0 +} +function function_out_string_at_IO { + PARAM self + PARAM str_val + + + + PRINTSTR str_val + RETURN self +} +function function_in_string_at_IO { + + + LOCAL local_in_string_at_IO_internal_0 + + local_in_string_at_IO_internal_0 = READSTR + RETURN local_in_string_at_IO_internal_0 +} +function function_out_int_at_IO { + PARAM self + PARAM int_val + + + + PRINTINT int_val + RETURN self +} +function function_in_int_at_IO { + + + LOCAL local_in_int_at_IO_internal_0 + + local_in_int_at_IO_internal_0 = READINT + RETURN local_in_int_at_IO_internal_0 +} +function ctor_IO { + PARAM self + + + + RETURN self +} +function ctor_Int { + PARAM self + + LOCAL local__internal_0 + + VOID + SETATTR value OF self_Int = local__internal_0 + RETURN self +} +function ctor_String { + PARAM self + + LOCAL local_ng_internal_0 + + VOID + SETATTR value OF self_String = local_ng_internal_0 + RETURN self +} +function ctor_Bool { + PARAM self + + LOCAL local__internal_0 + + VOID + SETATTR value OF self_Bool = local__internal_0 + RETURN self +} +function ctor_Object { + PARAM self + + + + RETURN self +} +function ctor_A { + PARAM self + + LOCAL local__internal_0 + + local__internal_0 = ALLOCATE IO + ARG local__internal_0 + local__internal_0 = CALL ctor_IO + SETATTR io OF self_A = local__internal_0 + RETURN self +} +function ctor_C { + PARAM self + + + + RETURN self +} +function ctor_Main { + PARAM self + + + + RETURN self +} +function ctor_B { + PARAM self + + LOCAL local__internal_0 + + local__internal_0 = ALLOCATE IO + ARG local__internal_0 + local__internal_0 = CALL ctor_IO + SETATTR io OF self_B = local__internal_0 + RETURN self +} +function ctor_D { + PARAM self + + + + RETURN self +} +function entry { + + + LOCAL local__internal_0 + LOCAL local__internal_1 + + local__internal_0 = ALLOCATE Main + ARG local__internal_0 + local__internal_1 = CALL function_main_at_Main + CLEAR 1 ARGS +} +function function_out_a_at_A { + PARAM self + + LOCAL local_out_a_at_A_internal_0 + LOCAL local_out_a_at_A_internal_1 + LOCAL local_out_a_at_A_internal_2 + + local_out_a_at_A_internal_1 = LOAD data_5 + ARG local_out_a_at_A_internal_1 + local_out_a_at_A_internal_2 = GETATTR self io + ARG local_out_a_at_A_internal_2 + local_out_a_at_A_internal_0 = VCALL IO out_string + CLEAR 2 ARGS + RETURN local_out_a_at_A_internal_0 +} +function function_out_c_at_C { + PARAM self + + LOCAL local_out_c_at_C_internal_0 + LOCAL local_out_c_at_C_internal_1 + + local_out_c_at_C_internal_1 = LOAD data_6 + ARG local_out_c_at_C_internal_1 + ARG self + local_out_c_at_C_internal_0 = VCALL C out_string + CLEAR 2 ARGS + RETURN local_out_c_at_C_internal_0 +} +function function_main_at_Main { + PARAM self + + LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_internal_1 + LOCAL local_main_at_Main_internal_2 + LOCAL local_main_at_Main_internal_3 + LOCAL local_main_at_Main_internal_4 + LOCAL local_main_at_Main_internal_5 + LOCAL local_main_at_Main_internal_6 + LOCAL local_main_at_Main_internal_7 + LOCAL local_main_at_Main_internal_8 + LOCAL local_main_at_Main_internal_9 + + local_main_at_Main_internal_1 = ALLOCATE A + ARG local_main_at_Main_internal_1 + local_main_at_Main_internal_1 = CALL ctor_A + ARG local_main_at_Main_internal_1 + local_main_at_Main_internal_0 = VCALL A out_a + CLEAR 1 ARGS + local_main_at_Main_internal_3 = ALLOCATE B + ARG local_main_at_Main_internal_3 + local_main_at_Main_internal_3 = CALL ctor_B + ARG local_main_at_Main_internal_3 + local_main_at_Main_internal_2 = VCALL B out_b + CLEAR 1 ARGS + local_main_at_Main_internal_5 = ALLOCATE C + ARG local_main_at_Main_internal_5 + local_main_at_Main_internal_5 = CALL ctor_C + ARG local_main_at_Main_internal_5 + local_main_at_Main_internal_4 = VCALL C out_c + CLEAR 1 ARGS + local_main_at_Main_internal_7 = ALLOCATE D + ARG local_main_at_Main_internal_7 + local_main_at_Main_internal_7 = CALL ctor_D + ARG local_main_at_Main_internal_7 + local_main_at_Main_internal_6 = VCALL D out_d + CLEAR 1 ARGS + local_main_at_Main_internal_9 = LOAD data_7 + ARG local_main_at_Main_internal_9 + ARG self + local_main_at_Main_internal_8 = VCALL Main out_string + CLEAR 2 ARGS + RETURN local_main_at_Main_internal_8 +} +function function_out_b_at_B { + PARAM self + + LOCAL local_out_b_at_B_internal_0 + LOCAL local_out_b_at_B_internal_1 + LOCAL local_out_b_at_B_internal_2 + + local_out_b_at_B_internal_1 = LOAD data_8 + ARG local_out_b_at_B_internal_1 + local_out_b_at_B_internal_2 = GETATTR self io + ARG local_out_b_at_B_internal_2 + local_out_b_at_B_internal_0 = VCALL IO out_string + CLEAR 2 ARGS + RETURN local_out_b_at_B_internal_0 +} +function function_out_d_at_D { + PARAM self + + LOCAL local_out_d_at_D_internal_0 + LOCAL local_out_d_at_D_internal_1 + + local_out_d_at_D_internal_1 = LOAD data_9 + ARG local_out_d_at_D_internal_1 + ARG self + local_out_d_at_D_internal_0 = VCALL D out_string + CLEAR 2 ARGS + RETURN local_out_d_at_D_internal_0 +} \ No newline at end of file From 43a164ab375458eb5f61f08f13c5d076965c0739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 16 Dec 2020 11:28:18 -0500 Subject: [PATCH 138/191] Revert "ctor fixed" This reverts commit d324b660d8e18052c632c1f60ee16ee11bf7c5d6. --- src/engine/codegen/to_cil.py | 7 +- src/test.cl | 202 +- src/test.mips | 3890 ++++++++++++++++++++++++++++++---- 3 files changed, 3571 insertions(+), 528 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index a6be26f4..7f9b5ce0 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -72,12 +72,11 @@ def save_attr_initializations(self, node: cool.ProgramNode, scope): def create_constructor(self, attr_declarations: List[cool.AttrDeclarationNode], type_name): self.current_function = self.register_function(f'ctor_{type_name}') - print(self.current_function.name) self.current_type = self.context.get_type(type_name) instance = self.register_param(VariableInfo('self', self.current_type)) - print(self.current_type.name) + scope = Scope() - scope.define_variable('self', self.current_type.name) + scope.define_variable('self', instance) for attr in attr_declarations: self.visit(attr, scope, typex=self.current_type.name) @@ -168,7 +167,6 @@ def visit(self, node: cool.AttrDeclarationNode, scope: Scope, typex): result = self.define_internal_local() self.register_instruction(VoidNode(result)) self_inst = scope.find_variable('self').name - print(scope) self.register_instruction( SetAttribNode(self_inst, node.id.lex, result, typex)) @@ -241,6 +239,7 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(IfGotoNode(cond, continue_label.label)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) + print(node.body) self.visit(node.body, while_scope) label_counter = self.label_counter_gen() self.register_instruction(GotoNode(start_label.label)) diff --git a/src/test.cl b/src/test.cl index 7f0de869..f4125a2f 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,103 +1,121 @@ (* - * 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. - * - *) + The class A2I provides integer-to-string and string-to-integer +conversion routines. To use these routines, either inherit them +in the class where needed, have a dummy variable bound to +something of type A2I, or simpl write (new A2I).method(argument). +*) -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(...) - -}; +(* + c2i Converts a 1-character string to an integer. Aborts + if the string is not "0" through "9" +*) +class A2I { + + c2i(char : String) : Int { + if char = "0" then 0 else + if char = "1" then 1 else + if char = "2" then 2 else + if char = "3" then 3 else + if char = "4" then 4 else + if char = "5" then 5 else + if char = "6" then 6 else + if char = "7" then 7 else + if char = "8" then 8 else + if char = "9" then 9 else + { abort(); 0; } -- the 0 is needed to satisfy the typchecker + fi fi fi fi fi fi fi fi fi fi + }; +(* + i2c is the inverse of c2i. +*) + i2c(i : Int) : String { + if i = 0 then "0" else + if i = 1 then "1" else + if i = 2 then "2" else + if i = 3 then "3" else + if i = 4 then "4" else + if i = 5 then "5" else + if i = 6 then "6" else + if i = 7 then "7" else + if i = 8 then "8" else + if i = 9 then "9" else + { abort(); ""; } -- the "" is needed to satisfy the typchecker + fi fi fi fi fi fi fi fi fi fi + }; -class D inherits C { +(* + a2i converts an ASCII string into an integer. The empty string +is converted to 0. Signed and unsigned strings are handled. The +method aborts if the string does not represent an integer. Very +long strings of digits produce strange answers because of arithmetic +overflow. + +*) + a2i(s : String) : Int { + if s.length() = 0 then 0 else + if s.substr(0,1) = "-" then ~a2i_aux(s.substr(1,s.length()-1)) else + if s.substr(0,1) = "+" then a2i_aux(s.substr(1,s.length()-1)) else + a2i_aux(s) + fi fi fi + }; - -- Inherits IO methods from C. +(* + a2i_aux converts the usigned portion of the string. As a programming +example, this method is written iteratively. +*) + a2i_aux(s : String) : Int { + (let int : Int <- 0 in + { + (let j : Int <- s.length() in + (let i : Int <- 0 in + while i < j loop + { + int <- int * 10 + c2i(s.substr(i,1)); + i <- i + 1; + } + pool + ) + ); + int; + } + ) + }; - out_d() : Object { out_string("D: Hello world\n") }; +(* + i2a converts an integer to a string. Positive and negative +numbers are handled correctly. +*) + i2a(i : Int) : String { + if i = 0 then "0" else + if 0 < i then i2a_aux(i) else + "-".concat(i2a_aux(i * ~1)) + fi fi + }; + +(* + i2a_aux is an example using recursion. +*) + i2a_aux(i : Int) : String { + if i = 0 then "" else + (let next : Int <- i / 10 in + i2a_aux(next).concat(i2c(i - next * 10)) + ) + fi + }; }; - class Main inherits IO { - - -- 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"); - } - }; - -}; + main () : Object { + let a : Int <- (new A2I).a2i("678987"), + b : String <- (new A2I).i2a(678987) in + { + out_int(a) ; + out_string(" == ") ; + out_string(b) ; + out_string("\n"); + } + } ; +} ; diff --git a/src/test.mips b/src/test.mips index a1a46134..69e2d5de 100644 --- a/src/test.mips +++ b/src/test.mips @@ -1,433 +1,3459 @@ -.TYPES -type Object { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type String { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method length: function_length_at_String - method concat: function_concat_at_String - method substr: function_substr_at_String -} -type IO { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO -} -type Int { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type Bool { - attribute value - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object -} -type A { - attribute io - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_a: function_out_a_at_A -} -type C { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method out_c: function_out_c_at_C -} -type Main { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method main: function_main_at_Main -} -type B { - attribute io - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_a: function_out_a_at_A - method out_b: function_out_b_at_B -} -type D { - - - method abort: function_abort_at_Object - method type_name: function_type_name_at_Object - method copy: function_copy_at_Object - method out_string: function_out_string_at_IO - method out_int: function_out_int_at_IO - method in_string: function_in_string_at_IO - method in_int: function_in_int_at_IO - method out_c: function_out_c_at_C - method out_d: function_out_d_at_D -} - -.DATA -data_0 = "Abort called from class " -data_1 = "\n" -data_2 = "Invalid substring start" -data_3 = "Invalid substring length" -data_4 = "Invalid substring" -data_5 = "A: Hello world +.data +classname_Object: +.asciiz "Object" +classname_String: +.asciiz "String" +classname_IO: +.asciiz "IO" +classname_Int: +.asciiz "Int" +classname_Bool: +.asciiz "Bool" +classname_A2I: +.asciiz "A2I" +classname_Main: +.asciiz "Main" +data_0: +.asciiz "Abort called from class " +data_1: +.asciiz "\n" +data_2: +.asciiz "Invalid substring start" +data_3: +.asciiz "Invalid substring length" +data_4: +.asciiz "Invalid substring" +data_5: +.asciiz "0" +data_6: +.asciiz "1" +data_7: +.asciiz "2" +data_8: +.asciiz "3" +data_9: +.asciiz "4" +data_10: +.asciiz "5" +data_11: +.asciiz "6" +data_12: +.asciiz "7" +data_13: +.asciiz "8" +data_14: +.asciiz "9" +data_15: +.asciiz "" +data_16: +.asciiz "-" +data_17: +.asciiz "+" +data_18: +.asciiz "678987" +data_19: +.asciiz " == " +data_20: +.asciiz " " -data_6 = "C: Hello world -" -data_7 = "Done. -" -data_8 = "B: Hello world -" -data_9 = "D: Hello world -" - -.CODE -function function_abort_at_Object { - PARAM self - - LOCAL local_abort_at_Object_internal_0 - LOCAL local_abort_at_Object_internal_1 - LOCAL local_abort_at_Object_internal_2 - - local_abort_at_Object_internal_0 = TYPENAME self - local_abort_at_Object_internal_1 = CONCAT data_0 local_abort_at_Object_internal_0 - local_abort_at_Object_internal_2 = CONCAT local_abort_at_Object_internal_1 data_1 - PRINTSTR local_abort_at_Object_internal_2 - ABORT -} -function function_copy_at_Object { - PARAM self - - LOCAL local_copy_at_Object_internal_0 - - local_copy_at_Object_internal_0 = COPY self - RETURN local_copy_at_Object_internal_0 -} -function function_type_name_at_Object { - PARAM self - - LOCAL local_type_name_at_Object_internal_0 - LOCAL local_type_name_at_Object_internal_1 - - local_type_name_at_Object_internal_1 = TYPEOF self - local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 - RETURN local_type_name_at_Object_internal_0 -} -function function_length_at_String { - PARAM self - - LOCAL local_length_at_String_internal_0 - - local_length_at_String_internal_0 = LENGTH self - RETURN local_length_at_String_internal_0 -} -function function_concat_at_String { - PARAM self - PARAM string - - LOCAL local_concat_at_String_internal_0 - - local_concat_at_String_internal_0 = CONCAT self string - RETURN local_concat_at_String_internal_0 -} -function function_substr_at_String { - PARAM self - PARAM start - PARAM length - - LOCAL local_substr_at_String_internal_0 - LOCAL local_substr_at_String_internal_1 - LOCAL local_substr_at_String_internal_2 - LOCAL local_substr_at_String_internal_3 - LOCAL local_substr_at_String_internal_4 - LOCAL local_substr_at_String_internal_5 - LOCAL local_substr_at_String_internal_6 - LOCAL local_substr_at_String_internal_7 - LOCAL local_substr_at_String_internal_8 - - local_substr_at_String_internal_3 = 0 - local_substr_at_String_internal_2 = LENGTH self - local_substr_at_String_internal_5 = local_substr_at_String_internal_3 <= start - IF local_substr_at_String_internal_5 GOTO error1 - local_substr_at_String_internal_8 = CONCAT data_2 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error1 - local_substr_at_String_internal_6 = local_substr_at_String_internal_3 <= length - IF local_substr_at_String_internal_6 GOTO error2 - local_substr_at_String_internal_8 = CONCAT data_3 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error2 - local_substr_at_String_internal_4 = start + length - local_substr_at_String_internal_7 = local_substr_at_String_internal_4 <= local_substr_at_String_internal_2 - IF local_substr_at_String_internal_7 GOTO error3 - local_substr_at_String_internal_8 = CONCAT data_4 data_1 - PRINTSTR local_substr_at_String_internal_8 - ERROR 0 - LABEL error3 - local_substr_at_String_internal_0 = SUBSTRING self start length - RETURN local_substr_at_String_internal_0 -} -function function_out_string_at_IO { - PARAM self - PARAM str_val - - - - PRINTSTR str_val - RETURN self -} -function function_in_string_at_IO { - - - LOCAL local_in_string_at_IO_internal_0 - - local_in_string_at_IO_internal_0 = READSTR - RETURN local_in_string_at_IO_internal_0 -} -function function_out_int_at_IO { - PARAM self - PARAM int_val - - - - PRINTINT int_val - RETURN self -} -function function_in_int_at_IO { - - - LOCAL local_in_int_at_IO_internal_0 - - local_in_int_at_IO_internal_0 = READINT - RETURN local_in_int_at_IO_internal_0 -} -function ctor_IO { - PARAM self - - - - RETURN self -} -function ctor_Int { - PARAM self - - LOCAL local__internal_0 - - VOID - SETATTR value OF self_Int = local__internal_0 - RETURN self -} -function ctor_String { - PARAM self - - LOCAL local_ng_internal_0 - - VOID - SETATTR value OF self_String = local_ng_internal_0 - RETURN self -} -function ctor_Bool { - PARAM self - - LOCAL local__internal_0 - - VOID - SETATTR value OF self_Bool = local__internal_0 - RETURN self -} -function ctor_Object { - PARAM self - - - - RETURN self -} -function ctor_A { - PARAM self - - LOCAL local__internal_0 - - local__internal_0 = ALLOCATE IO - ARG local__internal_0 - local__internal_0 = CALL ctor_IO - SETATTR io OF self_A = local__internal_0 - RETURN self -} -function ctor_C { - PARAM self - - - - RETURN self -} -function ctor_Main { - PARAM self - - - - RETURN self -} -function ctor_B { - PARAM self - - LOCAL local__internal_0 - - local__internal_0 = ALLOCATE IO - ARG local__internal_0 - local__internal_0 = CALL ctor_IO - SETATTR io OF self_B = local__internal_0 - RETURN self -} -function ctor_D { - PARAM self - - - - RETURN self -} -function entry { - - - LOCAL local__internal_0 - LOCAL local__internal_1 - - local__internal_0 = ALLOCATE Main - ARG local__internal_0 - local__internal_1 = CALL function_main_at_Main - CLEAR 1 ARGS -} -function function_out_a_at_A { - PARAM self - - LOCAL local_out_a_at_A_internal_0 - LOCAL local_out_a_at_A_internal_1 - LOCAL local_out_a_at_A_internal_2 - - local_out_a_at_A_internal_1 = LOAD data_5 - ARG local_out_a_at_A_internal_1 - local_out_a_at_A_internal_2 = GETATTR self io - ARG local_out_a_at_A_internal_2 - local_out_a_at_A_internal_0 = VCALL IO out_string - CLEAR 2 ARGS - RETURN local_out_a_at_A_internal_0 -} -function function_out_c_at_C { - PARAM self - - LOCAL local_out_c_at_C_internal_0 - LOCAL local_out_c_at_C_internal_1 - - local_out_c_at_C_internal_1 = LOAD data_6 - ARG local_out_c_at_C_internal_1 - ARG self - local_out_c_at_C_internal_0 = VCALL C out_string - CLEAR 2 ARGS - RETURN local_out_c_at_C_internal_0 -} -function function_main_at_Main { - PARAM self - - LOCAL local_main_at_Main_internal_0 - LOCAL local_main_at_Main_internal_1 - LOCAL local_main_at_Main_internal_2 - LOCAL local_main_at_Main_internal_3 - LOCAL local_main_at_Main_internal_4 - LOCAL local_main_at_Main_internal_5 - LOCAL local_main_at_Main_internal_6 - LOCAL local_main_at_Main_internal_7 - LOCAL local_main_at_Main_internal_8 - LOCAL local_main_at_Main_internal_9 - - local_main_at_Main_internal_1 = ALLOCATE A - ARG local_main_at_Main_internal_1 - local_main_at_Main_internal_1 = CALL ctor_A - ARG local_main_at_Main_internal_1 - local_main_at_Main_internal_0 = VCALL A out_a - CLEAR 1 ARGS - local_main_at_Main_internal_3 = ALLOCATE B - ARG local_main_at_Main_internal_3 - local_main_at_Main_internal_3 = CALL ctor_B - ARG local_main_at_Main_internal_3 - local_main_at_Main_internal_2 = VCALL B out_b - CLEAR 1 ARGS - local_main_at_Main_internal_5 = ALLOCATE C - ARG local_main_at_Main_internal_5 - local_main_at_Main_internal_5 = CALL ctor_C - ARG local_main_at_Main_internal_5 - local_main_at_Main_internal_4 = VCALL C out_c - CLEAR 1 ARGS - local_main_at_Main_internal_7 = ALLOCATE D - ARG local_main_at_Main_internal_7 - local_main_at_Main_internal_7 = CALL ctor_D - ARG local_main_at_Main_internal_7 - local_main_at_Main_internal_6 = VCALL D out_d - CLEAR 1 ARGS - local_main_at_Main_internal_9 = LOAD data_7 - ARG local_main_at_Main_internal_9 - ARG self - local_main_at_Main_internal_8 = VCALL Main out_string - CLEAR 2 ARGS - RETURN local_main_at_Main_internal_8 -} -function function_out_b_at_B { - PARAM self - - LOCAL local_out_b_at_B_internal_0 - LOCAL local_out_b_at_B_internal_1 - LOCAL local_out_b_at_B_internal_2 - - local_out_b_at_B_internal_1 = LOAD data_8 - ARG local_out_b_at_B_internal_1 - local_out_b_at_B_internal_2 = GETATTR self io - ARG local_out_b_at_B_internal_2 - local_out_b_at_B_internal_0 = VCALL IO out_string - CLEAR 2 ARGS - RETURN local_out_b_at_B_internal_0 -} -function function_out_d_at_D { - PARAM self - - LOCAL local_out_d_at_D_internal_0 - LOCAL local_out_d_at_D_internal_1 - - local_out_d_at_D_internal_1 = LOAD data_9 - ARG local_out_d_at_D_internal_1 - ARG self - local_out_d_at_D_internal_0 = VCALL D out_string - CLEAR 2 ARGS - RETURN local_out_d_at_D_internal_0 -} \ No newline at end of file +.text +main: +# Allocate Vtable +li $a0, 156 +li $v0, 9 +syscall +move $s7, $v0 +# Build VTable +la $s0, function_abort_at_Object +sw $s0, 0($s7) +la $s0, function_type_name_at_Object +sw $s0, 4($s7) +la $s0, function_copy_at_Object +sw $s0, 8($s7) +la $s0, function_abort_at_Object +sw $s0, 12($s7) +la $s0, function_type_name_at_Object +sw $s0, 16($s7) +la $s0, function_copy_at_Object +sw $s0, 20($s7) +la $s0, function_length_at_String +sw $s0, 24($s7) +la $s0, function_concat_at_String +sw $s0, 28($s7) +la $s0, function_substr_at_String +sw $s0, 32($s7) +la $s0, function_abort_at_Object +sw $s0, 36($s7) +la $s0, function_type_name_at_Object +sw $s0, 40($s7) +la $s0, function_copy_at_Object +sw $s0, 44($s7) +la $s0, function_out_string_at_IO +sw $s0, 48($s7) +la $s0, function_out_int_at_IO +sw $s0, 52($s7) +la $s0, function_in_string_at_IO +sw $s0, 56($s7) +la $s0, function_in_int_at_IO +sw $s0, 60($s7) +la $s0, function_abort_at_Object +sw $s0, 64($s7) +la $s0, function_type_name_at_Object +sw $s0, 68($s7) +la $s0, function_copy_at_Object +sw $s0, 72($s7) +la $s0, function_abort_at_Object +sw $s0, 76($s7) +la $s0, function_type_name_at_Object +sw $s0, 80($s7) +la $s0, function_copy_at_Object +sw $s0, 84($s7) +la $s0, function_abort_at_Object +sw $s0, 88($s7) +la $s0, function_type_name_at_Object +sw $s0, 92($s7) +la $s0, function_copy_at_Object +sw $s0, 96($s7) +la $s0, function_c2i_at_A2I +sw $s0, 100($s7) +la $s0, function_i2c_at_A2I +sw $s0, 104($s7) +la $s0, function_a2i_at_A2I +sw $s0, 108($s7) +la $s0, function_a2i_aux_at_A2I +sw $s0, 112($s7) +la $s0, function_i2a_at_A2I +sw $s0, 116($s7) +la $s0, function_i2a_aux_at_A2I +sw $s0, 120($s7) +la $s0, function_abort_at_Object +sw $s0, 124($s7) +la $s0, function_type_name_at_Object +sw $s0, 128($s7) +la $s0, function_copy_at_Object +sw $s0, 132($s7) +la $s0, function_out_string_at_IO +sw $s0, 136($s7) +la $s0, function_out_int_at_IO +sw $s0, 140($s7) +la $s0, function_in_string_at_IO +sw $s0, 144($s7) +la $s0, function_in_int_at_IO +sw $s0, 148($s7) +la $s0, function_main_at_Main +sw $s0, 152($s7) +jal entry + +li $v0, 10 +syscall +function_abort_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -12 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# TypeNameNode +# Load from self to $t0 +lw $t0, 4($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) +# Load from data_0 to $s0 +la $s0, data_0 +# Load from local_abort_at_Object_internal_0 to $s1 +lw $s1, 4($fp) +move $t0, $s0 +li $t1, 0 +mips_label_1: +lb $t3, 0($t0) +beqz $t3, mips_label_2 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_1 +mips_label_2: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_3: +lb $t3, 0($t0) +beqz $t3, mips_label_4 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_3 +mips_label_4: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_5: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_6 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_5 +mips_label_6: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_7: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_8 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_7 +mips_label_8: +move $v0, $t1 +sw $s3, 8($fp) +# Load from local_abort_at_Object_internal_1 to $s0 +lw $s0, 8($fp) +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_9: +lb $t3, 0($t0) +beqz $t3, mips_label_10 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_9 +mips_label_10: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_11: +lb $t3, 0($t0) +beqz $t3, mips_label_12 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_11 +mips_label_12: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_13: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_14 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_13 +mips_label_14: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_15: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_16 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_15 +mips_label_16: +move $v0, $t1 +sw $s3, 12($fp) +# Print str local_abort_at_Object_internal_2 +# Load from local_abort_at_Object_internal_2 to $a0 +lw $a0, 12($fp) +li $v0, 4 +syscall +li $v0, 10 +syscall + + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 12 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_copy_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +la $s1, -4($fp) +li $s3, 0 +move $t0, $s0 +move $t1, $s1 +move $t3, $s3 +mips_label_17: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 2 +addi $t1, $t1, 2 +addi $t3, $t3, -1 +beqz $t3, mips_label_18 +j mips_label_17 +mips_label_18: +# ReturnNode +# Load from local_copy_at_Object_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_type_name_at_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# TypeOfNode of self +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 3($s0) +sw $s1, 8($fp) +# TypeNameNode +# Load from local_type_name_at_Object_internal_1 to $t0 +lw $t0, 8($fp) +lw $t1, 4($t0) +sw $t1, 4($fp) +# ReturnNode +# Load from local_type_name_at_Object_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_length_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# LengthNode +# Load from self to $s1 +lw $s1, 4($fp) +move $t0, $s1 +li $t1, 0 +mips_label_19: +lb $t3, 0($t0) +beqz $t3, mips_label_20 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_19 +mips_label_20: +move $s0, $t1 +sw $s0, 4($fp) +# ReturnNode +# Load from local_length_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_concat_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from self to $s0 +lw $s0, 4($fp) +# Load from string to $s1 +lw $s1, 8($fp) +move $t0, $s0 +li $t1, 0 +mips_label_21: +lb $t3, 0($t0) +beqz $t3, mips_label_22 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_21 +mips_label_22: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_23: +lb $t3, 0($t0) +beqz $t3, mips_label_24 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_23 +mips_label_24: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_25: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_26 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_25 +mips_label_26: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_27: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_28 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_27 +mips_label_28: +move $v0, $t1 +sw $s3, 4($fp) +# ReturnNode +# Load from local_concat_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_substr_at_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -36 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 16($fp) +# LengthNode +# Load from self to $s1 +lw $s1, 4($fp) +move $t0, $s1 +li $t1, 0 +mips_label_29: +lb $t3, 0($t0) +beqz $t3, mips_label_30 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_29 +mips_label_30: +move $s0, $t1 +sw $s0, 12($fp) +# Load from local_substr_at_String_internal_3 to $t0 +lw $t0, 16($fp) +# Load from start to $t1 +lw $t1, 8($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 24($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_5 to $t0 +lw $t0, 24($fp) +li $t1, 0 +bne $t0, $t1, error1 +# Load from data_2 to $s0 +la $s0, data_2 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_31: +lb $t3, 0($t0) +beqz $t3, mips_label_32 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_31 +mips_label_32: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_33: +lb $t3, 0($t0) +beqz $t3, mips_label_34 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_33 +mips_label_34: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_35: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_36 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_35 +mips_label_36: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_37: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_38 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_37 +mips_label_38: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error1: +# Load from local_substr_at_String_internal_3 to $t0 +lw $t0, 16($fp) +# Load from length to $t1 +lw $t1, 12($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 28($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_6 to $t0 +lw $t0, 28($fp) +li $t1, 0 +bne $t0, $t1, error2 +# Load from data_3 to $s0 +la $s0, data_3 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_39: +lb $t3, 0($t0) +beqz $t3, mips_label_40 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_39 +mips_label_40: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_41: +lb $t3, 0($t0) +beqz $t3, mips_label_42 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_41 +mips_label_42: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_43: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_44 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_43 +mips_label_44: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_45: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_46 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_45 +mips_label_46: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error2: +# Load from start to $t0 +lw $t0, 8($fp) +# Load from length to $t1 +lw $t1, 12($fp) +add $t2, $t0, $t1 +sw $t2, 20($fp) +# Load from local_substr_at_String_internal_4 to $t0 +lw $t0, 20($fp) +# Load from local_substr_at_String_internal_2 to $t1 +lw $t1, 12($fp) +slt $t2, $t1, $t0 +li $t3, 1 +sub $t0, $t3, $t2 +sw $t0, 32($fp) +# IfGotoNode +# Load from local_substr_at_String_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, error3 +# Load from data_4 to $s0 +la $s0, data_4 +# Load from data_1 to $s1 +la $s1, data_1 +move $t0, $s0 +li $t1, 0 +mips_label_47: +lb $t3, 0($t0) +beqz $t3, mips_label_48 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_47 +mips_label_48: +move $s4, $t1 +move $t0, $s1 +li $t1, 0 +mips_label_49: +lb $t3, 0($t0) +beqz $t3, mips_label_50 +addi $t1, $t1, 1 +addi $t0, $t0, 1 +j mips_label_49 +mips_label_50: +move $s5, $t1 +add $a0, $s4, $s5 +li $v0, 9 +syscall +move $s3, $v0 +move $t0, $s0 +move $t1, $s3 +mips_label_51: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_52 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_51 +mips_label_52: +move $v0, $t1 +move $t0, $s1 +move $t1, $v0 +mips_label_53: +lb $t2, 0($t0) +sb $t2, 0($t1) +beqz $t2, mips_label_54 +addi $t0, $t0, 1 +addi $t1, $t1, 1 +j mips_label_53 +mips_label_54: +move $v0, $t1 +sw $s3, 36($fp) +# Print str local_substr_at_String_internal_8 +# Load from local_substr_at_String_internal_8 to $a0 +lw $a0, 36($fp) +li $v0, 4 +syscall +# ErrorNode +li $a0, 1 +li $v0, 17 +syscall +error3: +# Load from self to $s0 +lw $s0, 4($fp) +# Load from length to $s1 +lw $s1, 12($fp) +# Load from start to $s3 +lw $s3, 8($fp) +add $s0, $s0, $s3 +move $a0, $s1 +li $v0, 9 +syscall +move $t0, $s0 +move $t1, $v0 +move $t3, $s1 +mips_label_55: +lb $t2, 0($t0) +sb $t2, 0($t1) +addi $t0, $t0, 1 +addi $t1, $t1, 1 +addi $t3, $t3, -1 +beqz $t3, mips_label_56 +j mips_label_55 +mips_label_56: +move $t2, $zero +sb $t2, 0($t1) +sw $v0, 4($fp) +# ReturnNode +# Load from local_substr_at_String_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 36 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_out_string_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Print str str_val +# Load from str_val to $a0 +lw $a0, 8($fp) +li $v0, 4 +syscall +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_in_string_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $a0, 1024 +li $v0, 9 +syscall +move $a0, $v0 +sw $v0, 4($fp) +li $a1, 1024 +li $v0, 8 +syscall +# ReturnNode +# Load from local_in_string_at_IO_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_out_int_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from int_val to $a0 +lw $a0, 8($fp) +li $v0, 1 +syscall +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_in_int_at_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $v0, 5 +syscall +sw $v0, 4($fp) +# ReturnNode +# Load from local_in_int_at_IO_internal_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +entry: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -8 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Allocate space for Main +li $a0, 16 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 4($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 16 +sw $s0, 4($s1) +la $s0, classname_Main +sw $s0, 8($s1) +li $s0, 124 +sw $s0, 12($s1) +# ArgNode local__internal_0 to s0 +# Load from local__internal_0 to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal function_main_at_Main +sw $v0, 8($fp) +addi $sp, $sp, 4 + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 8 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_c2i_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -168 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 4($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_0 to $s1 +lw $s1, 4($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_60: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_58 +beqz $a1, mips_label_59 +seq $v0, $a0, $a1 +beqz $v0, mips_label_59 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_60 +mips_label_59: +li $v0, 0 +j mips_label_57 +mips_label_58: +bnez $a1, mips_label_59 +li $v0, 1 +mips_label_57: +sw $v0, 8($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_1 +# Load from data_6 to $s0 +la $s0, data_6 +sw $s0, 16($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_3 to $s1 +lw $s1, 16($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_64: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_62 +beqz $a1, mips_label_63 +seq $v0, $a0, $a1 +beqz $v0, mips_label_63 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_64 +mips_label_63: +li $v0, 0 +j mips_label_61 +mips_label_62: +bnez $a1, mips_label_63 +li $v0, 1 +mips_label_61: +sw $v0, 20($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +li $t1, 0 +bne $t0, $t1, TRUE_2 +# Load from data_7 to $s0 +la $s0, data_7 +sw $s0, 28($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_6 to $s1 +lw $s1, 28($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_68: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_66 +beqz $a1, mips_label_67 +seq $v0, $a0, $a1 +beqz $v0, mips_label_67 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_68 +mips_label_67: +li $v0, 0 +j mips_label_65 +mips_label_66: +bnez $a1, mips_label_67 +li $v0, 1 +mips_label_65: +sw $v0, 32($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, TRUE_3 +# Load from data_8 to $s0 +la $s0, data_8 +sw $s0, 40($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_9 to $s1 +lw $s1, 40($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_72: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_70 +beqz $a1, mips_label_71 +seq $v0, $a0, $a1 +beqz $v0, mips_label_71 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_72 +mips_label_71: +li $v0, 0 +j mips_label_69 +mips_label_70: +bnez $a1, mips_label_71 +li $v0, 1 +mips_label_69: +sw $v0, 44($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +li $t1, 0 +bne $t0, $t1, TRUE_4 +# Load from data_9 to $s0 +la $s0, data_9 +sw $s0, 52($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_12 to $s1 +lw $s1, 52($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_76: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_74 +beqz $a1, mips_label_75 +seq $v0, $a0, $a1 +beqz $v0, mips_label_75 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_76 +mips_label_75: +li $v0, 0 +j mips_label_73 +mips_label_74: +bnez $a1, mips_label_75 +li $v0, 1 +mips_label_73: +sw $v0, 56($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +li $t1, 0 +bne $t0, $t1, TRUE_5 +# Load from data_10 to $s0 +la $s0, data_10 +sw $s0, 64($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_15 to $s1 +lw $s1, 64($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_80: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_78 +beqz $a1, mips_label_79 +seq $v0, $a0, $a1 +beqz $v0, mips_label_79 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_80 +mips_label_79: +li $v0, 0 +j mips_label_77 +mips_label_78: +bnez $a1, mips_label_79 +li $v0, 1 +mips_label_77: +sw $v0, 68($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +li $t1, 0 +bne $t0, $t1, TRUE_6 +# Load from data_11 to $s0 +la $s0, data_11 +sw $s0, 76($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_18 to $s1 +lw $s1, 76($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_84: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_82 +beqz $a1, mips_label_83 +seq $v0, $a0, $a1 +beqz $v0, mips_label_83 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_84 +mips_label_83: +li $v0, 0 +j mips_label_81 +mips_label_82: +bnez $a1, mips_label_83 +li $v0, 1 +mips_label_81: +sw $v0, 80($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_19 to $t0 +lw $t0, 80($fp) +li $t1, 0 +bne $t0, $t1, TRUE_7 +# Load from data_12 to $s0 +la $s0, data_12 +sw $s0, 88($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_21 to $s1 +lw $s1, 88($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_88: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_86 +beqz $a1, mips_label_87 +seq $v0, $a0, $a1 +beqz $v0, mips_label_87 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_88 +mips_label_87: +li $v0, 0 +j mips_label_85 +mips_label_86: +bnez $a1, mips_label_87 +li $v0, 1 +mips_label_85: +sw $v0, 92($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_22 to $t0 +lw $t0, 92($fp) +li $t1, 0 +bne $t0, $t1, TRUE_8 +# Load from data_13 to $s0 +la $s0, data_13 +sw $s0, 100($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_24 to $s1 +lw $s1, 100($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_92: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_90 +beqz $a1, mips_label_91 +seq $v0, $a0, $a1 +beqz $v0, mips_label_91 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_92 +mips_label_91: +li $v0, 0 +j mips_label_89 +mips_label_90: +bnez $a1, mips_label_91 +li $v0, 1 +mips_label_89: +sw $v0, 104($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_25 to $t0 +lw $t0, 104($fp) +li $t1, 0 +bne $t0, $t1, TRUE_9 +# Load from data_14 to $s0 +la $s0, data_14 +sw $s0, 112($fp) +# Load from char to $s0 +lw $s0, 8($fp) +# Load from local_c2i_at_A2I_internal_27 to $s1 +lw $s1, 112($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_96: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_94 +beqz $a1, mips_label_95 +seq $v0, $a0, $a1 +beqz $v0, mips_label_95 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_96 +mips_label_95: +li $v0, 0 +j mips_label_93 +mips_label_94: +bnez $a1, mips_label_95 +li $v0, 1 +mips_label_93: +sw $v0, 116($fp) +# IfGotoNode +# Load from local_c2i_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +li $t1, 0 +bne $t0, $t1, TRUE_10 +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I abort +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 0 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 124($fp) +addi $sp, $sp, 4 +li $s0, 0 +sw $s0, 128($fp) +# Load from local_c2i_at_A2I_internal_31 to $t0 +lw $t0, 128($fp) +sw $t0, 120($fp) +# GotoNode +j END_10 +TRUE_10: +li $s0, 9 +sw $s0, 132($fp) +# Load from local_c2i_at_A2I_internal_32 to $t0 +lw $t0, 132($fp) +sw $t0, 120($fp) +END_10: +# Load from local_c2i_at_A2I_internal_29 to $t0 +lw $t0, 120($fp) +sw $t0, 108($fp) +# GotoNode +j END_9 +TRUE_9: +li $s0, 8 +sw $s0, 136($fp) +# Load from local_c2i_at_A2I_internal_33 to $t0 +lw $t0, 136($fp) +sw $t0, 108($fp) +END_9: +# Load from local_c2i_at_A2I_internal_26 to $t0 +lw $t0, 108($fp) +sw $t0, 96($fp) +# GotoNode +j END_8 +TRUE_8: +li $s0, 7 +sw $s0, 140($fp) +# Load from local_c2i_at_A2I_internal_34 to $t0 +lw $t0, 140($fp) +sw $t0, 96($fp) +END_8: +# Load from local_c2i_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 84($fp) +# GotoNode +j END_7 +TRUE_7: +li $s0, 6 +sw $s0, 144($fp) +# Load from local_c2i_at_A2I_internal_35 to $t0 +lw $t0, 144($fp) +sw $t0, 84($fp) +END_7: +# Load from local_c2i_at_A2I_internal_20 to $t0 +lw $t0, 84($fp) +sw $t0, 72($fp) +# GotoNode +j END_6 +TRUE_6: +li $s0, 5 +sw $s0, 148($fp) +# Load from local_c2i_at_A2I_internal_36 to $t0 +lw $t0, 148($fp) +sw $t0, 72($fp) +END_6: +# Load from local_c2i_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 60($fp) +# GotoNode +j END_5 +TRUE_5: +li $s0, 4 +sw $s0, 152($fp) +# Load from local_c2i_at_A2I_internal_37 to $t0 +lw $t0, 152($fp) +sw $t0, 60($fp) +END_5: +# Load from local_c2i_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +sw $t0, 48($fp) +# GotoNode +j END_4 +TRUE_4: +li $s0, 3 +sw $s0, 156($fp) +# Load from local_c2i_at_A2I_internal_38 to $t0 +lw $t0, 156($fp) +sw $t0, 48($fp) +END_4: +# Load from local_c2i_at_A2I_internal_11 to $t0 +lw $t0, 48($fp) +sw $t0, 36($fp) +# GotoNode +j END_3 +TRUE_3: +li $s0, 2 +sw $s0, 160($fp) +# Load from local_c2i_at_A2I_internal_39 to $t0 +lw $t0, 160($fp) +sw $t0, 36($fp) +END_3: +# Load from local_c2i_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +sw $t0, 24($fp) +# GotoNode +j END_2 +TRUE_2: +li $s0, 1 +sw $s0, 164($fp) +# Load from local_c2i_at_A2I_internal_40 to $t0 +lw $t0, 164($fp) +sw $t0, 24($fp) +END_2: +# Load from local_c2i_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_1 +TRUE_1: +li $s0, 0 +sw $s0, 168($fp) +# Load from local_c2i_at_A2I_internal_41 to $t0 +lw $t0, 168($fp) +sw $t0, 12($fp) +END_1: +# ReturnNode +# Load from local_c2i_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 168 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2c_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -168 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_21 +li $s0, 1 +sw $s0, 16($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_3 to $t1 +lw $t1, 16($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 20($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +li $t1, 0 +bne $t0, $t1, TRUE_22 +li $s0, 2 +sw $s0, 28($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_6 to $t1 +lw $t1, 28($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 32($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +li $t1, 0 +bne $t0, $t1, TRUE_23 +li $s0, 3 +sw $s0, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 44($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +li $t1, 0 +bne $t0, $t1, TRUE_24 +li $s0, 4 +sw $s0, 52($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_12 to $t1 +lw $t1, 52($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 56($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +li $t1, 0 +bne $t0, $t1, TRUE_25 +li $s0, 5 +sw $s0, 64($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_15 to $t1 +lw $t1, 64($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 68($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +li $t1, 0 +bne $t0, $t1, TRUE_26 +li $s0, 6 +sw $s0, 76($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_18 to $t1 +lw $t1, 76($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 80($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_19 to $t0 +lw $t0, 80($fp) +li $t1, 0 +bne $t0, $t1, TRUE_27 +li $s0, 7 +sw $s0, 88($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_21 to $t1 +lw $t1, 88($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 92($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_22 to $t0 +lw $t0, 92($fp) +li $t1, 0 +bne $t0, $t1, TRUE_28 +li $s0, 8 +sw $s0, 100($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_24 to $t1 +lw $t1, 100($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 104($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_25 to $t0 +lw $t0, 104($fp) +li $t1, 0 +bne $t0, $t1, TRUE_29 +li $s0, 9 +sw $s0, 112($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2c_at_A2I_internal_27 to $t1 +lw $t1, 112($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 116($fp) +# IfGotoNode +# Load from local_i2c_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +li $t1, 0 +bne $t0, $t1, TRUE_30 +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I abort +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 0 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 124($fp) +addi $sp, $sp, 4 +# Load from data_15 to $s0 +la $s0, data_15 +sw $s0, 128($fp) +# Load from local_i2c_at_A2I_internal_31 to $t0 +lw $t0, 128($fp) +sw $t0, 120($fp) +# GotoNode +j END_30 +TRUE_30: +# Load from data_14 to $s0 +la $s0, data_14 +sw $s0, 132($fp) +# Load from local_i2c_at_A2I_internal_32 to $t0 +lw $t0, 132($fp) +sw $t0, 120($fp) +END_30: +# Load from local_i2c_at_A2I_internal_29 to $t0 +lw $t0, 120($fp) +sw $t0, 108($fp) +# GotoNode +j END_29 +TRUE_29: +# Load from data_13 to $s0 +la $s0, data_13 +sw $s0, 136($fp) +# Load from local_i2c_at_A2I_internal_33 to $t0 +lw $t0, 136($fp) +sw $t0, 108($fp) +END_29: +# Load from local_i2c_at_A2I_internal_26 to $t0 +lw $t0, 108($fp) +sw $t0, 96($fp) +# GotoNode +j END_28 +TRUE_28: +# Load from data_12 to $s0 +la $s0, data_12 +sw $s0, 140($fp) +# Load from local_i2c_at_A2I_internal_34 to $t0 +lw $t0, 140($fp) +sw $t0, 96($fp) +END_28: +# Load from local_i2c_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 84($fp) +# GotoNode +j END_27 +TRUE_27: +# Load from data_11 to $s0 +la $s0, data_11 +sw $s0, 144($fp) +# Load from local_i2c_at_A2I_internal_35 to $t0 +lw $t0, 144($fp) +sw $t0, 84($fp) +END_27: +# Load from local_i2c_at_A2I_internal_20 to $t0 +lw $t0, 84($fp) +sw $t0, 72($fp) +# GotoNode +j END_26 +TRUE_26: +# Load from data_10 to $s0 +la $s0, data_10 +sw $s0, 148($fp) +# Load from local_i2c_at_A2I_internal_36 to $t0 +lw $t0, 148($fp) +sw $t0, 72($fp) +END_26: +# Load from local_i2c_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 60($fp) +# GotoNode +j END_25 +TRUE_25: +# Load from data_9 to $s0 +la $s0, data_9 +sw $s0, 152($fp) +# Load from local_i2c_at_A2I_internal_37 to $t0 +lw $t0, 152($fp) +sw $t0, 60($fp) +END_25: +# Load from local_i2c_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +sw $t0, 48($fp) +# GotoNode +j END_24 +TRUE_24: +# Load from data_8 to $s0 +la $s0, data_8 +sw $s0, 156($fp) +# Load from local_i2c_at_A2I_internal_38 to $t0 +lw $t0, 156($fp) +sw $t0, 48($fp) +END_24: +# Load from local_i2c_at_A2I_internal_11 to $t0 +lw $t0, 48($fp) +sw $t0, 36($fp) +# GotoNode +j END_23 +TRUE_23: +# Load from data_7 to $s0 +la $s0, data_7 +sw $s0, 160($fp) +# Load from local_i2c_at_A2I_internal_39 to $t0 +lw $t0, 160($fp) +sw $t0, 36($fp) +END_23: +# Load from local_i2c_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +sw $t0, 24($fp) +# GotoNode +j END_22 +TRUE_22: +# Load from data_6 to $s0 +la $s0, data_6 +sw $s0, 164($fp) +# Load from local_i2c_at_A2I_internal_40 to $t0 +lw $t0, 164($fp) +sw $t0, 24($fp) +END_22: +# Load from local_i2c_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_21 +TRUE_21: +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 168($fp) +# Load from local_i2c_at_A2I_internal_41 to $t0 +lw $t0, 168($fp) +sw $t0, 12($fp) +END_21: +# ReturnNode +# Load from local_i2c_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 168 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_a2i_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -124 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 4($fp) +addi $sp, $sp, 4 +li $s0, 0 +sw $s0, 8($fp) +# Load from local_a2i_at_A2I_internal_0 to $t0 +lw $t0, 4($fp) +# Load from local_a2i_at_A2I_internal_1 to $t1 +lw $t1, 8($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 12($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_2 to $t0 +lw $t0, 12($fp) +li $t1, 0 +bne $t0, $t1, TRUE_41 +li $s0, 0 +sw $s0, 24($fp) +li $s0, 1 +sw $s0, 28($fp) +# ArgNode local_a2i_at_A2I_internal_6 to s0 +# Load from local_a2i_at_A2I_internal_6 to $s0 +lw $s0, 28($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_5 to s0 +# Load from local_a2i_at_A2I_internal_5 to $s0 +lw $s0, 24($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 20($fp) +addi $sp, $sp, 12 +# Load from data_16 to $s0 +la $s0, data_16 +sw $s0, 32($fp) +# Load from local_a2i_at_A2I_internal_4 to $s0 +lw $s0, 20($fp) +# Load from local_a2i_at_A2I_internal_7 to $s1 +lw $s1, 32($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_100: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_98 +beqz $a1, mips_label_99 +seq $v0, $a0, $a1 +beqz $v0, mips_label_99 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_100 +mips_label_99: +li $v0, 0 +j mips_label_97 +mips_label_98: +bnez $a1, mips_label_99 +li $v0, 1 +mips_label_97: +sw $v0, 36($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +li $t1, 0 +bne $t0, $t1, TRUE_42 +li $s0, 0 +sw $s0, 48($fp) +li $s0, 1 +sw $s0, 52($fp) +# ArgNode local_a2i_at_A2I_internal_12 to s0 +# Load from local_a2i_at_A2I_internal_12 to $s0 +lw $s0, 52($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_11 to s0 +# Load from local_a2i_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 44($fp) +addi $sp, $sp, 12 +# Load from data_17 to $s0 +la $s0, data_17 +sw $s0, 56($fp) +# Load from local_a2i_at_A2I_internal_10 to $s0 +lw $s0, 44($fp) +# Load from local_a2i_at_A2I_internal_13 to $s1 +lw $s1, 56($fp) +move $t8, $s0 +move $t9, $s1 +mips_label_104: +lb $a0, 0($t8) +lb $a1, 0($t9) +beqz $a0, mips_label_102 +beqz $a1, mips_label_103 +seq $v0, $a0, $a1 +beqz $v0, mips_label_103 +addi $t8, $t8, 1 +addi $t9, $t9, 1 +j mips_label_104 +mips_label_103: +li $v0, 0 +j mips_label_101 +mips_label_102: +bnez $a1, mips_label_103 +li $v0, 1 +mips_label_101: +sw $v0, 60($fp) +# IfGotoNode +# Load from local_a2i_at_A2I_internal_14 to $t0 +lw $t0, 60($fp) +li $t1, 0 +bne $t0, $t1, TRUE_43 +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 68($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_16 to $t0 +lw $t0, 68($fp) +sw $t0, 64($fp) +# GotoNode +j END_43 +TRUE_43: +li $s0, 1 +sw $s0, 80($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 88($fp) +addi $sp, $sp, 4 +li $s0, 1 +sw $s0, 92($fp) +# Load from local_a2i_at_A2I_internal_21 to $t0 +lw $t0, 88($fp) +# Load from local_a2i_at_A2I_internal_22 to $t1 +lw $t1, 92($fp) +sub $t2, $t0, $t1 +sw $t2, 84($fp) +# ArgNode local_a2i_at_A2I_internal_20 to s0 +# Load from local_a2i_at_A2I_internal_20 to $s0 +lw $s0, 84($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_19 to s0 +# Load from local_a2i_at_A2I_internal_19 to $s0 +lw $s0, 80($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 76($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_at_A2I_internal_18 to s0 +# Load from local_a2i_at_A2I_internal_18 to $s0 +lw $s0, 76($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 72($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_17 to $t0 +lw $t0, 72($fp) +sw $t0, 64($fp) +END_43: +# Load from local_a2i_at_A2I_internal_15 to $t0 +lw $t0, 64($fp) +sw $t0, 40($fp) +# GotoNode +j END_42 +TRUE_42: +li $s0, 1 +sw $s0, 108($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 116($fp) +addi $sp, $sp, 4 +li $s0, 1 +sw $s0, 120($fp) +# Load from local_a2i_at_A2I_internal_28 to $t0 +lw $t0, 116($fp) +# Load from local_a2i_at_A2I_internal_29 to $t1 +lw $t1, 120($fp) +sub $t2, $t0, $t1 +sw $t2, 112($fp) +# ArgNode local_a2i_at_A2I_internal_27 to s0 +# Load from local_a2i_at_A2I_internal_27 to $s0 +lw $s0, 112($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_at_A2I_internal_26 to s0 +# Load from local_a2i_at_A2I_internal_26 to $s0 +lw $s0, 108($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 104($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_at_A2I_internal_25 to s0 +# Load from local_a2i_at_A2I_internal_25 to $s0 +lw $s0, 104($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 24 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 100($fp) +addi $sp, $sp, 8 +# Load from local_a2i_at_A2I_internal_24 to $t0 +lw $t0, 100($fp) +nor $t1, $t0, $t0 +sw $t1, 96($fp) +# Load from local_a2i_at_A2I_internal_23 to $t0 +lw $t0, 96($fp) +sw $t0, 40($fp) +END_42: +# Load from local_a2i_at_A2I_internal_9 to $t0 +lw $t0, 40($fp) +sw $t0, 16($fp) +# GotoNode +j END_41 +TRUE_41: +li $s0, 0 +sw $s0, 124($fp) +# Load from local_a2i_at_A2I_internal_30 to $t0 +lw $t0, 124($fp) +sw $t0, 16($fp) +END_41: +# ReturnNode +# Load from local_a2i_at_A2I_internal_3 to $v0 +lw $v0, 16($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 124 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_a2i_aux_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -60 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 8($fp) +# Load from local_a2i_aux_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +sw $t0, 4($fp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String length +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 16($fp) +addi $sp, $sp, 4 +# Load from local_a2i_aux_at_A2I_internal_3 to $t0 +lw $t0, 16($fp) +sw $t0, 12($fp) +li $s0, 0 +sw $s0, 24($fp) +# Load from local_a2i_aux_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 20($fp) +START_47: +# Load from local_a2i_aux_at_A2I_i_4 to $t0 +lw $t0, 20($fp) +# Load from local_a2i_aux_at_A2I_j_2 to $t1 +lw $t1, 12($fp) +slt $t2, $t0, $t1 +sw $t2, 28($fp) +# IfGotoNode +# Load from local_a2i_aux_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +li $t1, 0 +bne $t0, $t1, CONTINUE_47 +# GotoNode +j END_47 +CONTINUE_47: +li $s0, 10 +sw $s0, 40($fp) +# Load from local_a2i_aux_at_A2I_int_0 to $t0 +lw $t0, 4($fp) +# Load from local_a2i_aux_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 36($fp) +li $s0, 1 +sw $s0, 52($fp) +# ArgNode local_a2i_aux_at_A2I_internal_12 to s0 +# Load from local_a2i_aux_at_A2I_internal_12 to $s0 +lw $s0, 52($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_a2i_aux_at_A2I_i_4 to s0 +# Load from local_a2i_aux_at_A2I_i_4 to $s0 +lw $s0, 20($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode s to s0 +# Load from s to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String substr +# Load from s to $s0 +lw $s0, 8($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 12 +# ArgNode local_a2i_aux_at_A2I_internal_11 to s0 +# Load from local_a2i_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I c2i +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 44($fp) +addi $sp, $sp, 8 +# Load from local_a2i_aux_at_A2I_internal_8 to $t0 +lw $t0, 36($fp) +# Load from local_a2i_aux_at_A2I_internal_10 to $t1 +lw $t1, 44($fp) +add $t2, $t0, $t1 +sw $t2, 32($fp) +# Load from local_a2i_aux_at_A2I_internal_7 to $t0 +lw $t0, 32($fp) +sw $t0, 4($fp) +li $s0, 1 +sw $s0, 60($fp) +# Load from local_a2i_aux_at_A2I_i_4 to $t0 +lw $t0, 20($fp) +# Load from local_a2i_aux_at_A2I_internal_14 to $t1 +lw $t1, 60($fp) +add $t2, $t0, $t1 +sw $t2, 56($fp) +# Load from local_a2i_aux_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +sw $t0, 20($fp) +# GotoNode +j START_47 +END_47: +# ReturnNode +# Load from local_a2i_aux_at_A2I_int_0 to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 60 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2a_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -56 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2a_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_49 +li $s0, 0 +sw $s0, 20($fp) +# Load from local_i2a_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +# Load from i to $t1 +lw $t1, 8($fp) +slt $t2, $t0, $t1 +sw $t2, 16($fp) +# IfGotoNode +# Load from local_i2a_at_A2I_internal_3 to $t0 +lw $t0, 16($fp) +li $t1, 0 +bne $t0, $t1, TRUE_50 +li $s0, 1 +sw $s0, 44($fp) +# Load from local_i2a_at_A2I_internal_10 to $t0 +lw $t0, 44($fp) +nor $t1, $t0, $t0 +sw $t1, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 36($fp) +# ArgNode local_i2a_at_A2I_internal_8 to s0 +# Load from local_i2a_at_A2I_internal_8 to $s0 +lw $s0, 36($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 32($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_at_A2I_internal_7 to s0 +# Load from local_i2a_at_A2I_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Load from data_16 to $s0 +la $s0, data_16 +sw $s0, 48($fp) +# ArgNode local_i2a_at_A2I_internal_11 to s0 +# Load from local_i2a_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String concat +# Load from local_i2a_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 28($fp) +addi $sp, $sp, 8 +# Load from local_i2a_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +sw $t0, 24($fp) +# GotoNode +j END_50 +TRUE_50: +# ArgNode i to s0 +# Load from i to $s0 +lw $s0, 8($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 52($fp) +addi $sp, $sp, 8 +# Load from local_i2a_at_A2I_internal_12 to $t0 +lw $t0, 52($fp) +sw $t0, 24($fp) +END_50: +# Load from local_i2a_at_A2I_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 12($fp) +# GotoNode +j END_49 +TRUE_49: +# Load from data_5 to $s0 +la $s0, data_5 +sw $s0, 56($fp) +# Load from local_i2a_at_A2I_internal_13 to $t0 +lw $t0, 56($fp) +sw $t0, 12($fp) +END_49: +# ReturnNode +# Load from local_i2a_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 56 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_i2a_aux_at_A2I: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -52 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +li $s0, 0 +sw $s0, 4($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_0 to $t1 +lw $t1, 4($fp) +slt $t2, $t0, $t1 +slt $t3, $t1, $t0 +add $t0, $t2, $t3 +slti $t1, $t0, 1 +sw $t1, 8($fp) +# IfGotoNode +# Load from local_i2a_aux_at_A2I_internal_1 to $t0 +lw $t0, 8($fp) +li $t1, 0 +bne $t0, $t1, TRUE_53 +li $s0, 10 +sw $s0, 24($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_5 to $t1 +lw $t1, 24($fp) +div $t2, $t0, $t1 +mflo $t0 +sw $t0, 20($fp) +# Load from local_i2a_aux_at_A2I_internal_4 to $t0 +lw $t0, 20($fp) +sw $t0, 16($fp) +li $s0, 10 +sw $s0, 44($fp) +# Load from local_i2a_aux_at_A2I_next_3 to $t0 +lw $t0, 16($fp) +# Load from local_i2a_aux_at_A2I_internal_10 to $t1 +lw $t1, 44($fp) +mult $t0, $t1 +mflo $t0 +sw $t0, 40($fp) +# Load from i to $t0 +lw $t0, 8($fp) +# Load from local_i2a_aux_at_A2I_internal_9 to $t1 +lw $t1, 40($fp) +sub $t2, $t0, $t1 +sw $t2, 36($fp) +# ArgNode local_i2a_aux_at_A2I_internal_8 to s0 +# Load from local_i2a_aux_at_A2I_internal_8 to $s0 +lw $s0, 36($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2c +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 32($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_aux_at_A2I_internal_7 to s0 +# Load from local_i2a_aux_at_A2I_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode local_i2a_aux_at_A2I_next_3 to s0 +# Load from local_i2a_aux_at_A2I_next_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a_aux +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 32 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 8 +# ArgNode local_i2a_aux_at_A2I_internal_11 to s0 +# Load from local_i2a_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode String concat +# Load from local_i2a_aux_at_A2I_internal_11 to $s0 +lw $s0, 48($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 28($fp) +addi $sp, $sp, 8 +# Load from local_i2a_aux_at_A2I_internal_6 to $t0 +lw $t0, 28($fp) +sw $t0, 12($fp) +# GotoNode +j END_53 +TRUE_53: +# Load from data_15 to $s0 +la $s0, data_15 +sw $s0, 52($fp) +# Load from local_i2a_aux_at_A2I_internal_12 to $t0 +lw $t0, 52($fp) +sw $t0, 12($fp) +END_53: +# ReturnNode +# Load from local_i2a_aux_at_A2I_internal_2 to $v0 +lw $v0, 12($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 52 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +function_main_at_Main: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -56 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# Load from data_18 to $s0 +la $s0, data_18 +sw $s0, 12($fp) +# ArgNode local_main_at_Main_internal_2 to s0 +# Load from local_main_at_Main_internal_2 to $s0 +lw $s0, 12($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Allocate space for A2I +li $a0, 16 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 16($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 16 +sw $s0, 4($s1) +la $s0, classname_A2I +sw $s0, 8($s1) +li $s0, 88 +sw $s0, 12($s1) +# ArgNode local_main_at_Main_internal_3 to s0 +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal ctor_A2I +sw $v0, 16($fp) +# ArgNode local_main_at_Main_internal_3 to s0 +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I a2i +# Load from local_main_at_Main_internal_3 to $s0 +lw $s0, 16($fp) +lw $s1, 12($s0) +addi $s2, $s1, 20 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 8($fp) +addi $sp, $sp, 8 +# Load from local_main_at_Main_internal_1 to $t0 +lw $t0, 8($fp) +sw $t0, 4($fp) +li $s0, 678987 +sw $s0, 28($fp) +# ArgNode local_main_at_Main_internal_6 to s0 +# Load from local_main_at_Main_internal_6 to $s0 +lw $s0, 28($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# Allocate space for A2I +li $a0, 16 +li $v0, 9 +syscall +move $s1, $v0 +sw $s1, 32($fp) +li $s0, 0 +sw $s0, 0($s1) +li $s0, 16 +sw $s0, 4($s1) +la $s0, classname_A2I +sw $s0, 8($s1) +li $s0, 88 +sw $s0, 12($s1) +# ArgNode local_main_at_Main_internal_7 to s0 +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode +jal ctor_A2I +sw $v0, 32($fp) +# ArgNode local_main_at_Main_internal_7 to s0 +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode A2I i2a +# Load from local_main_at_Main_internal_7 to $s0 +lw $s0, 32($fp) +lw $s1, 12($s0) +addi $s2, $s1, 28 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 24($fp) +addi $sp, $sp, 8 +# Load from local_main_at_Main_internal_5 to $t0 +lw $t0, 24($fp) +sw $t0, 20($fp) +# ArgNode local_main_at_Main_a_0 to s0 +# Load from local_main_at_Main_a_0 to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_int +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 16 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 36($fp) +addi $sp, $sp, 8 +# Load from data_19 to $s0 +la $s0, data_19 +sw $s0, 44($fp) +# ArgNode local_main_at_Main_internal_10 to s0 +# Load from local_main_at_Main_internal_10 to $s0 +lw $s0, 44($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 40($fp) +addi $sp, $sp, 8 +# ArgNode local_main_at_Main_b_4 to s0 +# Load from local_main_at_Main_b_4 to $s0 +lw $s0, 20($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 48($fp) +addi $sp, $sp, 8 +# Load from data_20 to $s0 +la $s0, data_20 +sw $s0, 56($fp) +# ArgNode local_main_at_Main_internal_13 to s0 +# Load from local_main_at_Main_internal_13 to $s0 +lw $s0, 56($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# ArgNode self to s0 +# Load from self to $s0 +lw $s0, 4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# DynamicCallNode Main out_string +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 12($s0) +addi $s2, $s1, 12 +addu $s3, $s2, $s7 +lw $s4, 0($s3) +jalr $s4 +sw $v0, 52($fp) +addi $sp, $sp, 8 +# ReturnNode +# Load from local_main_at_Main_internal_12 to $v0 +lw $v0, 52($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 56 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra \ No newline at end of file From 4c3fc63aa1b30d5e449dfb594f910b01d3e7c54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 16 Dec 2020 11:42:13 -0500 Subject: [PATCH 139/191] Redefine Copy Node --- src/engine/codegen/to_mips.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 1675fd81..a481cc55 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -485,16 +485,19 @@ def copy_data(self, src, dst, length): @visitor.when(CopyNode) def visit(self, node): - dst = self.get_offset(node.dest) - length = 0 # TODO: donde saco el size este? - self.mips.la(reg.s1, dst) - # copy data raw byte to byte - self.mips.li(reg.s3, length) - self.copy_data(reg.s0, reg.s1, reg.s3) + self.mips.comment(f"Copy Node {node.dest} {node.obj}") + # load object + self.load_memory(reg.s0, node.obj) + # load size + self.load_memory(reg.s1, self.mips.offset(reg.s0, self.data_size)) + # load dest + self.load_memory(reg.s3, node.dest) + # copy byte to byte + self.copy_data(reg.s0, reg.s3, reg.s1) @visitor.when(TypeNameNode) def visit(self, node: TypeNameNode): - self.mips.comment("TypeNameNode") + self.mips.comment(f"TypeNameNode {node.dest} Type:{node.type}") self.load_memory(reg.t0, node.type) self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, self.data_size)) self.store_memory(reg.t1, node.dest) From 26818b11bf43d9692b8a904d08d1a1e4eca95a4b Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 13:18:26 -0500 Subject: [PATCH 140/191] ctor fix --- src/engine/codegen/to_cil.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 81e08bb8..84de5108 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -76,18 +76,27 @@ def create_constructor(self, attr_declarations: List[cool.AttrDeclarationNode], instance = self.register_param(VariableInfo('self', self.current_type)) scope = Scope() - scope.define_variable('self', instance) + instance = scope.define_variable('self', self.current_type) + + self_instance_name = instance.name for attr in attr_declarations: - self.visit(attr, scope, typex=self.current_type.name) + result = None + if attr.expression: + result = self.visit(attr.expression, scope) + elif attr.type == 'String': + result = self.register_data("").name + else: + result = self.define_internal_local() + self.register_instruction(VoidNode(result)) + + self.register_instruction( + SetAttribNode(self_instance_name, attr.id.lex, result, type_name)) - self.register_instruction(ReturnNode(instance)) + self.register_instruction(ReturnNode(self_instance_name)) self.current_type = None self.current_function = None - def create_vtables(self, node: cool.ProgramNode): - pass - @visitor.on('node') def visit(self, node, scope): pass @@ -97,7 +106,6 @@ def visit(self, node: cool.ProgramNode, scope=None): scope = Scope() self.sort_class_declar(node) self.save_attr_initializations(node, scope) - self.create_vtables(node) # entry self.current_function = self.register_function('entry') instance = self.define_internal_local() From 0617a48fc4acd64645a093057f3e4dc385b67fc1 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 14:02:44 -0500 Subject: [PATCH 141/191] isvoidnode change member name mips-visitor --- src/engine/codegen/to_mips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 1675fd81..687f98f7 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -306,7 +306,7 @@ def visit(self, node: LessNode): @visitor.when(IsVoidNode) def visit(self, node: IsVoidNode): self.mips.comment("IsVoidNode") - self.load_memory(reg.t0, node.body) + self.load_memory(reg.t0, node.expression) label = self.get_label() From 199d18735280d1838cd183b9a9002c4d283065cb Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 16 Dec 2020 14:07:18 -0500 Subject: [PATCH 142/191] store memory the right way --- src/engine/codegen/to_cil.py | 1 - src/engine/codegen/to_mips.py | 30 +- src/test.mips | 1702 +++++++++++++++++++++++++-------- 3 files changed, 1302 insertions(+), 431 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 7f9b5ce0..742a1101 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -239,7 +239,6 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(IfGotoNode(cond, continue_label.label)) self.register_instruction(GotoNode(end_label.label)) self.register_instruction(continue_label) - print(node.body) self.visit(node.body, while_scope) label_counter = self.label_counter_gen() self.register_instruction(GotoNode(start_label.label)) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 1675fd81..bdd4c0f1 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -78,9 +78,9 @@ def load_memory(self, dst, arg: str): offset = ( self.arguments[arg] if arg in self.arguments - else -self.local_vars[arg] + else self.local_vars[arg] ) * self.data_size - + print(offset) self.mips.load_memory(dst, self.mips.offset(reg.fp, offset)) elif arg in self.data_segment: self.mips.la(dst, arg) @@ -88,13 +88,21 @@ def load_memory(self, dst, arg: str): raise Exception( f"load_memory: The direction {arg} isn't an address") - def store_memory(self, dst, arg: str): - if arg in self.local_vars: - offset = -self.local_vars[arg] * self.data_size - self.mips.store_memory(dst, self.mips.offset(reg.fp, offset)) + def store_memory(self, src, dst: str): + + self.mips.comment(f"from src: {src} to dst: {dst}") + if dst in self.arguments or dst in self.local_vars: + offset = ( + self.arguments[dst] + if dst in self.arguments + else self.local_vars[dst] + ) * self.data_size + offset = self.mips.offset(reg.fp, offset) + self.mips.store_memory(src, offset) else: raise Exception( - f"store_memory: The direction {arg} isn't an address") + f"store_memory: The direction {dst} isn't an address") + self.mips.empty_line() def store_registers(self): self.mips.comment("Saving Registers") @@ -162,6 +170,7 @@ def visit(self, node: FunctionNode): self.mips.empty_line() self.mips.comment("Generating body code") for instruction in node.instructions: + print(instruction) self.visit(instruction) self.mips.empty_line() @@ -567,12 +576,17 @@ def visit(self, node: ConcatNode): @visitor.when(StringEqualNode) def visit(self, node: StringEqualNode): + self.mips.empty_line() + self.mips.comment('Comparing Strings --') end_label = self.get_label() end_ok_label = self.get_label() end_wrong_label = self.get_label() loop_label = self.get_label() - self.load_memory(reg.s0, node.msg1) + + self.mips.move(reg.a0, reg.s0) + self.mips.syscall(1) + self.load_memory(reg.s1, node.msg2) self.mips.move(reg.t8, reg.s0) diff --git a/src/test.mips b/src/test.mips index 69e2d5de..c0bb66b5 100644 --- a/src/test.mips +++ b/src/test.mips @@ -64,82 +64,121 @@ li $v0, 9 syscall move $s7, $v0 # Build VTable +# Object_abort la $s0, function_abort_at_Object sw $s0, 0($s7) +# Object_type_name la $s0, function_type_name_at_Object sw $s0, 4($s7) +# Object_copy la $s0, function_copy_at_Object sw $s0, 8($s7) +# String_abort la $s0, function_abort_at_Object sw $s0, 12($s7) +# String_type_name la $s0, function_type_name_at_Object sw $s0, 16($s7) +# String_copy la $s0, function_copy_at_Object sw $s0, 20($s7) +# String_length la $s0, function_length_at_String sw $s0, 24($s7) +# String_concat la $s0, function_concat_at_String sw $s0, 28($s7) +# String_substr la $s0, function_substr_at_String sw $s0, 32($s7) +# IO_abort la $s0, function_abort_at_Object sw $s0, 36($s7) +# IO_type_name la $s0, function_type_name_at_Object sw $s0, 40($s7) +# IO_copy la $s0, function_copy_at_Object sw $s0, 44($s7) +# IO_out_string la $s0, function_out_string_at_IO sw $s0, 48($s7) +# IO_out_int la $s0, function_out_int_at_IO sw $s0, 52($s7) +# IO_in_string la $s0, function_in_string_at_IO sw $s0, 56($s7) +# IO_in_int la $s0, function_in_int_at_IO sw $s0, 60($s7) +# Int_abort la $s0, function_abort_at_Object sw $s0, 64($s7) +# Int_type_name la $s0, function_type_name_at_Object sw $s0, 68($s7) +# Int_copy la $s0, function_copy_at_Object sw $s0, 72($s7) +# Bool_abort la $s0, function_abort_at_Object sw $s0, 76($s7) +# Bool_type_name la $s0, function_type_name_at_Object sw $s0, 80($s7) +# Bool_copy la $s0, function_copy_at_Object sw $s0, 84($s7) +# A2I_abort la $s0, function_abort_at_Object sw $s0, 88($s7) +# A2I_type_name la $s0, function_type_name_at_Object sw $s0, 92($s7) +# A2I_copy la $s0, function_copy_at_Object sw $s0, 96($s7) +# A2I_c2i la $s0, function_c2i_at_A2I sw $s0, 100($s7) +# A2I_i2c la $s0, function_i2c_at_A2I sw $s0, 104($s7) +# A2I_a2i la $s0, function_a2i_at_A2I sw $s0, 108($s7) +# A2I_a2i_aux la $s0, function_a2i_aux_at_A2I sw $s0, 112($s7) +# A2I_i2a la $s0, function_i2a_at_A2I sw $s0, 116($s7) +# A2I_i2a_aux la $s0, function_i2a_aux_at_A2I sw $s0, 120($s7) +# Main_abort la $s0, function_abort_at_Object sw $s0, 124($s7) +# Main_type_name la $s0, function_type_name_at_Object sw $s0, 128($s7) +# Main_copy la $s0, function_copy_at_Object sw $s0, 132($s7) +# Main_out_string la $s0, function_out_string_at_IO sw $s0, 136($s7) +# Main_out_int la $s0, function_out_int_at_IO sw $s0, 140($s7) +# Main_in_string la $s0, function_in_string_at_IO sw $s0, 144($s7) +# Main_in_int la $s0, function_in_int_at_IO sw $s0, 148($s7) +# Main_main la $s0, function_main_at_Main sw $s0, 152($s7) jal entry @@ -179,11 +218,13 @@ sw $s6, 0($sp) # Load from self to $t0 lw $t0, 4($fp) lw $t1, 4($t0) -sw $t1, 4($fp) +# from src: $t1 to dst: local_abort_at_Object_internal_0 +sw $t1, -4($fp) + # Load from data_0 to $s0 la $s0, data_0 # Load from local_abort_at_Object_internal_0 to $s1 -lw $s1, 4($fp) +lw $s1, -4($fp) move $t0, $s0 li $t1, 0 mips_label_1: @@ -230,9 +271,11 @@ addi $t1, $t1, 1 j mips_label_7 mips_label_8: move $v0, $t1 -sw $s3, 8($fp) +# from src: $s3 to dst: local_abort_at_Object_internal_1 +sw $s3, -8($fp) + # Load from local_abort_at_Object_internal_1 to $s0 -lw $s0, 8($fp) +lw $s0, -8($fp) # Load from data_1 to $s1 la $s1, data_1 move $t0, $s0 @@ -281,10 +324,12 @@ addi $t1, $t1, 1 j mips_label_15 mips_label_16: move $v0, $t1 -sw $s3, 12($fp) +# from src: $s3 to dst: local_abort_at_Object_internal_2 +sw $s3, -12($fp) + # Print str local_abort_at_Object_internal_2 # Load from local_abort_at_Object_internal_2 to $a0 -lw $a0, 12($fp) +lw $a0, -12($fp) li $v0, 4 syscall li $v0, 10 @@ -360,7 +405,7 @@ j mips_label_17 mips_label_18: # ReturnNode # Load from local_copy_at_Object_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -419,15 +464,19 @@ sw $s6, 0($sp) # Load from self to $s0 lw $s0, 4($fp) lw $s1, 3($s0) -sw $s1, 8($fp) +# from src: $s1 to dst: local_type_name_at_Object_internal_1 +sw $s1, -8($fp) + # TypeNameNode # Load from local_type_name_at_Object_internal_1 to $t0 -lw $t0, 8($fp) +lw $t0, -8($fp) lw $t1, 4($t0) -sw $t1, 4($fp) +# from src: $t1 to dst: local_type_name_at_Object_internal_0 +sw $t1, -4($fp) + # ReturnNode # Load from local_type_name_at_Object_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -495,10 +544,12 @@ addi $t0, $t0, 1 j mips_label_19 mips_label_20: move $s0, $t1 -sw $s0, 4($fp) +# from src: $s0 to dst: local_length_at_String_internal_0 +sw $s0, -4($fp) + # ReturnNode # Load from local_length_at_String_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -603,10 +654,12 @@ addi $t1, $t1, 1 j mips_label_27 mips_label_28: move $v0, $t1 -sw $s3, 4($fp) +# from src: $s3 to dst: local_concat_at_String_internal_0 +sw $s3, -4($fp) + # ReturnNode # Load from local_concat_at_String_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -662,7 +715,9 @@ sw $s6, 0($sp) # Generating body code li $s0, 0 -sw $s0, 16($fp) +# from src: $s0 to dst: local_substr_at_String_internal_3 +sw $s0, -16($fp) + # LengthNode # Load from self to $s1 lw $s1, 4($fp) @@ -676,18 +731,22 @@ addi $t0, $t0, 1 j mips_label_29 mips_label_30: move $s0, $t1 -sw $s0, 12($fp) +# from src: $s0 to dst: local_substr_at_String_internal_2 +sw $s0, -12($fp) + # Load from local_substr_at_String_internal_3 to $t0 -lw $t0, 16($fp) +lw $t0, -16($fp) # Load from start to $t1 lw $t1, 8($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -sw $t0, 24($fp) +# from src: $t0 to dst: local_substr_at_String_internal_5 +sw $t0, -24($fp) + # IfGotoNode # Load from local_substr_at_String_internal_5 to $t0 -lw $t0, 24($fp) +lw $t0, -24($fp) li $t1, 0 bne $t0, $t1, error1 # Load from data_2 to $s0 @@ -740,10 +799,12 @@ addi $t1, $t1, 1 j mips_label_37 mips_label_38: move $v0, $t1 -sw $s3, 36($fp) +# from src: $s3 to dst: local_substr_at_String_internal_8 +sw $s3, -36($fp) + # Print str local_substr_at_String_internal_8 # Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) +lw $a0, -36($fp) li $v0, 4 syscall # ErrorNode @@ -752,16 +813,18 @@ li $v0, 17 syscall error1: # Load from local_substr_at_String_internal_3 to $t0 -lw $t0, 16($fp) +lw $t0, -16($fp) # Load from length to $t1 lw $t1, 12($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -sw $t0, 28($fp) +# from src: $t0 to dst: local_substr_at_String_internal_6 +sw $t0, -28($fp) + # IfGotoNode # Load from local_substr_at_String_internal_6 to $t0 -lw $t0, 28($fp) +lw $t0, -28($fp) li $t1, 0 bne $t0, $t1, error2 # Load from data_3 to $s0 @@ -814,10 +877,12 @@ addi $t1, $t1, 1 j mips_label_45 mips_label_46: move $v0, $t1 -sw $s3, 36($fp) +# from src: $s3 to dst: local_substr_at_String_internal_8 +sw $s3, -36($fp) + # Print str local_substr_at_String_internal_8 # Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) +lw $a0, -36($fp) li $v0, 4 syscall # ErrorNode @@ -830,18 +895,22 @@ lw $t0, 8($fp) # Load from length to $t1 lw $t1, 12($fp) add $t2, $t0, $t1 -sw $t2, 20($fp) +# from src: $t2 to dst: local_substr_at_String_internal_4 +sw $t2, -20($fp) + # Load from local_substr_at_String_internal_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) # Load from local_substr_at_String_internal_2 to $t1 -lw $t1, 12($fp) +lw $t1, -12($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -sw $t0, 32($fp) +# from src: $t0 to dst: local_substr_at_String_internal_7 +sw $t0, -32($fp) + # IfGotoNode # Load from local_substr_at_String_internal_7 to $t0 -lw $t0, 32($fp) +lw $t0, -32($fp) li $t1, 0 bne $t0, $t1, error3 # Load from data_4 to $s0 @@ -894,10 +963,12 @@ addi $t1, $t1, 1 j mips_label_53 mips_label_54: move $v0, $t1 -sw $s3, 36($fp) +# from src: $s3 to dst: local_substr_at_String_internal_8 +sw $s3, -36($fp) + # Print str local_substr_at_String_internal_8 # Load from local_substr_at_String_internal_8 to $a0 -lw $a0, 36($fp) +lw $a0, -36($fp) li $v0, 4 syscall # ErrorNode @@ -929,10 +1000,12 @@ j mips_label_55 mips_label_56: move $t2, $zero sb $t2, 0($t1) -sw $v0, 4($fp) +# from src: $v0 to dst: local_substr_at_String_internal_0 +sw $v0, -4($fp) + # ReturnNode # Load from local_substr_at_String_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -1053,13 +1126,15 @@ li $a0, 1024 li $v0, 9 syscall move $a0, $v0 -sw $v0, 4($fp) +# from src: $v0 to dst: local_in_string_at_IO_internal_0 +sw $v0, -4($fp) + li $a1, 1024 li $v0, 8 syscall # ReturnNode # Load from local_in_string_at_IO_internal_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -1177,9 +1252,269 @@ sw $s6, 0($sp) # Generating body code li $v0, 5 syscall -sw $v0, 4($fp) +# from src: $v0 to dst: local_in_int_at_IO_internal_0 +sw $v0, -4($fp) + # ReturnNode # Load from local_in_int_at_IO_internal_0 to $v0 +lw $v0, -4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_IO: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_Int: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# from src: $zero to dst: local__internal_0 +sw $zero, -4($fp) + +# SetAttribNode self.value Type:Int = local__internal_0 +# Load from self to $s0 +lw $s0, 4($fp) +# SET local var local__internal_0 +# Load from local__internal_0 to $s1 +lw $s1, -4($fp) +sw $s1, 16($s0) +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_String: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# from src: $zero to dst: local_ng_internal_0 +sw $zero, -4($fp) + +# SetAttribNode self.value Type:String = local_ng_internal_0 +# Load from self to $s0 +lw $s0, 4($fp) +# SET local var local_ng_internal_0 +# Load from local_ng_internal_0 to $s1 +lw $s1, -4($fp) +sw $s1, 16($s0) +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 4 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra +ctor_Bool: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, -4 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# from src: $zero to dst: local__internal_0 +sw $zero, -4($fp) + +# SetAttribNode self.value Type:Bool = local__internal_0 +# Load from self to $s0 +lw $s0, 4($fp) +# SET local var local__internal_0 +# Load from local__internal_0 to $s1 +lw $s1, -4($fp) +sw $s1, 16($s0) +# ReturnNode +# Load from self to $v0 lw $v0, 4($fp) # Restore registers @@ -1206,6 +1541,63 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra +ctor_Object: +# Set stack frame +addi $sp, $sp, -4 +sw $fp, 0($sp) +move $fp, $sp + +# Allocate memory for Local variables +addi $sp, $sp, 0 + + +# Saving Registers +addi $sp, $sp, -4 +sw $ra, 0($sp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +addi $sp, $sp, -4 +sw $s1, 0($sp) +addi $sp, $sp, -4 +sw $s2, 0($sp) +addi $sp, $sp, -4 +sw $s3, 0($sp) +addi $sp, $sp, -4 +sw $s4, 0($sp) +addi $sp, $sp, -4 +sw $s5, 0($sp) +addi $sp, $sp, -4 +sw $s6, 0($sp) + +# Generating body code +# ReturnNode +# Load from self to $v0 +lw $v0, 4($fp) + +# Restore registers +lw $s6, 0($sp) +addi $sp, $sp, 4 +lw $s5, 0($sp) +addi $sp, $sp, 4 +lw $s4, 0($sp) +addi $sp, $sp, 4 +lw $s3, 0($sp) +addi $sp, $sp, 4 +lw $s2, 0($sp) +addi $sp, $sp, 4 +lw $s1, 0($sp) +addi $sp, $sp, 4 +lw $s0, 0($sp) +addi $sp, $sp, 4 +lw $ra, 0($sp) +addi $sp, $sp, 4 + +# Clean stack variable space +addi $sp, $sp, 0 +# Return +lw $fp, 0($sp) +addi $sp, $sp, 4 +jr $ra ctor_A2I: # Set stack frame addi $sp, $sp, -4 @@ -1354,8 +1746,10 @@ li $a0, 16 li $v0, 9 syscall move $s1, $v0 -sw $s1, 4($fp) -li $s0, 0 +# from src: $s1 to dst: local__internal_0 +sw $s1, -4($fp) + +li $s0, 6 sw $s0, 0($s1) li $s0, 16 sw $s0, 4($s1) @@ -1365,12 +1759,14 @@ li $s0, 124 sw $s0, 12($s1) # ArgNode local__internal_0 to s0 # Load from local__internal_0 to $s0 -lw $s0, 4($fp) +lw $s0, -4($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # StaticCallNode jal function_main_at_Main -sw $v0, 8($fp) +# from src: $v0 to dst: local__internal_1 +sw $v0, -8($fp) + addi $sp, $sp, 4 # Restore registers @@ -1428,11 +1824,18 @@ sw $s6, 0($sp) # Generating body code # Load from data_5 to $s0 la $s0, data_5 -sw $s0, 4($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_0 +sw $s0, -4($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_0 to $s1 -lw $s1, 4($fp) +lw $s1, -4($fp) move $t8, $s0 move $t9, $s1 mips_label_60: @@ -1452,19 +1855,28 @@ mips_label_58: bnez $a1, mips_label_59 li $v0, 1 mips_label_57: -sw $v0, 8($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_1 +sw $v0, -8($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) +lw $t0, -8($fp) li $t1, 0 bne $t0, $t1, TRUE_1 # Load from data_6 to $s0 la $s0, data_6 -sw $s0, 16($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_3 +sw $s0, -16($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_3 to $s1 -lw $s1, 16($fp) +lw $s1, -16($fp) move $t8, $s0 move $t9, $s1 mips_label_64: @@ -1484,19 +1896,28 @@ mips_label_62: bnez $a1, mips_label_63 li $v0, 1 mips_label_61: -sw $v0, 20($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_4 +sw $v0, -20($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) li $t1, 0 bne $t0, $t1, TRUE_2 # Load from data_7 to $s0 la $s0, data_7 -sw $s0, 28($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_6 +sw $s0, -28($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_6 to $s1 -lw $s1, 28($fp) +lw $s1, -28($fp) move $t8, $s0 move $t9, $s1 mips_label_68: @@ -1516,19 +1937,28 @@ mips_label_66: bnez $a1, mips_label_67 li $v0, 1 mips_label_65: -sw $v0, 32($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_7 +sw $v0, -32($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) +lw $t0, -32($fp) li $t1, 0 bne $t0, $t1, TRUE_3 # Load from data_8 to $s0 la $s0, data_8 -sw $s0, 40($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_9 +sw $s0, -40($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_9 to $s1 -lw $s1, 40($fp) +lw $s1, -40($fp) move $t8, $s0 move $t9, $s1 mips_label_72: @@ -1548,19 +1978,28 @@ mips_label_70: bnez $a1, mips_label_71 li $v0, 1 mips_label_69: -sw $v0, 44($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_10 +sw $v0, -44($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) +lw $t0, -44($fp) li $t1, 0 bne $t0, $t1, TRUE_4 # Load from data_9 to $s0 la $s0, data_9 -sw $s0, 52($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_12 +sw $s0, -52($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_12 to $s1 -lw $s1, 52($fp) +lw $s1, -52($fp) move $t8, $s0 move $t9, $s1 mips_label_76: @@ -1580,19 +2019,28 @@ mips_label_74: bnez $a1, mips_label_75 li $v0, 1 mips_label_73: -sw $v0, 56($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_13 +sw $v0, -56($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) +lw $t0, -56($fp) li $t1, 0 bne $t0, $t1, TRUE_5 # Load from data_10 to $s0 la $s0, data_10 -sw $s0, 64($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_15 +sw $s0, -64($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_15 to $s1 -lw $s1, 64($fp) +lw $s1, -64($fp) move $t8, $s0 move $t9, $s1 mips_label_80: @@ -1612,19 +2060,28 @@ mips_label_78: bnez $a1, mips_label_79 li $v0, 1 mips_label_77: -sw $v0, 68($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_16 +sw $v0, -68($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) +lw $t0, -68($fp) li $t1, 0 bne $t0, $t1, TRUE_6 # Load from data_11 to $s0 la $s0, data_11 -sw $s0, 76($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_18 +sw $s0, -76($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_18 to $s1 -lw $s1, 76($fp) +lw $s1, -76($fp) move $t8, $s0 move $t9, $s1 mips_label_84: @@ -1644,19 +2101,28 @@ mips_label_82: bnez $a1, mips_label_83 li $v0, 1 mips_label_81: -sw $v0, 80($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_19 +sw $v0, -80($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_19 to $t0 -lw $t0, 80($fp) +lw $t0, -80($fp) li $t1, 0 bne $t0, $t1, TRUE_7 # Load from data_12 to $s0 la $s0, data_12 -sw $s0, 88($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_21 +sw $s0, -88($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_21 to $s1 -lw $s1, 88($fp) +lw $s1, -88($fp) move $t8, $s0 move $t9, $s1 mips_label_88: @@ -1676,19 +2142,28 @@ mips_label_86: bnez $a1, mips_label_87 li $v0, 1 mips_label_85: -sw $v0, 92($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_22 +sw $v0, -92($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_22 to $t0 -lw $t0, 92($fp) +lw $t0, -92($fp) li $t1, 0 bne $t0, $t1, TRUE_8 # Load from data_13 to $s0 la $s0, data_13 -sw $s0, 100($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_24 +sw $s0, -100($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_24 to $s1 -lw $s1, 100($fp) +lw $s1, -100($fp) move $t8, $s0 move $t9, $s1 mips_label_92: @@ -1708,19 +2183,28 @@ mips_label_90: bnez $a1, mips_label_91 li $v0, 1 mips_label_89: -sw $v0, 104($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_25 +sw $v0, -104($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_25 to $t0 -lw $t0, 104($fp) +lw $t0, -104($fp) li $t1, 0 bne $t0, $t1, TRUE_9 # Load from data_14 to $s0 la $s0, data_14 -sw $s0, 112($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_27 +sw $s0, -112($fp) + + +# Comparing Strings -- # Load from char to $s0 lw $s0, 8($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_c2i_at_A2I_internal_27 to $s1 -lw $s1, 112($fp) +lw $s1, -112($fp) move $t8, $s0 move $t9, $s1 mips_label_96: @@ -1740,10 +2224,12 @@ mips_label_94: bnez $a1, mips_label_95 li $v0, 1 mips_label_93: -sw $v0, 116($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_28 +sw $v0, -116($fp) + # IfGotoNode # Load from local_c2i_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) +lw $t0, -116($fp) li $t1, 0 bne $t0, $t1, TRUE_10 # ArgNode self to s0 @@ -1759,133 +2245,197 @@ addi $s2, $s1, 0 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 124($fp) +# from src: $v0 to dst: local_c2i_at_A2I_internal_30 +sw $v0, -124($fp) + addi $sp, $sp, 4 li $s0, 0 -sw $s0, 128($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_31 +sw $s0, -128($fp) + # Load from local_c2i_at_A2I_internal_31 to $t0 -lw $t0, 128($fp) -sw $t0, 120($fp) +lw $t0, -128($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_29 +sw $t0, -120($fp) + # GotoNode j END_10 TRUE_10: li $s0, 9 -sw $s0, 132($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_32 +sw $s0, -132($fp) + # Load from local_c2i_at_A2I_internal_32 to $t0 -lw $t0, 132($fp) -sw $t0, 120($fp) +lw $t0, -132($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_29 +sw $t0, -120($fp) + END_10: # Load from local_c2i_at_A2I_internal_29 to $t0 -lw $t0, 120($fp) -sw $t0, 108($fp) +lw $t0, -120($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_26 +sw $t0, -108($fp) + # GotoNode j END_9 TRUE_9: li $s0, 8 -sw $s0, 136($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_33 +sw $s0, -136($fp) + # Load from local_c2i_at_A2I_internal_33 to $t0 -lw $t0, 136($fp) -sw $t0, 108($fp) +lw $t0, -136($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_26 +sw $t0, -108($fp) + END_9: # Load from local_c2i_at_A2I_internal_26 to $t0 -lw $t0, 108($fp) -sw $t0, 96($fp) +lw $t0, -108($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_23 +sw $t0, -96($fp) + # GotoNode j END_8 TRUE_8: li $s0, 7 -sw $s0, 140($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_34 +sw $s0, -140($fp) + # Load from local_c2i_at_A2I_internal_34 to $t0 -lw $t0, 140($fp) -sw $t0, 96($fp) +lw $t0, -140($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_23 +sw $t0, -96($fp) + END_8: # Load from local_c2i_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 84($fp) +lw $t0, -96($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_20 +sw $t0, -84($fp) + # GotoNode j END_7 TRUE_7: li $s0, 6 -sw $s0, 144($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_35 +sw $s0, -144($fp) + # Load from local_c2i_at_A2I_internal_35 to $t0 -lw $t0, 144($fp) -sw $t0, 84($fp) +lw $t0, -144($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_20 +sw $t0, -84($fp) + END_7: # Load from local_c2i_at_A2I_internal_20 to $t0 -lw $t0, 84($fp) -sw $t0, 72($fp) +lw $t0, -84($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_17 +sw $t0, -72($fp) + # GotoNode j END_6 TRUE_6: li $s0, 5 -sw $s0, 148($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_36 +sw $s0, -148($fp) + # Load from local_c2i_at_A2I_internal_36 to $t0 -lw $t0, 148($fp) -sw $t0, 72($fp) +lw $t0, -148($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_17 +sw $t0, -72($fp) + END_6: # Load from local_c2i_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 60($fp) +lw $t0, -72($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_14 +sw $t0, -60($fp) + # GotoNode j END_5 TRUE_5: li $s0, 4 -sw $s0, 152($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_37 +sw $s0, -152($fp) + # Load from local_c2i_at_A2I_internal_37 to $t0 -lw $t0, 152($fp) -sw $t0, 60($fp) +lw $t0, -152($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_14 +sw $t0, -60($fp) + END_5: # Load from local_c2i_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) -sw $t0, 48($fp) +lw $t0, -60($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_11 +sw $t0, -48($fp) + # GotoNode j END_4 TRUE_4: li $s0, 3 -sw $s0, 156($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_38 +sw $s0, -156($fp) + # Load from local_c2i_at_A2I_internal_38 to $t0 -lw $t0, 156($fp) -sw $t0, 48($fp) +lw $t0, -156($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_11 +sw $t0, -48($fp) + END_4: # Load from local_c2i_at_A2I_internal_11 to $t0 -lw $t0, 48($fp) -sw $t0, 36($fp) +lw $t0, -48($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_8 +sw $t0, -36($fp) + # GotoNode j END_3 TRUE_3: li $s0, 2 -sw $s0, 160($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_39 +sw $s0, -160($fp) + # Load from local_c2i_at_A2I_internal_39 to $t0 -lw $t0, 160($fp) -sw $t0, 36($fp) +lw $t0, -160($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_8 +sw $t0, -36($fp) + END_3: # Load from local_c2i_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -sw $t0, 24($fp) +lw $t0, -36($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_5 +sw $t0, -24($fp) + # GotoNode j END_2 TRUE_2: li $s0, 1 -sw $s0, 164($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_40 +sw $s0, -164($fp) + # Load from local_c2i_at_A2I_internal_40 to $t0 -lw $t0, 164($fp) -sw $t0, 24($fp) +lw $t0, -164($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_5 +sw $t0, -24($fp) + END_2: # Load from local_c2i_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) +lw $t0, -24($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_2 +sw $t0, -12($fp) + # GotoNode j END_1 TRUE_1: li $s0, 0 -sw $s0, 168($fp) +# from src: $s0 to dst: local_c2i_at_A2I_internal_41 +sw $s0, -168($fp) + # Load from local_c2i_at_A2I_internal_41 to $t0 -lw $t0, 168($fp) -sw $t0, 12($fp) +lw $t0, -168($fp) +# from src: $t0 to dst: local_c2i_at_A2I_internal_2 +sw $t0, -12($fp) + END_1: # ReturnNode # Load from local_c2i_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) +lw $v0, -12($fp) # Restore registers lw $s6, 0($sp) @@ -1941,163 +2491,203 @@ sw $s6, 0($sp) # Generating body code li $s0, 0 -sw $s0, 4($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_0 +sw $s0, -4($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) +lw $t1, -4($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 8($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_1 +sw $t1, -8($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) +lw $t0, -8($fp) li $t1, 0 bne $t0, $t1, TRUE_21 li $s0, 1 -sw $s0, 16($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_3 +sw $s0, -16($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_3 to $t1 -lw $t1, 16($fp) +lw $t1, -16($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 20($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_4 +sw $t1, -20($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) li $t1, 0 bne $t0, $t1, TRUE_22 li $s0, 2 -sw $s0, 28($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_6 +sw $s0, -28($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_6 to $t1 -lw $t1, 28($fp) +lw $t1, -28($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 32($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_7 +sw $t1, -32($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) +lw $t0, -32($fp) li $t1, 0 bne $t0, $t1, TRUE_23 li $s0, 3 -sw $s0, 40($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_9 +sw $s0, -40($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) +lw $t1, -40($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 44($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_10 +sw $t1, -44($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) +lw $t0, -44($fp) li $t1, 0 bne $t0, $t1, TRUE_24 li $s0, 4 -sw $s0, 52($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_12 +sw $s0, -52($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_12 to $t1 -lw $t1, 52($fp) +lw $t1, -52($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 56($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_13 +sw $t1, -56($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) +lw $t0, -56($fp) li $t1, 0 bne $t0, $t1, TRUE_25 li $s0, 5 -sw $s0, 64($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_15 +sw $s0, -64($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_15 to $t1 -lw $t1, 64($fp) +lw $t1, -64($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 68($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_16 +sw $t1, -68($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) +lw $t0, -68($fp) li $t1, 0 bne $t0, $t1, TRUE_26 li $s0, 6 -sw $s0, 76($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_18 +sw $s0, -76($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_18 to $t1 -lw $t1, 76($fp) +lw $t1, -76($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 80($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_19 +sw $t1, -80($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_19 to $t0 -lw $t0, 80($fp) +lw $t0, -80($fp) li $t1, 0 bne $t0, $t1, TRUE_27 li $s0, 7 -sw $s0, 88($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_21 +sw $s0, -88($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_21 to $t1 -lw $t1, 88($fp) +lw $t1, -88($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 92($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_22 +sw $t1, -92($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_22 to $t0 -lw $t0, 92($fp) +lw $t0, -92($fp) li $t1, 0 bne $t0, $t1, TRUE_28 li $s0, 8 -sw $s0, 100($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_24 +sw $s0, -100($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_24 to $t1 -lw $t1, 100($fp) +lw $t1, -100($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 104($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_25 +sw $t1, -104($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_25 to $t0 -lw $t0, 104($fp) +lw $t0, -104($fp) li $t1, 0 bne $t0, $t1, TRUE_29 li $s0, 9 -sw $s0, 112($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_27 +sw $s0, -112($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2c_at_A2I_internal_27 to $t1 -lw $t1, 112($fp) +lw $t1, -112($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 116($fp) +# from src: $t1 to dst: local_i2c_at_A2I_internal_28 +sw $t1, -116($fp) + # IfGotoNode # Load from local_i2c_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) +lw $t0, -116($fp) li $t1, 0 bne $t0, $t1, TRUE_30 # ArgNode self to s0 @@ -2113,144 +2703,208 @@ addi $s2, $s1, 0 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 124($fp) +# from src: $v0 to dst: local_i2c_at_A2I_internal_30 +sw $v0, -124($fp) + addi $sp, $sp, 4 # Load from data_15 to $s0 la $s0, data_15 -sw $s0, 128($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_31 +sw $s0, -128($fp) + # Load from local_i2c_at_A2I_internal_31 to $t0 -lw $t0, 128($fp) -sw $t0, 120($fp) +lw $t0, -128($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_29 +sw $t0, -120($fp) + # GotoNode j END_30 TRUE_30: # Load from data_14 to $s0 la $s0, data_14 -sw $s0, 132($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_32 +sw $s0, -132($fp) + # Load from local_i2c_at_A2I_internal_32 to $t0 -lw $t0, 132($fp) -sw $t0, 120($fp) +lw $t0, -132($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_29 +sw $t0, -120($fp) + END_30: # Load from local_i2c_at_A2I_internal_29 to $t0 -lw $t0, 120($fp) -sw $t0, 108($fp) +lw $t0, -120($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_26 +sw $t0, -108($fp) + # GotoNode j END_29 TRUE_29: # Load from data_13 to $s0 la $s0, data_13 -sw $s0, 136($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_33 +sw $s0, -136($fp) + # Load from local_i2c_at_A2I_internal_33 to $t0 -lw $t0, 136($fp) -sw $t0, 108($fp) +lw $t0, -136($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_26 +sw $t0, -108($fp) + END_29: # Load from local_i2c_at_A2I_internal_26 to $t0 -lw $t0, 108($fp) -sw $t0, 96($fp) +lw $t0, -108($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_23 +sw $t0, -96($fp) + # GotoNode j END_28 TRUE_28: # Load from data_12 to $s0 la $s0, data_12 -sw $s0, 140($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_34 +sw $s0, -140($fp) + # Load from local_i2c_at_A2I_internal_34 to $t0 -lw $t0, 140($fp) -sw $t0, 96($fp) +lw $t0, -140($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_23 +sw $t0, -96($fp) + END_28: # Load from local_i2c_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 84($fp) +lw $t0, -96($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_20 +sw $t0, -84($fp) + # GotoNode j END_27 TRUE_27: # Load from data_11 to $s0 la $s0, data_11 -sw $s0, 144($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_35 +sw $s0, -144($fp) + # Load from local_i2c_at_A2I_internal_35 to $t0 -lw $t0, 144($fp) -sw $t0, 84($fp) +lw $t0, -144($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_20 +sw $t0, -84($fp) + END_27: # Load from local_i2c_at_A2I_internal_20 to $t0 -lw $t0, 84($fp) -sw $t0, 72($fp) +lw $t0, -84($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_17 +sw $t0, -72($fp) + # GotoNode j END_26 TRUE_26: # Load from data_10 to $s0 la $s0, data_10 -sw $s0, 148($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_36 +sw $s0, -148($fp) + # Load from local_i2c_at_A2I_internal_36 to $t0 -lw $t0, 148($fp) -sw $t0, 72($fp) +lw $t0, -148($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_17 +sw $t0, -72($fp) + END_26: # Load from local_i2c_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 60($fp) +lw $t0, -72($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_14 +sw $t0, -60($fp) + # GotoNode j END_25 TRUE_25: # Load from data_9 to $s0 la $s0, data_9 -sw $s0, 152($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_37 +sw $s0, -152($fp) + # Load from local_i2c_at_A2I_internal_37 to $t0 -lw $t0, 152($fp) -sw $t0, 60($fp) +lw $t0, -152($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_14 +sw $t0, -60($fp) + END_25: # Load from local_i2c_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) -sw $t0, 48($fp) +lw $t0, -60($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_11 +sw $t0, -48($fp) + # GotoNode j END_24 TRUE_24: # Load from data_8 to $s0 la $s0, data_8 -sw $s0, 156($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_38 +sw $s0, -156($fp) + # Load from local_i2c_at_A2I_internal_38 to $t0 -lw $t0, 156($fp) -sw $t0, 48($fp) +lw $t0, -156($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_11 +sw $t0, -48($fp) + END_24: # Load from local_i2c_at_A2I_internal_11 to $t0 -lw $t0, 48($fp) -sw $t0, 36($fp) +lw $t0, -48($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_8 +sw $t0, -36($fp) + # GotoNode j END_23 TRUE_23: # Load from data_7 to $s0 la $s0, data_7 -sw $s0, 160($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_39 +sw $s0, -160($fp) + # Load from local_i2c_at_A2I_internal_39 to $t0 -lw $t0, 160($fp) -sw $t0, 36($fp) +lw $t0, -160($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_8 +sw $t0, -36($fp) + END_23: # Load from local_i2c_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) -sw $t0, 24($fp) +lw $t0, -36($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_5 +sw $t0, -24($fp) + # GotoNode j END_22 TRUE_22: # Load from data_6 to $s0 la $s0, data_6 -sw $s0, 164($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_40 +sw $s0, -164($fp) + # Load from local_i2c_at_A2I_internal_40 to $t0 -lw $t0, 164($fp) -sw $t0, 24($fp) +lw $t0, -164($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_5 +sw $t0, -24($fp) + END_22: # Load from local_i2c_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) +lw $t0, -24($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_2 +sw $t0, -12($fp) + # GotoNode j END_21 TRUE_21: # Load from data_5 to $s0 la $s0, data_5 -sw $s0, 168($fp) +# from src: $s0 to dst: local_i2c_at_A2I_internal_41 +sw $s0, -168($fp) + # Load from local_i2c_at_A2I_internal_41 to $t0 -lw $t0, 168($fp) -sw $t0, 12($fp) +lw $t0, -168($fp) +# from src: $t0 to dst: local_i2c_at_A2I_internal_2 +sw $t0, -12($fp) + END_21: # ReturnNode # Load from local_i2c_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) +lw $v0, -12($fp) # Restore registers lw $s6, 0($sp) @@ -2318,36 +2972,46 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 4($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_0 +sw $v0, -4($fp) + addi $sp, $sp, 4 li $s0, 0 -sw $s0, 8($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_1 +sw $s0, -8($fp) + # Load from local_a2i_at_A2I_internal_0 to $t0 -lw $t0, 4($fp) +lw $t0, -4($fp) # Load from local_a2i_at_A2I_internal_1 to $t1 -lw $t1, 8($fp) +lw $t1, -8($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 12($fp) +# from src: $t1 to dst: local_a2i_at_A2I_internal_2 +sw $t1, -12($fp) + # IfGotoNode # Load from local_a2i_at_A2I_internal_2 to $t0 -lw $t0, 12($fp) +lw $t0, -12($fp) li $t1, 0 bne $t0, $t1, TRUE_41 li $s0, 0 -sw $s0, 24($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_5 +sw $s0, -24($fp) + li $s0, 1 -sw $s0, 28($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_6 +sw $s0, -28($fp) + # ArgNode local_a2i_at_A2I_internal_6 to s0 # Load from local_a2i_at_A2I_internal_6 to $s0 -lw $s0, 28($fp) +lw $s0, -28($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_a2i_at_A2I_internal_5 to s0 # Load from local_a2i_at_A2I_internal_5 to $s0 -lw $s0, 24($fp) +lw $s0, -24($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode s to s0 @@ -2363,15 +3027,24 @@ addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 20($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_4 +sw $v0, -20($fp) + addi $sp, $sp, 12 # Load from data_16 to $s0 la $s0, data_16 -sw $s0, 32($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_7 +sw $s0, -32($fp) + + +# Comparing Strings -- # Load from local_a2i_at_A2I_internal_4 to $s0 -lw $s0, 20($fp) +lw $s0, -20($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_a2i_at_A2I_internal_7 to $s1 -lw $s1, 32($fp) +lw $s1, -32($fp) move $t8, $s0 move $t9, $s1 mips_label_100: @@ -2391,24 +3064,30 @@ mips_label_98: bnez $a1, mips_label_99 li $v0, 1 mips_label_97: -sw $v0, 36($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_8 +sw $v0, -36($fp) + # IfGotoNode # Load from local_a2i_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) +lw $t0, -36($fp) li $t1, 0 bne $t0, $t1, TRUE_42 li $s0, 0 -sw $s0, 48($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_11 +sw $s0, -48($fp) + li $s0, 1 -sw $s0, 52($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_12 +sw $s0, -52($fp) + # ArgNode local_a2i_at_A2I_internal_12 to s0 # Load from local_a2i_at_A2I_internal_12 to $s0 -lw $s0, 52($fp) +lw $s0, -52($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_a2i_at_A2I_internal_11 to s0 # Load from local_a2i_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode s to s0 @@ -2424,15 +3103,24 @@ addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 44($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_10 +sw $v0, -44($fp) + addi $sp, $sp, 12 # Load from data_17 to $s0 la $s0, data_17 -sw $s0, 56($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_13 +sw $s0, -56($fp) + + +# Comparing Strings -- # Load from local_a2i_at_A2I_internal_10 to $s0 -lw $s0, 44($fp) +lw $s0, -44($fp) +move $a0, $s0 +li $v0, 1 +syscall # Load from local_a2i_at_A2I_internal_13 to $s1 -lw $s1, 56($fp) +lw $s1, -56($fp) move $t8, $s0 move $t9, $s1 mips_label_104: @@ -2452,10 +3140,12 @@ mips_label_102: bnez $a1, mips_label_103 li $v0, 1 mips_label_101: -sw $v0, 60($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_14 +sw $v0, -60($fp) + # IfGotoNode # Load from local_a2i_at_A2I_internal_14 to $t0 -lw $t0, 60($fp) +lw $t0, -60($fp) li $t1, 0 bne $t0, $t1, TRUE_43 # ArgNode s to s0 @@ -2476,16 +3166,22 @@ addi $s2, $s1, 24 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 68($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_16 +sw $v0, -68($fp) + addi $sp, $sp, 8 # Load from local_a2i_at_A2I_internal_16 to $t0 -lw $t0, 68($fp) -sw $t0, 64($fp) +lw $t0, -68($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_15 +sw $t0, -64($fp) + # GotoNode j END_43 TRUE_43: li $s0, 1 -sw $s0, 80($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_19 +sw $s0, -80($fp) + # ArgNode s to s0 # Load from s to $s0 lw $s0, 8($fp) @@ -2499,24 +3195,30 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 88($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_21 +sw $v0, -88($fp) + addi $sp, $sp, 4 li $s0, 1 -sw $s0, 92($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_22 +sw $s0, -92($fp) + # Load from local_a2i_at_A2I_internal_21 to $t0 -lw $t0, 88($fp) +lw $t0, -88($fp) # Load from local_a2i_at_A2I_internal_22 to $t1 -lw $t1, 92($fp) +lw $t1, -92($fp) sub $t2, $t0, $t1 -sw $t2, 84($fp) +# from src: $t2 to dst: local_a2i_at_A2I_internal_20 +sw $t2, -84($fp) + # ArgNode local_a2i_at_A2I_internal_20 to s0 # Load from local_a2i_at_A2I_internal_20 to $s0 -lw $s0, 84($fp) +lw $s0, -84($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_a2i_at_A2I_internal_19 to s0 # Load from local_a2i_at_A2I_internal_19 to $s0 -lw $s0, 80($fp) +lw $s0, -80($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode s to s0 @@ -2532,11 +3234,13 @@ addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 76($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_18 +sw $v0, -76($fp) + addi $sp, $sp, 12 # ArgNode local_a2i_at_A2I_internal_18 to s0 # Load from local_a2i_at_A2I_internal_18 to $s0 -lw $s0, 76($fp) +lw $s0, -76($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -2552,20 +3256,28 @@ addi $s2, $s1, 24 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 72($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_17 +sw $v0, -72($fp) + addi $sp, $sp, 8 # Load from local_a2i_at_A2I_internal_17 to $t0 -lw $t0, 72($fp) -sw $t0, 64($fp) +lw $t0, -72($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_15 +sw $t0, -64($fp) + END_43: # Load from local_a2i_at_A2I_internal_15 to $t0 -lw $t0, 64($fp) -sw $t0, 40($fp) +lw $t0, -64($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_9 +sw $t0, -40($fp) + # GotoNode j END_42 TRUE_42: li $s0, 1 -sw $s0, 108($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_26 +sw $s0, -108($fp) + # ArgNode s to s0 # Load from s to $s0 lw $s0, 8($fp) @@ -2579,24 +3291,30 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 116($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_28 +sw $v0, -116($fp) + addi $sp, $sp, 4 li $s0, 1 -sw $s0, 120($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_29 +sw $s0, -120($fp) + # Load from local_a2i_at_A2I_internal_28 to $t0 -lw $t0, 116($fp) +lw $t0, -116($fp) # Load from local_a2i_at_A2I_internal_29 to $t1 -lw $t1, 120($fp) +lw $t1, -120($fp) sub $t2, $t0, $t1 -sw $t2, 112($fp) +# from src: $t2 to dst: local_a2i_at_A2I_internal_27 +sw $t2, -112($fp) + # ArgNode local_a2i_at_A2I_internal_27 to s0 # Load from local_a2i_at_A2I_internal_27 to $s0 -lw $s0, 112($fp) +lw $s0, -112($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_a2i_at_A2I_internal_26 to s0 # Load from local_a2i_at_A2I_internal_26 to $s0 -lw $s0, 108($fp) +lw $s0, -108($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode s to s0 @@ -2612,11 +3330,13 @@ addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 104($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_25 +sw $v0, -104($fp) + addi $sp, $sp, 12 # ArgNode local_a2i_at_A2I_internal_25 to s0 # Load from local_a2i_at_A2I_internal_25 to $s0 -lw $s0, 104($fp) +lw $s0, -104($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -2632,31 +3352,43 @@ addi $s2, $s1, 24 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 100($fp) +# from src: $v0 to dst: local_a2i_at_A2I_internal_24 +sw $v0, -100($fp) + addi $sp, $sp, 8 # Load from local_a2i_at_A2I_internal_24 to $t0 -lw $t0, 100($fp) +lw $t0, -100($fp) nor $t1, $t0, $t0 -sw $t1, 96($fp) +# from src: $t1 to dst: local_a2i_at_A2I_internal_23 +sw $t1, -96($fp) + # Load from local_a2i_at_A2I_internal_23 to $t0 -lw $t0, 96($fp) -sw $t0, 40($fp) +lw $t0, -96($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_9 +sw $t0, -40($fp) + END_42: # Load from local_a2i_at_A2I_internal_9 to $t0 -lw $t0, 40($fp) -sw $t0, 16($fp) +lw $t0, -40($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_3 +sw $t0, -16($fp) + # GotoNode j END_41 TRUE_41: li $s0, 0 -sw $s0, 124($fp) +# from src: $s0 to dst: local_a2i_at_A2I_internal_30 +sw $s0, -124($fp) + # Load from local_a2i_at_A2I_internal_30 to $t0 -lw $t0, 124($fp) -sw $t0, 16($fp) +lw $t0, -124($fp) +# from src: $t0 to dst: local_a2i_at_A2I_internal_3 +sw $t0, -16($fp) + END_41: # ReturnNode # Load from local_a2i_at_A2I_internal_3 to $v0 -lw $v0, 16($fp) +lw $v0, -16($fp) # Restore registers lw $s6, 0($sp) @@ -2712,10 +3444,14 @@ sw $s6, 0($sp) # Generating body code li $s0, 0 -sw $s0, 8($fp) +# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_1 +sw $s0, -8($fp) + # Load from local_a2i_aux_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) -sw $t0, 4($fp) +lw $t0, -8($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_int_0 +sw $t0, -4($fp) + # ArgNode s to s0 # Load from s to $s0 lw $s0, 8($fp) @@ -2729,50 +3465,66 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 16($fp) +# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_3 +sw $v0, -16($fp) + addi $sp, $sp, 4 # Load from local_a2i_aux_at_A2I_internal_3 to $t0 -lw $t0, 16($fp) -sw $t0, 12($fp) +lw $t0, -16($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_j_2 +sw $t0, -12($fp) + li $s0, 0 -sw $s0, 24($fp) +# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_5 +sw $s0, -24($fp) + # Load from local_a2i_aux_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 20($fp) +lw $t0, -24($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_i_4 +sw $t0, -20($fp) + START_47: # Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) # Load from local_a2i_aux_at_A2I_j_2 to $t1 -lw $t1, 12($fp) +lw $t1, -12($fp) slt $t2, $t0, $t1 -sw $t2, 28($fp) +# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_6 +sw $t2, -28($fp) + # IfGotoNode # Load from local_a2i_aux_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) +lw $t0, -28($fp) li $t1, 0 bne $t0, $t1, CONTINUE_47 # GotoNode j END_47 CONTINUE_47: li $s0, 10 -sw $s0, 40($fp) +# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_9 +sw $s0, -40($fp) + # Load from local_a2i_aux_at_A2I_int_0 to $t0 -lw $t0, 4($fp) +lw $t0, -4($fp) # Load from local_a2i_aux_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) +lw $t1, -40($fp) mult $t0, $t1 mflo $t0 -sw $t0, 36($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_internal_8 +sw $t0, -36($fp) + li $s0, 1 -sw $s0, 52($fp) +# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_12 +sw $s0, -52($fp) + # ArgNode local_a2i_aux_at_A2I_internal_12 to s0 # Load from local_a2i_aux_at_A2I_internal_12 to $s0 -lw $s0, 52($fp) +lw $s0, -52($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_a2i_aux_at_A2I_i_4 to s0 # Load from local_a2i_aux_at_A2I_i_4 to $s0 -lw $s0, 20($fp) +lw $s0, -20($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode s to s0 @@ -2788,11 +3540,13 @@ addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 48($fp) +# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_11 +sw $v0, -48($fp) + addi $sp, $sp, 12 # ArgNode local_a2i_aux_at_A2I_internal_11 to s0 # Load from local_a2i_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -2808,34 +3562,46 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 44($fp) +# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_10 +sw $v0, -44($fp) + addi $sp, $sp, 8 # Load from local_a2i_aux_at_A2I_internal_8 to $t0 -lw $t0, 36($fp) +lw $t0, -36($fp) # Load from local_a2i_aux_at_A2I_internal_10 to $t1 -lw $t1, 44($fp) +lw $t1, -44($fp) add $t2, $t0, $t1 -sw $t2, 32($fp) +# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_7 +sw $t2, -32($fp) + # Load from local_a2i_aux_at_A2I_internal_7 to $t0 -lw $t0, 32($fp) -sw $t0, 4($fp) +lw $t0, -32($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_int_0 +sw $t0, -4($fp) + li $s0, 1 -sw $s0, 60($fp) +# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_14 +sw $s0, -60($fp) + # Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) # Load from local_a2i_aux_at_A2I_internal_14 to $t1 -lw $t1, 60($fp) +lw $t1, -60($fp) add $t2, $t0, $t1 -sw $t2, 56($fp) +# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_13 +sw $t2, -56($fp) + # Load from local_a2i_aux_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -sw $t0, 20($fp) +lw $t0, -56($fp) +# from src: $t0 to dst: local_a2i_aux_at_A2I_i_4 +sw $t0, -20($fp) + # GotoNode j START_47 END_47: # ReturnNode # Load from local_a2i_aux_at_A2I_int_0 to $v0 -lw $v0, 4($fp) +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -2891,50 +3657,64 @@ sw $s6, 0($sp) # Generating body code li $s0, 0 -sw $s0, 4($fp) +# from src: $s0 to dst: local_i2a_at_A2I_internal_0 +sw $s0, -4($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2a_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) +lw $t1, -4($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 8($fp) +# from src: $t1 to dst: local_i2a_at_A2I_internal_1 +sw $t1, -8($fp) + # IfGotoNode # Load from local_i2a_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) +lw $t0, -8($fp) li $t1, 0 bne $t0, $t1, TRUE_49 li $s0, 0 -sw $s0, 20($fp) +# from src: $s0 to dst: local_i2a_at_A2I_internal_4 +sw $s0, -20($fp) + # Load from local_i2a_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) +lw $t0, -20($fp) # Load from i to $t1 lw $t1, 8($fp) slt $t2, $t0, $t1 -sw $t2, 16($fp) +# from src: $t2 to dst: local_i2a_at_A2I_internal_3 +sw $t2, -16($fp) + # IfGotoNode # Load from local_i2a_at_A2I_internal_3 to $t0 -lw $t0, 16($fp) +lw $t0, -16($fp) li $t1, 0 bne $t0, $t1, TRUE_50 li $s0, 1 -sw $s0, 44($fp) +# from src: $s0 to dst: local_i2a_at_A2I_internal_10 +sw $s0, -44($fp) + # Load from local_i2a_at_A2I_internal_10 to $t0 -lw $t0, 44($fp) +lw $t0, -44($fp) nor $t1, $t0, $t0 -sw $t1, 40($fp) +# from src: $t1 to dst: local_i2a_at_A2I_internal_9 +sw $t1, -40($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2a_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) +lw $t1, -40($fp) mult $t0, $t1 mflo $t0 -sw $t0, 36($fp) +# from src: $t0 to dst: local_i2a_at_A2I_internal_8 +sw $t0, -36($fp) + # ArgNode local_i2a_at_A2I_internal_8 to s0 # Load from local_i2a_at_A2I_internal_8 to $s0 -lw $s0, 36($fp) +lw $s0, -36($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -2950,34 +3730,42 @@ addi $s2, $s1, 32 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 32($fp) +# from src: $v0 to dst: local_i2a_at_A2I_internal_7 +sw $v0, -32($fp) + addi $sp, $sp, 8 # ArgNode local_i2a_at_A2I_internal_7 to s0 # Load from local_i2a_at_A2I_internal_7 to $s0 -lw $s0, 32($fp) +lw $s0, -32($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # Load from data_16 to $s0 la $s0, data_16 -sw $s0, 48($fp) +# from src: $s0 to dst: local_i2a_at_A2I_internal_11 +sw $s0, -48($fp) + # ArgNode local_i2a_at_A2I_internal_11 to s0 # Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # DynamicCallNode String concat # Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) lw $s1, 12($s0) addi $s2, $s1, 16 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 28($fp) +# from src: $v0 to dst: local_i2a_at_A2I_internal_6 +sw $v0, -28($fp) + addi $sp, $sp, 8 # Load from local_i2a_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) -sw $t0, 24($fp) +lw $t0, -28($fp) +# from src: $t0 to dst: local_i2a_at_A2I_internal_5 +sw $t0, -24($fp) + # GotoNode j END_50 TRUE_50: @@ -2999,28 +3787,38 @@ addi $s2, $s1, 32 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 52($fp) +# from src: $v0 to dst: local_i2a_at_A2I_internal_12 +sw $v0, -52($fp) + addi $sp, $sp, 8 # Load from local_i2a_at_A2I_internal_12 to $t0 -lw $t0, 52($fp) -sw $t0, 24($fp) +lw $t0, -52($fp) +# from src: $t0 to dst: local_i2a_at_A2I_internal_5 +sw $t0, -24($fp) + END_50: # Load from local_i2a_at_A2I_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 12($fp) +lw $t0, -24($fp) +# from src: $t0 to dst: local_i2a_at_A2I_internal_2 +sw $t0, -12($fp) + # GotoNode j END_49 TRUE_49: # Load from data_5 to $s0 la $s0, data_5 -sw $s0, 56($fp) +# from src: $s0 to dst: local_i2a_at_A2I_internal_13 +sw $s0, -56($fp) + # Load from local_i2a_at_A2I_internal_13 to $t0 -lw $t0, 56($fp) -sw $t0, 12($fp) +lw $t0, -56($fp) +# from src: $t0 to dst: local_i2a_at_A2I_internal_2 +sw $t0, -12($fp) + END_49: # ReturnNode # Load from local_i2a_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) +lw $v0, -12($fp) # Restore registers lw $s6, 0($sp) @@ -3076,51 +3874,67 @@ sw $s6, 0($sp) # Generating body code li $s0, 0 -sw $s0, 4($fp) +# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_0 +sw $s0, -4($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2a_aux_at_A2I_internal_0 to $t1 -lw $t1, 4($fp) +lw $t1, -4($fp) slt $t2, $t0, $t1 slt $t3, $t1, $t0 add $t0, $t2, $t3 slti $t1, $t0, 1 -sw $t1, 8($fp) +# from src: $t1 to dst: local_i2a_aux_at_A2I_internal_1 +sw $t1, -8($fp) + # IfGotoNode # Load from local_i2a_aux_at_A2I_internal_1 to $t0 -lw $t0, 8($fp) +lw $t0, -8($fp) li $t1, 0 bne $t0, $t1, TRUE_53 li $s0, 10 -sw $s0, 24($fp) +# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_5 +sw $s0, -24($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2a_aux_at_A2I_internal_5 to $t1 -lw $t1, 24($fp) +lw $t1, -24($fp) div $t2, $t0, $t1 mflo $t0 -sw $t0, 20($fp) +# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_4 +sw $t0, -20($fp) + # Load from local_i2a_aux_at_A2I_internal_4 to $t0 -lw $t0, 20($fp) -sw $t0, 16($fp) +lw $t0, -20($fp) +# from src: $t0 to dst: local_i2a_aux_at_A2I_next_3 +sw $t0, -16($fp) + li $s0, 10 -sw $s0, 44($fp) +# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_10 +sw $s0, -44($fp) + # Load from local_i2a_aux_at_A2I_next_3 to $t0 -lw $t0, 16($fp) +lw $t0, -16($fp) # Load from local_i2a_aux_at_A2I_internal_10 to $t1 -lw $t1, 44($fp) +lw $t1, -44($fp) mult $t0, $t1 mflo $t0 -sw $t0, 40($fp) +# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_9 +sw $t0, -40($fp) + # Load from i to $t0 lw $t0, 8($fp) # Load from local_i2a_aux_at_A2I_internal_9 to $t1 -lw $t1, 40($fp) +lw $t1, -40($fp) sub $t2, $t0, $t1 -sw $t2, 36($fp) +# from src: $t2 to dst: local_i2a_aux_at_A2I_internal_8 +sw $t2, -36($fp) + # ArgNode local_i2a_aux_at_A2I_internal_8 to s0 # Load from local_i2a_aux_at_A2I_internal_8 to $s0 -lw $s0, 36($fp) +lw $s0, -36($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3136,16 +3950,18 @@ addi $s2, $s1, 16 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 32($fp) +# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_7 +sw $v0, -32($fp) + addi $sp, $sp, 8 # ArgNode local_i2a_aux_at_A2I_internal_7 to s0 # Load from local_i2a_aux_at_A2I_internal_7 to $s0 -lw $s0, 32($fp) +lw $s0, -32($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode local_i2a_aux_at_A2I_next_3 to s0 # Load from local_i2a_aux_at_A2I_next_3 to $s0 -lw $s0, 16($fp) +lw $s0, -16($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3161,39 +3977,49 @@ addi $s2, $s1, 32 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 48($fp) +# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_11 +sw $v0, -48($fp) + addi $sp, $sp, 8 # ArgNode local_i2a_aux_at_A2I_internal_11 to s0 # Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # DynamicCallNode String concat # Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, 48($fp) +lw $s0, -48($fp) lw $s1, 12($s0) addi $s2, $s1, 16 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 28($fp) +# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_6 +sw $v0, -28($fp) + addi $sp, $sp, 8 # Load from local_i2a_aux_at_A2I_internal_6 to $t0 -lw $t0, 28($fp) -sw $t0, 12($fp) +lw $t0, -28($fp) +# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_2 +sw $t0, -12($fp) + # GotoNode j END_53 TRUE_53: # Load from data_15 to $s0 la $s0, data_15 -sw $s0, 52($fp) +# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_12 +sw $s0, -52($fp) + # Load from local_i2a_aux_at_A2I_internal_12 to $t0 -lw $t0, 52($fp) -sw $t0, 12($fp) +lw $t0, -52($fp) +# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_2 +sw $t0, -12($fp) + END_53: # ReturnNode # Load from local_i2a_aux_at_A2I_internal_2 to $v0 -lw $v0, 12($fp) +lw $v0, -12($fp) # Restore registers lw $s6, 0($sp) @@ -3250,10 +4076,12 @@ sw $s6, 0($sp) # Generating body code # Load from data_18 to $s0 la $s0, data_18 -sw $s0, 12($fp) +# from src: $s0 to dst: local_main_at_Main_internal_2 +sw $s0, -12($fp) + # ArgNode local_main_at_Main_internal_2 to s0 # Load from local_main_at_Main_internal_2 to $s0 -lw $s0, 12($fp) +lw $s0, -12($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # Allocate space for A2I @@ -3261,8 +4089,10 @@ li $a0, 16 li $v0, 9 syscall move $s1, $v0 -sw $s1, 16($fp) -li $s0, 0 +# from src: $s1 to dst: local_main_at_Main_internal_3 +sw $s1, -16($fp) + +li $s0, 5 sw $s0, 0($s1) li $s0, 16 sw $s0, 4($s1) @@ -3272,35 +4102,43 @@ li $s0, 88 sw $s0, 12($s1) # ArgNode local_main_at_Main_internal_3 to s0 # Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) +lw $s0, -16($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # StaticCallNode jal ctor_A2I -sw $v0, 16($fp) +# from src: $v0 to dst: local_main_at_Main_internal_3 +sw $v0, -16($fp) + # ArgNode local_main_at_Main_internal_3 to s0 # Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) +lw $s0, -16($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # DynamicCallNode A2I a2i # Load from local_main_at_Main_internal_3 to $s0 -lw $s0, 16($fp) +lw $s0, -16($fp) lw $s1, 12($s0) addi $s2, $s1, 20 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 8($fp) +# from src: $v0 to dst: local_main_at_Main_internal_1 +sw $v0, -8($fp) + addi $sp, $sp, 8 # Load from local_main_at_Main_internal_1 to $t0 -lw $t0, 8($fp) -sw $t0, 4($fp) +lw $t0, -8($fp) +# from src: $t0 to dst: local_main_at_Main_a_0 +sw $t0, -4($fp) + li $s0, 678987 -sw $s0, 28($fp) +# from src: $s0 to dst: local_main_at_Main_internal_6 +sw $s0, -28($fp) + # ArgNode local_main_at_Main_internal_6 to s0 # Load from local_main_at_Main_internal_6 to $s0 -lw $s0, 28($fp) +lw $s0, -28($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # Allocate space for A2I @@ -3308,8 +4146,10 @@ li $a0, 16 li $v0, 9 syscall move $s1, $v0 -sw $s1, 32($fp) -li $s0, 0 +# from src: $s1 to dst: local_main_at_Main_internal_7 +sw $s1, -32($fp) + +li $s0, 5 sw $s0, 0($s1) li $s0, 16 sw $s0, 4($s1) @@ -3319,33 +4159,39 @@ li $s0, 88 sw $s0, 12($s1) # ArgNode local_main_at_Main_internal_7 to s0 # Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) +lw $s0, -32($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # StaticCallNode jal ctor_A2I -sw $v0, 32($fp) +# from src: $v0 to dst: local_main_at_Main_internal_7 +sw $v0, -32($fp) + # ArgNode local_main_at_Main_internal_7 to s0 # Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) +lw $s0, -32($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # DynamicCallNode A2I i2a # Load from local_main_at_Main_internal_7 to $s0 -lw $s0, 32($fp) +lw $s0, -32($fp) lw $s1, 12($s0) addi $s2, $s1, 28 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 24($fp) +# from src: $v0 to dst: local_main_at_Main_internal_5 +sw $v0, -24($fp) + addi $sp, $sp, 8 # Load from local_main_at_Main_internal_5 to $t0 -lw $t0, 24($fp) -sw $t0, 20($fp) +lw $t0, -24($fp) +# from src: $t0 to dst: local_main_at_Main_b_4 +sw $t0, -20($fp) + # ArgNode local_main_at_Main_a_0 to s0 # Load from local_main_at_Main_a_0 to $s0 -lw $s0, 4($fp) +lw $s0, -4($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3361,14 +4207,18 @@ addi $s2, $s1, 16 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 36($fp) +# from src: $v0 to dst: local_main_at_Main_internal_8 +sw $v0, -36($fp) + addi $sp, $sp, 8 # Load from data_19 to $s0 la $s0, data_19 -sw $s0, 44($fp) +# from src: $s0 to dst: local_main_at_Main_internal_10 +sw $s0, -44($fp) + # ArgNode local_main_at_Main_internal_10 to s0 # Load from local_main_at_Main_internal_10 to $s0 -lw $s0, 44($fp) +lw $s0, -44($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3384,11 +4234,13 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 40($fp) +# from src: $v0 to dst: local_main_at_Main_internal_9 +sw $v0, -40($fp) + addi $sp, $sp, 8 # ArgNode local_main_at_Main_b_4 to s0 # Load from local_main_at_Main_b_4 to $s0 -lw $s0, 20($fp) +lw $s0, -20($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3404,14 +4256,18 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 48($fp) +# from src: $v0 to dst: local_main_at_Main_internal_11 +sw $v0, -48($fp) + addi $sp, $sp, 8 # Load from data_20 to $s0 la $s0, data_20 -sw $s0, 56($fp) +# from src: $s0 to dst: local_main_at_Main_internal_13 +sw $s0, -56($fp) + # ArgNode local_main_at_Main_internal_13 to s0 # Load from local_main_at_Main_internal_13 to $s0 -lw $s0, 56($fp) +lw $s0, -56($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -3427,11 +4283,13 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -sw $v0, 52($fp) +# from src: $v0 to dst: local_main_at_Main_internal_12 +sw $v0, -52($fp) + addi $sp, $sp, 8 # ReturnNode # Load from local_main_at_Main_internal_12 to $v0 -lw $v0, 52($fp) +lw $v0, -52($fp) # Restore registers lw $s6, 0($sp) From aed93d9ef9f081f858e61643bec81a4e6bff9f84 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 14:40:27 -0500 Subject: [PATCH 143/191] clean args after ctor --- src/engine/codegen/to_cil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 39ae9240..533edb9c 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -207,6 +207,7 @@ def visit(self, node: cool.NewNode, scope): self.register_instruction(ArgNode(new_local)) self.register_instruction( StaticCallNode(f'ctor_{typex.name}', new_local)) + self.register_instruction(EmptyArgs(1)) return new_local @visitor.when(cool.IfThenElseNode) @@ -333,13 +334,13 @@ def visit(self, node: cool.FunctionCallNode, scope): typex = node.type.lex name = self.to_function_name(node.id.lex, typex) result = self.define_internal_local() + obj = self.visit(node.obj, scope) rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) - obj = self.visit(node.obj, scope) self.register_instruction(ArgNode(obj)) if name: self.register_instruction(StaticCallNode(name, result)) From 558c52d36e6ac5d3bca3639b705a6d864dca025f Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 15:22:28 -0500 Subject: [PATCH 144/191] fix main entry point --- src/main.py | 145 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 58 deletions(-) diff --git a/src/main.py b/src/main.py index 2291a5cc..920b23b2 100644 --- a/src/main.py +++ b/src/main.py @@ -3,85 +3,114 @@ from engine import * import sys -args = sys.argv -input_file = open(args[1], "r") -output_file = open(args[2], 'w') +def compile_code(inFile, outFile, output_cil=False): + input_file = open(inFile, "r") + output_file = open(outFile, 'w') -t = input_file.read() + text_code = input_file.read() -lexer = CoolLexer() -tokens, errors = lexer.tokenize(t) + ast = parse(text_code) + context = collect(ast) + context = builder(ast, context) + context = checker(ast, context) -if len(errors): - for e in errors: - print(e) - exit(1) + string_formatted = codegen(ast, context, output_cil) + output_file.write(string_formatted) -if not tokens: - print(SyntacticError(0, 0, 'ERROR at or near "%s"' % 'EOF')) - exit(1) + input_file.close() + output_file.close() -lexer = CoolLexer() -parser = CoolParser(lexer) -ast, errors = parser.parse(t) + exit(0) -if errors: - for error in errors: - print(error) - exit(1) -# print(ast) -# fmatter = Format() -# tree = fmatter.visit(ast, 0) +def parse(text_code): + lexer = CoolLexer() + tokens, errors = lexer.tokenize(text_code) -# print(tree) + if len(errors): + for e in errors: + print(e) + exit(1) -collect_errors = [] -collect = Collector(collect_errors) -collect.visit(ast) + if not tokens: + print(SyntacticError(0, 0, 'ERROR at or near "%s"' % 'EOF')) + exit(1) -if len(collect_errors): - for e in collect_errors[::-1]: - print(e) - exit(1) + lexer = CoolLexer() + parser = CoolParser(lexer) + ast, errors = parser.parse(text_code) -context = collect.context -builder_errors = [] -builder = Builder(context, builder_errors) + if errors: + for error in errors: + print(error) + exit(1) + # print(ast) + # fmatter = Format() + # tree = fmatter.visit(ast, 0) -builder.visit(ast) + # print(tree) + return ast -if len(builder_errors): - for e in builder_errors: - print(e) - exit(1) -context = builder.context -checker_errors = [] -checker = Checker(context, checker_errors) -scope = checker.visit(ast) +def collect(ast): + collect_errors = [] + collect = Collector(collect_errors) + collect.visit(ast) -if len(checker_errors): - for e in checker_errors: - print(e) - exit(1) + if len(collect_errors): + for e in collect_errors[::-1]: + print(e) + exit(1) + return collect.context -cil = COOL_TO_CIL(checker.context) -cil_ast = cil.visit(ast) +def builder(ast, context): + builder_errors = [] + builder = Builder(context, builder_errors) -emsamb = CIL_TO_MIPS() -emsamb.visit(cil_ast) + builder.visit(ast) -f_ast = emsamb.mips.compile() -# f_ast = CIL_FORMATTER().visit(cil_ast) + if len(builder_errors): + for e in builder_errors: + print(e) + exit(1) + return builder.context -string_formatted = str(f_ast) -output_file.write(string_formatted) -input_file.close() -output_file.close() +def checker(ast, context): + checker_errors = [] + checker = Checker(context, checker_errors) + scope = checker.visit(ast, Scope()) -exit(0) + if len(checker_errors): + for e in checker_errors: + print(e) + exit(1) + return checker.context + + +def codegen(ast, context, output_cil=False): + cil = COOL_TO_CIL(context) + cil_ast = cil.visit(ast) + + if output_cil: + formatted_ast = CIL_FORMATTER().visit(cil_ast) + with open('out.cil', 'w') as f: + f.write(formatted_ast) + + emsamb = CIL_TO_MIPS() + emsamb.visit(cil_ast) + + f_ast = emsamb.mips.compile() + + return str(f_ast) + + +if __name__ == "__main__": + args = sys.argv + if not len(args) in (3, 4): + print('') + exit(1) + compile_code(*args[1:]) From df8eeae297a6ddc143115c1314c98f78f54e881b Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 16 Dec 2020 15:26:59 -0500 Subject: [PATCH 145/191] eliminating excesive prints --- src/engine/codegen/to_mips.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 3d027666..a9dea40c 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -80,7 +80,6 @@ def load_memory(self, dst, arg: str): if arg in self.arguments else self.local_vars[arg] ) * self.data_size - print(offset) self.mips.load_memory(dst, self.mips.offset(reg.fp, offset)) elif arg in self.data_segment: self.mips.la(dst, arg) @@ -170,7 +169,6 @@ def visit(self, node: FunctionNode): self.mips.empty_line() self.mips.comment("Generating body code") for instruction in node.instructions: - print(instruction) self.visit(instruction) self.mips.empty_line() From be4b3ea13176a2ac48e67466852ac9a0fc30a79d Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 16:14:12 -0500 Subject: [PATCH 146/191] fix main ctor --- src/engine/codegen/to_cil.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 533edb9c..26abff0c 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -34,13 +34,6 @@ def sort_class_declar(self, program: cool.ProgramNode): key=lambda cd: self.context.inheritance_deep(cd.id.lex), ) - def init_class_attr(self, scope: Scope, class_id, self_inst): - attr_nodes = self.attr_declarations[class_id] - for attr in attr_nodes: - attr_scope = scope.create_child() - attr_scope.define_variable('self', self_inst) - self.visit(attr, attr_scope, typex=class_id) - def save_attr_initializations(self, node: cool.ProgramNode, scope): self.attr_declarations = dict() self.attr_declarations['Object'] = [] @@ -108,11 +101,19 @@ def visit(self, node: cool.ProgramNode, scope=None): self.save_attr_initializations(node, scope) # entry self.current_function = self.register_function('entry') + # call Constructor instance = self.define_internal_local() - result = self.define_internal_local() self.current_type = self.context.get_type('Main') - self.register_instruction(AllocateNode(instance, 'Main')) - self.init_class_attr(scope, 'Main', instance) + self.register_instruction( + AllocateNode(instance, self.current_type.name) + ) + self.register_instruction(ArgNode(instance)) + self.register_instruction( + StaticCallNode(f'ctor_{self.current_type.name}', instance)) + self.register_instruction(EmptyArgs(1)) + + # call Main.main + result = self.define_internal_local() self.register_instruction(ArgNode(instance)) name = self.to_function_name('main', 'Main') self.register_instruction(StaticCallNode(name, result)) From 8c23441dd05be38a71d4dc99268740343bc3f06e Mon Sep 17 00:00:00 2001 From: thenai310 Date: Wed, 16 Dec 2020 22:39:34 -0500 Subject: [PATCH 147/191] real_value passed on the string built-in methods --- src/engine/codegen/cil.py | 124 ++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 9aab493b..281bac24 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -110,23 +110,16 @@ def define_string_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods - # self.current_method = self.current_type.get_method('ctor_String') - # type_name = self.current_type.name - # self.current_function = self.register_function( - # self.to_function_name(self.current_method.name, type_name)) - # self_local = self.register_param(VariableInfo("self", None)) - # self.register_instruction( - # SetAttribNode(self_local, node.id.lex, result, typex)) - # self.register_instruction(ReturnNode(self_local)) - # self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('length') type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_param = self.register_param(VariableInfo('self', None)) dest = self.define_internal_local() - self.register_instruction(LengthNode(dest, self_param)) + real_value = self.define_internal_local() + self.register_instruction(GetAttribNode( + real_value, self_param, 'value', 'String')) + self.register_instruction(LengthNode(dest, real_value)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None @@ -137,7 +130,10 @@ def define_string_type(self): self_param = self.register_param(VariableInfo('self', None)) str_param = self.register_param(VariableInfo('string', None)) dest = self.define_internal_local() - self.register_instruction(ConcatNode(dest, self_param, str_param)) + real_value = self.define_internal_local() + self.register_instruction(GetAttribNode( + real_value, self_param, 'value', 'String')) + self.register_instruction(ConcatNode(dest, real_value, str_param)) self.register_instruction(ReturnNode(dest)) self.current_method = self.current_function = None @@ -146,51 +142,66 @@ def define_string_type(self): self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_param = self.register_param(VariableInfo('self', None)) + real_value = self.define_internal_local() + self.register_instruction(GetAttribNode( + real_value, self_param, 'value', 'String')) start = self.register_param(VariableInfo('start', None)) length = self.register_param(VariableInfo('length', None)) - dest = self.define_internal_local() - result_msg = self.define_internal_local() - length_var = self.define_internal_local() - zero = self.define_internal_local() - sum_var = self.define_internal_local() + result = self.define_internal_local() + # sum_var = self.define_internal_local() cmp_var1 = self.define_internal_local() cmp_var2 = self.define_internal_local() - cmp_var3 = self.define_internal_local() + # cmp_var3 = self.define_internal_local() + local_error1 = self.define_internal_local() + local_error2 = self.define_internal_local() + # local_error3 = self.define_internal_local() + no_error_label1 = LabelNode("error1") no_error_label2 = LabelNode("error2") - no_error_label3 = LabelNode("error3") + # no_error_label3 = LabelNode("error3") + + zero = self.define_internal_local() self.register_instruction(BoxNode(zero, 0)) - self.register_instruction(LengthNode(length_var, self_param)) - eol = self.register_data('\\n').name + + length_var = self.define_internal_local() + self.register_instruction(LengthNode(length_var, real_value)) + + eol = self.register_data('\n') msg_eol = self.define_internal_local() + self.register_instruction(LoadNode(msg_eol, eol.name)) self.register_instruction(LessEqNode(cmp_var1, zero, start)) self.register_instruction(IfGotoNode(cmp_var1, no_error_label1.label)) - error_msg = self.register_data("Invalid substring start").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) - self.register_instruction(PrintStrNode(msg_eol)) + error_msg = self.register_data("Invalid substring start") + self.register_instruction(LoadNode(local_error1, error_msg.name)) + self.register_instruction(ConcatNode( + local_error1, local_error1, msg_eol)) + self.register_instruction(PrintStrNode(local_error1)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label1) self.register_instruction(LessEqNode(cmp_var2, zero, length)) self.register_instruction(IfGotoNode(cmp_var2, no_error_label2.label)) - error_msg = self.register_data("Invalid substring length").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) - self.register_instruction(PrintStrNode(msg_eol)) + error_msg = self.register_data("Invalid substring length") + self.register_instruction(LoadNode(local_error2, error_msg.name)) + self.register_instruction(ConcatNode( + local_error2, local_error2, msg_eol)) + self.register_instruction(PrintStrNode(local_error2)) self.register_instruction(ErrorNode()) self.register_instruction(no_error_label2) - self.register_instruction(PlusNode(sum_var, start, length)) - self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) - self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) - error_msg = self.register_data("Invalid substring").name - self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) - self.register_instruction(PrintStrNode(msg_eol)) - self.register_instruction(ErrorNode()) - self.register_instruction(no_error_label3) + # self.register_instruction(PlusNode(sum_var, start, length)) + # self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) + # self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) + # error_msg = self.register_data("Invalid substring").name + # self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) + # self.register_instruction(PrintStrNode(msg_eol)) + # self.register_instruction(no_error_label3) + # self.register_instruction(ErrorNode()) + self.register_instruction(SubstringNode( - dest, self_param, start, length)) - self.register_instruction(ReturnNode(dest)) + result, real_value, start, length)) + self.register_instruction(ReturnNode(result)) self.current_method = self.current_function = None self.current_type = None @@ -204,14 +215,6 @@ def define_io_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods - # self.current_method = self.current_type.get_method('ctor_IO') - # type_name = self.current_type.name - # self.current_function = self.register_function( - # self.to_function_name(self.current_method.name, type_name)) - # self_local = self.register_param(VariableInfo("self", None)) - # self.register_instruction(ReturnNode(self_local)) - # self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('out_string') type_name = self.current_type.name self.current_function = self.register_function( @@ -260,28 +263,29 @@ def define_object_type(self): method.name, xtype.name)) for method, xtype in self.current_type.all_methods()] type_node.features = type_node.attributes + type_node.methods - # self.current_method = self.current_type.get_method('ctor_Object') - # type_name = self.current_type.name - # self.current_function = self.register_function( - # self.to_function_name(self.current_method.name, type_name)) - # self_local = self.register_param(VariableInfo("self", None)) - # self.register_instruction(ReturnNode(self_local)) - # self.current_method = self.current_function = None - self.current_method = self.current_type.get_method('abort') type_name = self.current_type.name self.current_function = self.register_function( self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) type_name = self.define_internal_local() - abort_msg = self.register_data("Abort called from class ").name - eol = self.register_data('\\n').name - msg = self.define_internal_local() + full_msg = self.define_internal_local() + + abort = self.register_data("Abort called from class ") + eol = self.register_data('\n') + + abort_msg = self.define_internal_local() + self.register_instruction(LoadNode(abort_msg, abort.name)) + msg_eol = self.define_internal_local() - self.register_instruction(TypeNameNode(type_name, self_local)) - self.register_instruction(ConcatNode(msg, abort_msg, type_name)) - self.register_instruction(ConcatNode(msg_eol, msg, eol)) - self.register_instruction(PrintStrNode(msg_eol)) + self.register_instruction(LoadNode(msg_eol, eol.name)) + + obj_type = self.define_internal_local() + self.register_instruction(TypeOfNode(self_local, obj_type)) + self.register_instruction(TypeNameNode(type_name, obj_type)) + self.register_instruction(ConcatNode(full_msg, abort_msg, type_name)) + self.register_instruction(ConcatNode(full_msg, full_msg, msg_eol)) + self.register_instruction(PrintStrNode(full_msg)) self.register_instruction(AbortNode()) self.current_method = self.current_function = None From f9da070d662e4d23f29abbec3f1d89214e5af49f Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Wed, 16 Dec 2020 23:15:21 -0500 Subject: [PATCH 148/191] change cil formatter void node --- src/engine/codegen/cil_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 91e0efcd..8eb71b6e 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -177,7 +177,7 @@ def visit(self, node: AbortNode): @visitor.when(VoidNode) def visit(self, node: VoidNode): - return f'VOID' + return f'{node.dest} = VOID' @visitor.when(ConformsNode) def visit(self, node: ConformsNode): From c3c477b884ca8d713ed7d3b6cfc0bd5cf0c4bb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 16 Dec 2020 23:56:50 -0500 Subject: [PATCH 149/191] Fix memory allocation --- src/engine/codegen/to_mips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 092c9d99..19be1a58 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -496,7 +496,7 @@ def visit(self, node): # load object self.load_memory(reg.s0, node.obj) # load size - self.load_memory(reg.s1, self.mips.offset(reg.s0, self.data_size)) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, self.data_size)) # load dest self.load_memory(reg.s3, node.dest) # copy byte to byte From 2d4a269400920d3697e58785d23f80c2c81a67ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Wed, 16 Dec 2020 23:57:11 -0500 Subject: [PATCH 150/191] Typenode improve --- src/engine/codegen/to_mips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 19be1a58..61a7a044 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -506,7 +506,7 @@ def visit(self, node): def visit(self, node: TypeNameNode): self.mips.comment(f"TypeNameNode {node.dest} Type:{node.type}") self.load_memory(reg.t0, node.type) - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, self.data_size)) + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, 3 * self.data_size)) self.store_memory(reg.t1, node.dest) def get_string_length(self, src, dst): From 48a59a6ee5cc45c319336af758a3548d26c35c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 17 Dec 2020 00:09:38 -0500 Subject: [PATCH 151/191] Typeof improve --- src/engine/codegen/to_mips.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 61a7a044..cf94d6cb 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -384,11 +384,11 @@ def visit(self, node: AllocateNode): @visitor.when(TypeOfNode) def visit(self, node: TypeOfNode): - self.mips.comment(f"TypeOfNode of {node.obj}") + self.mips.comment(f"TypeOfNode of {node.obj} to {node.dest}") # Cargar la direccion de memoria self.load_memory(reg.s0, node.obj) - # El offset 3 para ptr al name - self.mips.load_memory(reg.s1, self.mips.offset(reg.s0, 3)) + # El offset 0 para el numero del tipo + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0)) self.store_memory(reg.s1, node.dest) @visitor.when(LabelNode) From 30ea842d47dc37d5e6967d4a36faab5d41257e91 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 00:32:44 -0500 Subject: [PATCH 152/191] typename changed not using typeof --- src/engine/codegen/cil.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 281bac24..71e08745 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -305,9 +305,7 @@ def define_object_type(self): self.to_function_name(self.current_method.name, type_name)) self_local = self.register_param(VariableInfo('self', None)) type_name_inst = self.define_internal_local() - obj_type = self.define_internal_local() - self.register_instruction(TypeOfNode(self_local, obj_type)) - self.register_instruction(TypeNameNode(type_name_inst, obj_type)) + self.register_instruction(TypeNameNode(type_name_inst, self_local)) self.register_instruction(ReturnNode(type_name_inst)) self.current_method = self.current_function = None self.current_type = None From 6a56cd88fe5504a7fc58185d301b62d40786e411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 17 Dec 2020 01:04:54 -0500 Subject: [PATCH 153/191] Fix typename node --- src/engine/codegen/to_mips.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index cf94d6cb..dfce5bf0 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -506,7 +506,8 @@ def visit(self, node): def visit(self, node: TypeNameNode): self.mips.comment(f"TypeNameNode {node.dest} Type:{node.type}") self.load_memory(reg.t0, node.type) - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, 3 * self.data_size)) + # ptr at 3rd position in memory ( 2 in base 0) + self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, 2 * self.data_size)) self.store_memory(reg.t1, node.dest) def get_string_length(self, src, dst): From 27c2325bd42d1082a9d6c672367495454fe1bb6f Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 01:53:45 -0500 Subject: [PATCH 154/191] fix isvoid formatter --- src/engine/codegen/cil_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/cil_format.py b/src/engine/codegen/cil_format.py index 8eb71b6e..a9d4f139 100644 --- a/src/engine/codegen/cil_format.py +++ b/src/engine/codegen/cil_format.py @@ -153,7 +153,7 @@ def visit(self, node: LessNode): @visitor.when(IsVoidNode) def visit(self, node: IsVoidNode): - return f'{node.dest} = ISVOID {node.body}' + return f'{node.dest} = ISVOID {node.expression}' @visitor.when(LessEqNode) def visit(self, node: LessEqNode): From 6fed4401fdf79802bada989fb44206a82df68173 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 01:54:38 -0500 Subject: [PATCH 155/191] Conforms passing type error --- src/engine/codegen/to_cil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 26abff0c..5ab550f3 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -294,8 +294,8 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_t test_res = self.define_internal_local() matching_label = LabelNode(f'CASE_MATCH_{node.id.lex}_{node.type.lex}') - self.register_instruction(ConformsNode(test_res, expr, node.type)) - self.register_instruction(IfGotoNode(expr, matching_label)) + self.register_instruction(ConformsNode(test_res, expr, node.type.lex)) + self.register_instruction(IfGotoNode(expr, matching_label.label)) self.register_instruction( GotoNode(next_label.label) ) From 19fc94797efaeb3f111bfec5d02e04ce3a55f877 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 02:15:27 -0500 Subject: [PATCH 156/191] abort whitout typeof --- src/engine/codegen/cil.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 71e08745..8d595cc8 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -166,7 +166,7 @@ def define_string_type(self): length_var = self.define_internal_local() self.register_instruction(LengthNode(length_var, real_value)) - eol = self.register_data('\n') + eol = self.register_data(r'\n') msg_eol = self.define_internal_local() self.register_instruction(LoadNode(msg_eol, eol.name)) @@ -272,7 +272,7 @@ def define_object_type(self): full_msg = self.define_internal_local() abort = self.register_data("Abort called from class ") - eol = self.register_data('\n') + eol = self.register_data(r'\n') abort_msg = self.define_internal_local() self.register_instruction(LoadNode(abort_msg, abort.name)) @@ -280,9 +280,7 @@ def define_object_type(self): msg_eol = self.define_internal_local() self.register_instruction(LoadNode(msg_eol, eol.name)) - obj_type = self.define_internal_local() - self.register_instruction(TypeOfNode(self_local, obj_type)) - self.register_instruction(TypeNameNode(type_name, obj_type)) + self.register_instruction(TypeNameNode(type_name, self_local)) self.register_instruction(ConcatNode(full_msg, abort_msg, type_name)) self.register_instruction(ConcatNode(full_msg, full_msg, msg_eol)) self.register_instruction(PrintStrNode(full_msg)) From 78a113d5fb2e8dc24ddc73be9048da86ba027b01 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 02:16:06 -0500 Subject: [PATCH 157/191] func args problem --- src/engine/codegen/to_cil.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 5ab550f3..96ed779a 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -336,11 +336,9 @@ def visit(self, node: cool.FunctionCallNode, scope): name = self.to_function_name(node.id.lex, typex) result = self.define_internal_local() obj = self.visit(node.obj, scope) - rev_args = [] for arg in node.args: + # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = [arg_value] + rev_args - for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self.register_instruction(ArgNode(obj)) if name: @@ -357,11 +355,9 @@ def visit(self, node: cool.FunctionCallNode, scope): def visit(self, node: cool.MemberCallNode, scope: Scope): type_name = self.current_type.name result = self.define_internal_local() - rev_args = [] for arg in node.args: + # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = [arg_value] + rev_args - for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name self.register_instruction(ArgNode(self_inst)) From 80a465dabe7a5ac1062855a74766738744898798 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 09:14:47 -0500 Subject: [PATCH 158/191] string attr passed ok --- src/coolc.sh | 2 +- src/engine/codegen/to_cil.py | 19 +++++++++++++++---- src/engine/codegen/to_mips.py | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/coolc.sh b/src/coolc.sh index 5482a9ed..7493a037 100755 --- a/src/coolc.sh +++ b/src/coolc.sh @@ -10,4 +10,4 @@ echo "Copyright (c) 2020: Leonel Alejandro García López, Jorge Daniel Valle D # Llamar al compilador #echo "Compiling $INPUT_FILE into $OUTPUT_FILE" -python3 main.py $INPUT_FILE $OUTPUT_FILE +python3 main.py $INPUT_FILE $OUTPUT_FILE do_cil diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 26abff0c..84f7bbcb 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -39,13 +39,13 @@ def save_attr_initializations(self, node: cool.ProgramNode, scope): self.attr_declarations['Object'] = [] self.attr_declarations['IO'] = [] self.attr_declarations['Int'] = [ - cool.AttrDeclarationNode("value") + cool.AttrDeclarationNode("value", 'Int') ] self.attr_declarations['String'] = [ - cool.AttrDeclarationNode("value") + cool.AttrDeclarationNode("value", 'String') ] self.attr_declarations['Bool'] = [ - cool.AttrDeclarationNode("value") + cool.AttrDeclarationNode("value", 'Bool') ] for built_in in ['IO', 'Int', 'String', 'Bool', 'Object']: @@ -295,7 +295,7 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_t matching_label = LabelNode(f'CASE_MATCH_{node.id.lex}_{node.type.lex}') self.register_instruction(ConformsNode(test_res, expr, node.type)) - self.register_instruction(IfGotoNode(expr, matching_label)) + self.register_instruction(IfGotoNode(expr, matching_label.label)) self.register_instruction( GotoNode(next_label.label) ) @@ -335,13 +335,24 @@ def visit(self, node: cool.FunctionCallNode, scope): typex = node.type.lex name = self.to_function_name(node.id.lex, typex) result = self.define_internal_local() + obj = self.visit(node.obj, scope) + if typex in ["Int", "Bool", "String"]: + self.register_instruction(ArgNode(obj)) + packed = self.define_internal_local() + self.register_instruction(StaticCallNode(f"ctor_{typex}", packed)) + self.register_instruction(EmptyArgs(1)) + self.register_instruction( + SetAttribNode(packed, "value", obj, typex)) + obj = packed + rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) + self.register_instruction(ArgNode(obj)) if name: self.register_instruction(StaticCallNode(name, result)) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index a9dea40c..1a860997 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -182,6 +182,7 @@ def visit(self, node: FunctionNode): self.mips.comment("Return") self.mips.pop(reg.fp) self.mips.jr(reg.ra) + self.mips.empty_line() @visitor.when(DataNode) def visit(self, node: DataNode): From e181fdc37f14b613543653b8c3a9f6dae8522028 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 10:15:34 -0500 Subject: [PATCH 159/191] allocating the string node... methods kinda working --- src/engine/codegen/to_cil.py | 11 +- src/out.cil | 273 ++++ src/test.cl | 120 +- src/test.mips | 2916 +++------------------------------- 4 files changed, 477 insertions(+), 2843 deletions(-) create mode 100644 src/out.cil diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 84f7bbcb..83d9bd7d 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -338,13 +338,16 @@ def visit(self, node: cool.FunctionCallNode, scope): obj = self.visit(node.obj, scope) if typex in ["Int", "Bool", "String"]: - self.register_instruction(ArgNode(obj)) + # self.register_instruction(ArgNode(obj)) packed = self.define_internal_local() - self.register_instruction(StaticCallNode(f"ctor_{typex}", packed)) + alloc = self.define_internal_local() + self.register_instruction(AllocateNode(alloc, 'String')) + self.register_instruction(ArgNode(alloc)) + self.register_instruction(StaticCallNode(f"ctor_{typex}", alloc)) self.register_instruction(EmptyArgs(1)) self.register_instruction( - SetAttribNode(packed, "value", obj, typex)) - obj = packed + SetAttribNode(alloc, "value", obj, typex)) + obj = alloc rev_args = [] for arg in node.args: diff --git a/src/out.cil b/src/out.cil new file mode 100644 index 00000000..55f80626 --- /dev/null +++ b/src/out.cil @@ -0,0 +1,273 @@ +.TYPES +type Object { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type String { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method length: function_length_at_String + method concat: function_concat_at_String + method substr: function_substr_at_String +} +type IO { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO +} +type Int { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type Bool { + attribute value + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object +} +type Main { + + + method abort: function_abort_at_Object + method type_name: function_type_name_at_Object + method copy: function_copy_at_Object + method out_string: function_out_string_at_IO + method out_int: function_out_int_at_IO + method in_string: function_in_string_at_IO + method in_int: function_in_int_at_IO + method main: function_main_at_Main +} + +.DATA +data_0 = "Abort called from class " +data_1 = " +" +data_2 = "Invalid substring start" +data_3 = "Invalid substring length" +data_4 = "" + +.CODE +function function_abort_at_Object { + PARAM self + + LOCAL local_abort_at_Object_internal_0 + LOCAL local_abort_at_Object_internal_1 + LOCAL local_abort_at_Object_internal_2 + LOCAL local_abort_at_Object_internal_3 + LOCAL local_abort_at_Object_internal_4 + + local_abort_at_Object_internal_2 = LOAD data_0 + local_abort_at_Object_internal_3 = LOAD data_1 + local_abort_at_Object_internal_4 = TYPEOF self + local_abort_at_Object_internal_0 = TYPENAME local_abort_at_Object_internal_4 + local_abort_at_Object_internal_1 = CONCAT local_abort_at_Object_internal_2 local_abort_at_Object_internal_0 + local_abort_at_Object_internal_1 = CONCAT local_abort_at_Object_internal_1 local_abort_at_Object_internal_3 + PRINTSTR local_abort_at_Object_internal_1 + ABORT +} +function function_copy_at_Object { + PARAM self + + LOCAL local_copy_at_Object_internal_0 + + local_copy_at_Object_internal_0 = COPY self + RETURN local_copy_at_Object_internal_0 +} +function function_type_name_at_Object { + PARAM self + + LOCAL local_type_name_at_Object_internal_0 + LOCAL local_type_name_at_Object_internal_1 + + local_type_name_at_Object_internal_1 = TYPEOF self + local_type_name_at_Object_internal_0 = TYPENAME local_type_name_at_Object_internal_1 + RETURN local_type_name_at_Object_internal_0 +} +function function_length_at_String { + PARAM self + + LOCAL local_length_at_String_internal_0 + LOCAL local_length_at_String_internal_1 + + local_length_at_String_internal_1 = GETATTR self value + local_length_at_String_internal_0 = LENGTH local_length_at_String_internal_1 + RETURN local_length_at_String_internal_0 +} +function function_concat_at_String { + PARAM self + PARAM string + + LOCAL local_concat_at_String_internal_0 + LOCAL local_concat_at_String_internal_1 + + local_concat_at_String_internal_1 = GETATTR self value + local_concat_at_String_internal_0 = CONCAT local_concat_at_String_internal_1 string + RETURN local_concat_at_String_internal_0 +} +function function_substr_at_String { + PARAM self + PARAM start + PARAM length + + LOCAL local_substr_at_String_internal_0 + LOCAL local_substr_at_String_internal_1 + LOCAL local_substr_at_String_internal_2 + LOCAL local_substr_at_String_internal_3 + LOCAL local_substr_at_String_internal_4 + LOCAL local_substr_at_String_internal_5 + LOCAL local_substr_at_String_internal_6 + LOCAL local_substr_at_String_internal_7 + LOCAL local_substr_at_String_internal_8 + + local_substr_at_String_internal_0 = GETATTR self value + local_substr_at_String_internal_6 = 0 + local_substr_at_String_internal_7 = LENGTH local_substr_at_String_internal_0 + local_substr_at_String_internal_8 = LOAD data_1 + local_substr_at_String_internal_2 = local_substr_at_String_internal_6 <= start + IF local_substr_at_String_internal_2 GOTO error1 + local_substr_at_String_internal_4 = LOAD data_2 + local_substr_at_String_internal_4 = CONCAT local_substr_at_String_internal_4 local_substr_at_String_internal_8 + PRINTSTR local_substr_at_String_internal_4 + ERROR 0 + LABEL error1 + local_substr_at_String_internal_3 = local_substr_at_String_internal_6 <= length + IF local_substr_at_String_internal_3 GOTO error2 + local_substr_at_String_internal_5 = LOAD data_3 + local_substr_at_String_internal_5 = CONCAT local_substr_at_String_internal_5 local_substr_at_String_internal_8 + PRINTSTR local_substr_at_String_internal_5 + ERROR 0 + LABEL error2 + local_substr_at_String_internal_1 = SUBSTRING local_substr_at_String_internal_0 start length + RETURN local_substr_at_String_internal_1 +} +function function_out_string_at_IO { + PARAM self + PARAM str_val + + + + PRINTSTR str_val + RETURN self +} +function function_in_string_at_IO { + + + LOCAL local_in_string_at_IO_internal_0 + + local_in_string_at_IO_internal_0 = READSTR + RETURN local_in_string_at_IO_internal_0 +} +function function_out_int_at_IO { + PARAM self + PARAM int_val + + + + PRINTINT int_val + RETURN self +} +function function_in_int_at_IO { + + + LOCAL local_in_int_at_IO_internal_0 + + local_in_int_at_IO_internal_0 = READINT + RETURN local_in_int_at_IO_internal_0 +} +function ctor_IO { + PARAM self + + + + RETURN self +} +function ctor_Int { + PARAM self + + LOCAL local__internal_0 + + VOID + SETATTR value OF self_Int = local__internal_0 + RETURN self +} +function ctor_String { + PARAM self + + + + SETATTR value OF self_String = data_4 + RETURN self +} +function ctor_Bool { + PARAM self + + LOCAL local__internal_0 + + VOID + SETATTR value OF self_Bool = local__internal_0 + RETURN self +} +function ctor_Object { + PARAM self + + + + RETURN self +} +function ctor_Main { + PARAM self + + + + RETURN self +} +function entry { + + + LOCAL local__internal_0 + LOCAL local__internal_1 + + local__internal_0 = ALLOCATE Main + ARG local__internal_0 + local__internal_0 = CALL ctor_Main + CLEAR 1 ARGS + ARG local__internal_0 + local__internal_1 = CALL function_main_at_Main + CLEAR 1 ARGS +} +function function_main_at_Main { + PARAM self + + LOCAL local_main_at_Main_internal_0 + LOCAL local_main_at_Main_internal_1 + LOCAL local_main_at_Main_internal_2 + + local_main_at_Main_internal_2 = ALLOCATE Object + ARG local_main_at_Main_internal_2 + local_main_at_Main_internal_2 = CALL ctor_Object + CLEAR 1 ARGS + ARG local_main_at_Main_internal_2 + local_main_at_Main_internal_1 = VCALL Object type_name + CLEAR 1 ARGS + ARG local_main_at_Main_internal_1 + ARG self + local_main_at_Main_internal_0 = VCALL Main out_string + CLEAR 2 ARGS + RETURN local_main_at_Main_internal_0 +} \ No newline at end of file diff --git a/src/test.cl b/src/test.cl index f4125a2f..b9e90b32 100644 --- a/src/test.cl +++ b/src/test.cl @@ -1,121 +1,5 @@ -(* - The class A2I provides integer-to-string and string-to-integer -conversion routines. To use these routines, either inherit them -in the class where needed, have a dummy variable bound to -something of type A2I, or simpl write (new A2I).method(argument). -*) - - -(* - c2i Converts a 1-character string to an integer. Aborts - if the string is not "0" through "9" -*) -class A2I { - - c2i(char : String) : Int { - if char = "0" then 0 else - if char = "1" then 1 else - if char = "2" then 2 else - if char = "3" then 3 else - if char = "4" then 4 else - if char = "5" then 5 else - if char = "6" then 6 else - if char = "7" then 7 else - if char = "8" then 8 else - if char = "9" then 9 else - { abort(); 0; } -- the 0 is needed to satisfy the typchecker - fi fi fi fi fi fi fi fi fi fi - }; - -(* - i2c is the inverse of c2i. -*) - i2c(i : Int) : String { - if i = 0 then "0" else - if i = 1 then "1" else - if i = 2 then "2" else - if i = 3 then "3" else - if i = 4 then "4" else - if i = 5 then "5" else - if i = 6 then "6" else - if i = 7 then "7" else - if i = 8 then "8" else - if i = 9 then "9" else - { abort(); ""; } -- the "" is needed to satisfy the typchecker - fi fi fi fi fi fi fi fi fi fi - }; - -(* - a2i converts an ASCII string into an integer. The empty string -is converted to 0. Signed and unsigned strings are handled. The -method aborts if the string does not represent an integer. Very -long strings of digits produce strange answers because of arithmetic -overflow. - -*) - a2i(s : String) : Int { - if s.length() = 0 then 0 else - if s.substr(0,1) = "-" then ~a2i_aux(s.substr(1,s.length()-1)) else - if s.substr(0,1) = "+" then a2i_aux(s.substr(1,s.length()-1)) else - a2i_aux(s) - fi fi fi - }; - -(* - a2i_aux converts the usigned portion of the string. As a programming -example, this method is written iteratively. -*) - a2i_aux(s : String) : Int { - (let int : Int <- 0 in - { - (let j : Int <- s.length() in - (let i : Int <- 0 in - while i < j loop - { - int <- int * 10 + c2i(s.substr(i,1)); - i <- i + 1; - } - pool - ) - ); - int; - } - ) - }; - -(* - i2a converts an integer to a string. Positive and negative -numbers are handled correctly. -*) - i2a(i : Int) : String { - if i = 0 then "0" else - if 0 < i then i2a_aux(i) else - "-".concat(i2a_aux(i * ~1)) - fi fi - }; - -(* - i2a_aux is an example using recursion. -*) - i2a_aux(i : Int) : String { - if i = 0 then "" else - (let next : Int <- i / 10 in - i2a_aux(next).concat(i2c(i - next * 10)) - ) - fi - }; - -}; - class Main inherits IO { - main () : Object { - let a : Int <- (new A2I).a2i("678987"), - b : String <- (new A2I).i2a(678987) in - { - out_int(a) ; - out_string(" == ") ; - out_string(b) ; - out_string("\n"); - } + main () : IO { + out_string((new Object).type_name()) } ; } ; diff --git a/src/test.mips b/src/test.mips index c0bb66b5..3bd01244 100644 --- a/src/test.mips +++ b/src/test.mips @@ -9,57 +9,23 @@ classname_Int: .asciiz "Int" classname_Bool: .asciiz "Bool" -classname_A2I: -.asciiz "A2I" classname_Main: .asciiz "Main" data_0: .asciiz "Abort called from class " data_1: -.asciiz "\n" +.asciiz " +" data_2: .asciiz "Invalid substring start" data_3: .asciiz "Invalid substring length" data_4: -.asciiz "Invalid substring" -data_5: -.asciiz "0" -data_6: -.asciiz "1" -data_7: -.asciiz "2" -data_8: -.asciiz "3" -data_9: -.asciiz "4" -data_10: -.asciiz "5" -data_11: -.asciiz "6" -data_12: -.asciiz "7" -data_13: -.asciiz "8" -data_14: -.asciiz "9" -data_15: .asciiz "" -data_16: -.asciiz "-" -data_17: -.asciiz "+" -data_18: -.asciiz "678987" -data_19: -.asciiz " == " -data_20: -.asciiz " -" .text main: # Allocate Vtable -li $a0, 156 +li $a0, 120 li $v0, 9 syscall move $s7, $v0 @@ -130,57 +96,30 @@ sw $s0, 80($s7) # Bool_copy la $s0, function_copy_at_Object sw $s0, 84($s7) -# A2I_abort -la $s0, function_abort_at_Object -sw $s0, 88($s7) -# A2I_type_name -la $s0, function_type_name_at_Object -sw $s0, 92($s7) -# A2I_copy -la $s0, function_copy_at_Object -sw $s0, 96($s7) -# A2I_c2i -la $s0, function_c2i_at_A2I -sw $s0, 100($s7) -# A2I_i2c -la $s0, function_i2c_at_A2I -sw $s0, 104($s7) -# A2I_a2i -la $s0, function_a2i_at_A2I -sw $s0, 108($s7) -# A2I_a2i_aux -la $s0, function_a2i_aux_at_A2I -sw $s0, 112($s7) -# A2I_i2a -la $s0, function_i2a_at_A2I -sw $s0, 116($s7) -# A2I_i2a_aux -la $s0, function_i2a_aux_at_A2I -sw $s0, 120($s7) # Main_abort la $s0, function_abort_at_Object -sw $s0, 124($s7) +sw $s0, 88($s7) # Main_type_name la $s0, function_type_name_at_Object -sw $s0, 128($s7) +sw $s0, 92($s7) # Main_copy la $s0, function_copy_at_Object -sw $s0, 132($s7) +sw $s0, 96($s7) # Main_out_string la $s0, function_out_string_at_IO -sw $s0, 136($s7) +sw $s0, 100($s7) # Main_out_int la $s0, function_out_int_at_IO -sw $s0, 140($s7) +sw $s0, 104($s7) # Main_in_string la $s0, function_in_string_at_IO -sw $s0, 144($s7) +sw $s0, 108($s7) # Main_in_int la $s0, function_in_int_at_IO -sw $s0, 148($s7) +sw $s0, 112($s7) # Main_main la $s0, function_main_at_Main -sw $s0, 152($s7) +sw $s0, 116($s7) jal entry li $v0, 10 @@ -192,7 +131,7 @@ sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -12 +addi $sp, $sp, -20 # Saving Registers @@ -214,15 +153,32 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code +# Load from data_0 to $s0 +la $s0, data_0 +# from src: $s0 to dst: local_abort_at_Object_internal_2 +sw $s0, -12($fp) + +# Load from data_1 to $s0 +la $s0, data_1 +# from src: $s0 to dst: local_abort_at_Object_internal_3 +sw $s0, -16($fp) + +# TypeOfNode of self +# Load from self to $s0 +lw $s0, 4($fp) +lw $s1, 3($s0) +# from src: $s1 to dst: local_abort_at_Object_internal_4 +sw $s1, -20($fp) + # TypeNameNode -# Load from self to $t0 -lw $t0, 4($fp) +# Load from local_abort_at_Object_internal_4 to $t0 +lw $t0, -20($fp) lw $t1, 4($t0) # from src: $t1 to dst: local_abort_at_Object_internal_0 sw $t1, -4($fp) -# Load from data_0 to $s0 -la $s0, data_0 +# Load from local_abort_at_Object_internal_2 to $s0 +lw $s0, -12($fp) # Load from local_abort_at_Object_internal_0 to $s1 lw $s1, -4($fp) move $t0, $s0 @@ -276,8 +232,8 @@ sw $s3, -8($fp) # Load from local_abort_at_Object_internal_1 to $s0 lw $s0, -8($fp) -# Load from data_1 to $s1 -la $s1, data_1 +# Load from local_abort_at_Object_internal_3 to $s1 +lw $s1, -16($fp) move $t0, $s0 li $t1, 0 mips_label_9: @@ -324,12 +280,12 @@ addi $t1, $t1, 1 j mips_label_15 mips_label_16: move $v0, $t1 -# from src: $s3 to dst: local_abort_at_Object_internal_2 -sw $s3, -12($fp) +# from src: $s3 to dst: local_abort_at_Object_internal_1 +sw $s3, -8($fp) -# Print str local_abort_at_Object_internal_2 -# Load from local_abort_at_Object_internal_2 to $a0 -lw $a0, -12($fp) +# Print str local_abort_at_Object_internal_1 +# Load from local_abort_at_Object_internal_1 to $a0 +lw $a0, -8($fp) li $v0, 4 syscall li $v0, 10 @@ -355,11 +311,12 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 12 +addi $sp, $sp, 20 # Return lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_copy_at_Object: # Set stack frame addi $sp, $sp, -4 @@ -431,6 +388,7 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_type_name_at_Object: # Set stack frame addi $sp, $sp, -4 @@ -502,6 +460,7 @@ addi $sp, $sp, 8 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_length_at_String: # Set stack frame addi $sp, $sp, -4 @@ -509,7 +468,7 @@ sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -4 +addi $sp, $sp, -8 # Saving Registers @@ -531,9 +490,16 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code +# GetAttribNode local_length_at_String_internal_1 = self.value Type:String +# Load from self to $t0 +lw $t0, 4($fp) +lw $t1, 16($t0) +# from src: $t1 to dst: local_length_at_String_internal_1 +sw $t1, -8($fp) + # LengthNode -# Load from self to $s1 -lw $s1, 4($fp) +# Load from local_length_at_String_internal_1 to $s1 +lw $s1, -8($fp) move $t0, $s1 li $t1, 0 mips_label_19: @@ -570,11 +536,12 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 4 +addi $sp, $sp, 8 # Return lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_concat_at_String: # Set stack frame addi $sp, $sp, -4 @@ -582,7 +549,7 @@ sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -4 +addi $sp, $sp, -8 # Saving Registers @@ -604,8 +571,15 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code -# Load from self to $s0 -lw $s0, 4($fp) +# GetAttribNode local_concat_at_String_internal_1 = self.value Type:String +# Load from self to $t0 +lw $t0, 4($fp) +lw $t1, 16($t0) +# from src: $t1 to dst: local_concat_at_String_internal_1 +sw $t1, -8($fp) + +# Load from local_concat_at_String_internal_1 to $s0 +lw $s0, -8($fp) # Load from string to $s1 lw $s1, 8($fp) move $t0, $s0 @@ -680,11 +654,12 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 4 +addi $sp, $sp, 8 # Return lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_substr_at_String: # Set stack frame addi $sp, $sp, -4 @@ -714,13 +689,20 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code +# GetAttribNode local_substr_at_String_internal_0 = self.value Type:String +# Load from self to $t0 +lw $t0, 4($fp) +lw $t1, 16($t0) +# from src: $t1 to dst: local_substr_at_String_internal_0 +sw $t1, -4($fp) + li $s0, 0 -# from src: $s0 to dst: local_substr_at_String_internal_3 -sw $s0, -16($fp) +# from src: $s0 to dst: local_substr_at_String_internal_6 +sw $s0, -28($fp) # LengthNode -# Load from self to $s1 -lw $s1, 4($fp) +# Load from local_substr_at_String_internal_0 to $s1 +lw $s1, -4($fp) move $t0, $s1 li $t1, 0 mips_label_29: @@ -731,28 +713,38 @@ addi $t0, $t0, 1 j mips_label_29 mips_label_30: move $s0, $t1 -# from src: $s0 to dst: local_substr_at_String_internal_2 -sw $s0, -12($fp) +# from src: $s0 to dst: local_substr_at_String_internal_7 +sw $s0, -32($fp) -# Load from local_substr_at_String_internal_3 to $t0 -lw $t0, -16($fp) +# Load from data_1 to $s0 +la $s0, data_1 +# from src: $s0 to dst: local_substr_at_String_internal_8 +sw $s0, -36($fp) + +# Load from local_substr_at_String_internal_6 to $t0 +lw $t0, -28($fp) # Load from start to $t1 lw $t1, 8($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -# from src: $t0 to dst: local_substr_at_String_internal_5 -sw $t0, -24($fp) +# from src: $t0 to dst: local_substr_at_String_internal_2 +sw $t0, -12($fp) # IfGotoNode -# Load from local_substr_at_String_internal_5 to $t0 -lw $t0, -24($fp) +# Load from local_substr_at_String_internal_2 to $t0 +lw $t0, -12($fp) li $t1, 0 bne $t0, $t1, error1 # Load from data_2 to $s0 la $s0, data_2 -# Load from data_1 to $s1 -la $s1, data_1 +# from src: $s0 to dst: local_substr_at_String_internal_4 +sw $s0, -20($fp) + +# Load from local_substr_at_String_internal_4 to $s0 +lw $s0, -20($fp) +# Load from local_substr_at_String_internal_8 to $s1 +lw $s1, -36($fp) move $t0, $s0 li $t1, 0 mips_label_31: @@ -799,12 +791,12 @@ addi $t1, $t1, 1 j mips_label_37 mips_label_38: move $v0, $t1 -# from src: $s3 to dst: local_substr_at_String_internal_8 -sw $s3, -36($fp) +# from src: $s3 to dst: local_substr_at_String_internal_4 +sw $s3, -20($fp) -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, -36($fp) +# Print str local_substr_at_String_internal_4 +# Load from local_substr_at_String_internal_4 to $a0 +lw $a0, -20($fp) li $v0, 4 syscall # ErrorNode @@ -812,25 +804,30 @@ li $a0, 1 li $v0, 17 syscall error1: -# Load from local_substr_at_String_internal_3 to $t0 -lw $t0, -16($fp) +# Load from local_substr_at_String_internal_6 to $t0 +lw $t0, -28($fp) # Load from length to $t1 lw $t1, 12($fp) slt $t2, $t1, $t0 li $t3, 1 sub $t0, $t3, $t2 -# from src: $t0 to dst: local_substr_at_String_internal_6 -sw $t0, -28($fp) +# from src: $t0 to dst: local_substr_at_String_internal_3 +sw $t0, -16($fp) # IfGotoNode -# Load from local_substr_at_String_internal_6 to $t0 -lw $t0, -28($fp) +# Load from local_substr_at_String_internal_3 to $t0 +lw $t0, -16($fp) li $t1, 0 bne $t0, $t1, error2 # Load from data_3 to $s0 la $s0, data_3 -# Load from data_1 to $s1 -la $s1, data_1 +# from src: $s0 to dst: local_substr_at_String_internal_5 +sw $s0, -24($fp) + +# Load from local_substr_at_String_internal_5 to $s0 +lw $s0, -24($fp) +# Load from local_substr_at_String_internal_8 to $s1 +lw $s1, -36($fp) move $t0, $s0 li $t1, 0 mips_label_39: @@ -877,12 +874,12 @@ addi $t1, $t1, 1 j mips_label_45 mips_label_46: move $v0, $t1 -# from src: $s3 to dst: local_substr_at_String_internal_8 -sw $s3, -36($fp) +# from src: $s3 to dst: local_substr_at_String_internal_5 +sw $s3, -24($fp) -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, -36($fp) +# Print str local_substr_at_String_internal_5 +# Load from local_substr_at_String_internal_5 to $a0 +lw $a0, -24($fp) li $v0, 4 syscall # ErrorNode @@ -890,94 +887,8 @@ li $a0, 1 li $v0, 17 syscall error2: -# Load from start to $t0 -lw $t0, 8($fp) -# Load from length to $t1 -lw $t1, 12($fp) -add $t2, $t0, $t1 -# from src: $t2 to dst: local_substr_at_String_internal_4 -sw $t2, -20($fp) - -# Load from local_substr_at_String_internal_4 to $t0 -lw $t0, -20($fp) -# Load from local_substr_at_String_internal_2 to $t1 -lw $t1, -12($fp) -slt $t2, $t1, $t0 -li $t3, 1 -sub $t0, $t3, $t2 -# from src: $t0 to dst: local_substr_at_String_internal_7 -sw $t0, -32($fp) - -# IfGotoNode -# Load from local_substr_at_String_internal_7 to $t0 -lw $t0, -32($fp) -li $t1, 0 -bne $t0, $t1, error3 -# Load from data_4 to $s0 -la $s0, data_4 -# Load from data_1 to $s1 -la $s1, data_1 -move $t0, $s0 -li $t1, 0 -mips_label_47: -lb $t3, 0($t0) -beqz $t3, mips_label_48 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_47 -mips_label_48: -move $s4, $t1 -move $t0, $s1 -li $t1, 0 -mips_label_49: -lb $t3, 0($t0) -beqz $t3, mips_label_50 -addi $t1, $t1, 1 -addi $t0, $t0, 1 -j mips_label_49 -mips_label_50: -move $s5, $t1 -add $a0, $s4, $s5 -li $v0, 9 -syscall -move $s3, $v0 -move $t0, $s0 -move $t1, $s3 -mips_label_51: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_52 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_51 -mips_label_52: -move $v0, $t1 -move $t0, $s1 -move $t1, $v0 -mips_label_53: -lb $t2, 0($t0) -sb $t2, 0($t1) -beqz $t2, mips_label_54 -addi $t0, $t0, 1 -addi $t1, $t1, 1 -j mips_label_53 -mips_label_54: -move $v0, $t1 -# from src: $s3 to dst: local_substr_at_String_internal_8 -sw $s3, -36($fp) - -# Print str local_substr_at_String_internal_8 -# Load from local_substr_at_String_internal_8 to $a0 -lw $a0, -36($fp) -li $v0, 4 -syscall -# ErrorNode -li $a0, 1 -li $v0, 17 -syscall -error3: -# Load from self to $s0 -lw $s0, 4($fp) +# Load from local_substr_at_String_internal_0 to $s0 +lw $s0, -4($fp) # Load from length to $s1 lw $s1, 12($fp) # Load from start to $s3 @@ -989,23 +900,23 @@ syscall move $t0, $s0 move $t1, $v0 move $t3, $s1 -mips_label_55: +mips_label_47: lb $t2, 0($t0) sb $t2, 0($t1) addi $t0, $t0, 1 addi $t1, $t1, 1 addi $t3, $t3, -1 -beqz $t3, mips_label_56 -j mips_label_55 -mips_label_56: +beqz $t3, mips_label_48 +j mips_label_47 +mips_label_48: move $t2, $zero sb $t2, 0($t1) -# from src: $v0 to dst: local_substr_at_String_internal_0 -sw $v0, -4($fp) +# from src: $v0 to dst: local_substr_at_String_internal_1 +sw $v0, -8($fp) # ReturnNode -# Load from local_substr_at_String_internal_0 to $v0 -lw $v0, -4($fp) +# Load from local_substr_at_String_internal_1 to $v0 +lw $v0, -8($fp) # Restore registers lw $s6, 0($sp) @@ -1031,6 +942,7 @@ addi $sp, $sp, 36 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_out_string_at_IO: # Set stack frame addi $sp, $sp, -4 @@ -1093,6 +1005,7 @@ addi $sp, $sp, 0 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_in_string_at_IO: # Set stack frame addi $sp, $sp, -4 @@ -1160,6 +1073,7 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_out_int_at_IO: # Set stack frame addi $sp, $sp, -4 @@ -1221,6 +1135,7 @@ addi $sp, $sp, 0 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + function_in_int_at_IO: # Set stack frame addi $sp, $sp, -4 @@ -1283,6 +1198,7 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + ctor_IO: # Set stack frame addi $sp, $sp, -4 @@ -1340,6 +1256,7 @@ addi $sp, $sp, 0 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + ctor_Int: # Set stack frame addi $sp, $sp, -4 @@ -1407,6 +1324,7 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + ctor_String: # Set stack frame addi $sp, $sp, -4 @@ -1414,7 +1332,7 @@ sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -4 +addi $sp, $sp, 0 # Saving Registers @@ -1436,15 +1354,11 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code -# from src: $zero to dst: local_ng_internal_0 -sw $zero, -4($fp) - -# SetAttribNode self.value Type:String = local_ng_internal_0 +# SetAttribNode self.value Type:String = data_4 # Load from self to $s0 lw $s0, 4($fp) -# SET local var local_ng_internal_0 -# Load from local_ng_internal_0 to $s1 -lw $s1, -4($fp) +# SET data data_4 +la $s1, data_4 sw $s1, 16($s0) # ReturnNode # Load from self to $v0 @@ -1469,11 +1383,12 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 4 +addi $sp, $sp, 0 # Return lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + ctor_Bool: # Set stack frame addi $sp, $sp, -4 @@ -1541,6 +1456,7 @@ addi $sp, $sp, 4 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + ctor_Object: # Set stack frame addi $sp, $sp, -4 @@ -1598,63 +1514,7 @@ addi $sp, $sp, 0 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra -ctor_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, 0 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# ReturnNode -# Load from self to $v0 -lw $v0, 4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 -# Clean stack variable space -addi $sp, $sp, 0 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra ctor_Main: # Set stack frame addi $sp, $sp, -4 @@ -1712,6 +1572,7 @@ addi $sp, $sp, 0 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra + entry: # Set stack frame addi $sp, $sp, -4 @@ -1749,13 +1610,13 @@ move $s1, $v0 # from src: $s1 to dst: local__internal_0 sw $s1, -4($fp) -li $s0, 6 +li $s0, 5 sw $s0, 0($s1) li $s0, 16 sw $s0, 4($s1) la $s0, classname_Main sw $s0, 8($s1) -li $s0, 124 +li $s0, 88 sw $s0, 12($s1) # ArgNode local__internal_0 to s0 # Load from local__internal_0 to $s0 @@ -1763,6 +1624,17 @@ lw $s0, -4($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # StaticCallNode +jal ctor_Main +# from src: $v0 to dst: local__internal_0 +sw $v0, -4($fp) + +addi $sp, $sp, 4 +# ArgNode local__internal_0 to s0 +# Load from local__internal_0 to $s0 +lw $s0, -4($fp) +addi $sp, $sp, -4 +sw $s0, 0($sp) +# StaticCallNode jal function_main_at_Main # from src: $v0 to dst: local__internal_1 sw $v0, -8($fp) @@ -1793,14 +1665,15 @@ addi $sp, $sp, 8 lw $fp, 0($sp) addi $sp, $sp, 4 jr $ra -function_c2i_at_A2I: + +function_main_at_Main: # Set stack frame addi $sp, $sp, -4 sw $fp, 0($sp) move $fp, $sp # Allocate memory for Local variables -addi $sp, $sp, -168 +addi $sp, $sp, -12 # Saving Registers @@ -1822,2452 +1695,53 @@ addi $sp, $sp, -4 sw $s6, 0($sp) # Generating body code -# Load from data_5 to $s0 -la $s0, data_5 -# from src: $s0 to dst: local_c2i_at_A2I_internal_0 -sw $s0, -4($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_0 to $s1 -lw $s1, -4($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_60: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_58 -beqz $a1, mips_label_59 -seq $v0, $a0, $a1 -beqz $v0, mips_label_59 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_60 -mips_label_59: -li $v0, 0 -j mips_label_57 -mips_label_58: -bnez $a1, mips_label_59 -li $v0, 1 -mips_label_57: -# from src: $v0 to dst: local_c2i_at_A2I_internal_1 -sw $v0, -8($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_1 to $t0 -lw $t0, -8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_1 -# Load from data_6 to $s0 -la $s0, data_6 -# from src: $s0 to dst: local_c2i_at_A2I_internal_3 -sw $s0, -16($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_3 to $s1 -lw $s1, -16($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_64: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_62 -beqz $a1, mips_label_63 -seq $v0, $a0, $a1 -beqz $v0, mips_label_63 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_64 -mips_label_63: -li $v0, 0 -j mips_label_61 -mips_label_62: -bnez $a1, mips_label_63 -li $v0, 1 -mips_label_61: -# from src: $v0 to dst: local_c2i_at_A2I_internal_4 -sw $v0, -20($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_4 to $t0 -lw $t0, -20($fp) -li $t1, 0 -bne $t0, $t1, TRUE_2 -# Load from data_7 to $s0 -la $s0, data_7 -# from src: $s0 to dst: local_c2i_at_A2I_internal_6 -sw $s0, -28($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_6 to $s1 -lw $s1, -28($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_68: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_66 -beqz $a1, mips_label_67 -seq $v0, $a0, $a1 -beqz $v0, mips_label_67 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_68 -mips_label_67: -li $v0, 0 -j mips_label_65 -mips_label_66: -bnez $a1, mips_label_67 -li $v0, 1 -mips_label_65: -# from src: $v0 to dst: local_c2i_at_A2I_internal_7 -sw $v0, -32($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_7 to $t0 -lw $t0, -32($fp) -li $t1, 0 -bne $t0, $t1, TRUE_3 -# Load from data_8 to $s0 -la $s0, data_8 -# from src: $s0 to dst: local_c2i_at_A2I_internal_9 -sw $s0, -40($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_9 to $s1 -lw $s1, -40($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_72: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_70 -beqz $a1, mips_label_71 -seq $v0, $a0, $a1 -beqz $v0, mips_label_71 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_72 -mips_label_71: -li $v0, 0 -j mips_label_69 -mips_label_70: -bnez $a1, mips_label_71 -li $v0, 1 -mips_label_69: -# from src: $v0 to dst: local_c2i_at_A2I_internal_10 -sw $v0, -44($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_10 to $t0 -lw $t0, -44($fp) -li $t1, 0 -bne $t0, $t1, TRUE_4 -# Load from data_9 to $s0 -la $s0, data_9 -# from src: $s0 to dst: local_c2i_at_A2I_internal_12 -sw $s0, -52($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_12 to $s1 -lw $s1, -52($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_76: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_74 -beqz $a1, mips_label_75 -seq $v0, $a0, $a1 -beqz $v0, mips_label_75 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_76 -mips_label_75: -li $v0, 0 -j mips_label_73 -mips_label_74: -bnez $a1, mips_label_75 -li $v0, 1 -mips_label_73: -# from src: $v0 to dst: local_c2i_at_A2I_internal_13 -sw $v0, -56($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_13 to $t0 -lw $t0, -56($fp) -li $t1, 0 -bne $t0, $t1, TRUE_5 -# Load from data_10 to $s0 -la $s0, data_10 -# from src: $s0 to dst: local_c2i_at_A2I_internal_15 -sw $s0, -64($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_15 to $s1 -lw $s1, -64($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_80: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_78 -beqz $a1, mips_label_79 -seq $v0, $a0, $a1 -beqz $v0, mips_label_79 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_80 -mips_label_79: -li $v0, 0 -j mips_label_77 -mips_label_78: -bnez $a1, mips_label_79 -li $v0, 1 -mips_label_77: -# from src: $v0 to dst: local_c2i_at_A2I_internal_16 -sw $v0, -68($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_16 to $t0 -lw $t0, -68($fp) -li $t1, 0 -bne $t0, $t1, TRUE_6 -# Load from data_11 to $s0 -la $s0, data_11 -# from src: $s0 to dst: local_c2i_at_A2I_internal_18 -sw $s0, -76($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_18 to $s1 -lw $s1, -76($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_84: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_82 -beqz $a1, mips_label_83 -seq $v0, $a0, $a1 -beqz $v0, mips_label_83 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_84 -mips_label_83: -li $v0, 0 -j mips_label_81 -mips_label_82: -bnez $a1, mips_label_83 -li $v0, 1 -mips_label_81: -# from src: $v0 to dst: local_c2i_at_A2I_internal_19 -sw $v0, -80($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_19 to $t0 -lw $t0, -80($fp) -li $t1, 0 -bne $t0, $t1, TRUE_7 -# Load from data_12 to $s0 -la $s0, data_12 -# from src: $s0 to dst: local_c2i_at_A2I_internal_21 -sw $s0, -88($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_21 to $s1 -lw $s1, -88($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_88: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_86 -beqz $a1, mips_label_87 -seq $v0, $a0, $a1 -beqz $v0, mips_label_87 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_88 -mips_label_87: -li $v0, 0 -j mips_label_85 -mips_label_86: -bnez $a1, mips_label_87 -li $v0, 1 -mips_label_85: -# from src: $v0 to dst: local_c2i_at_A2I_internal_22 -sw $v0, -92($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_22 to $t0 -lw $t0, -92($fp) -li $t1, 0 -bne $t0, $t1, TRUE_8 -# Load from data_13 to $s0 -la $s0, data_13 -# from src: $s0 to dst: local_c2i_at_A2I_internal_24 -sw $s0, -100($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_24 to $s1 -lw $s1, -100($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_92: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_90 -beqz $a1, mips_label_91 -seq $v0, $a0, $a1 -beqz $v0, mips_label_91 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_92 -mips_label_91: -li $v0, 0 -j mips_label_89 -mips_label_90: -bnez $a1, mips_label_91 -li $v0, 1 -mips_label_89: -# from src: $v0 to dst: local_c2i_at_A2I_internal_25 -sw $v0, -104($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_25 to $t0 -lw $t0, -104($fp) -li $t1, 0 -bne $t0, $t1, TRUE_9 -# Load from data_14 to $s0 -la $s0, data_14 -# from src: $s0 to dst: local_c2i_at_A2I_internal_27 -sw $s0, -112($fp) - - -# Comparing Strings -- -# Load from char to $s0 -lw $s0, 8($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_c2i_at_A2I_internal_27 to $s1 -lw $s1, -112($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_96: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_94 -beqz $a1, mips_label_95 -seq $v0, $a0, $a1 -beqz $v0, mips_label_95 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_96 -mips_label_95: -li $v0, 0 -j mips_label_93 -mips_label_94: -bnez $a1, mips_label_95 -li $v0, 1 -mips_label_93: -# from src: $v0 to dst: local_c2i_at_A2I_internal_28 -sw $v0, -116($fp) - -# IfGotoNode -# Load from local_c2i_at_A2I_internal_28 to $t0 -lw $t0, -116($fp) -li $t1, 0 -bne $t0, $t1, TRUE_10 -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I abort -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 0 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_c2i_at_A2I_internal_30 -sw $v0, -124($fp) - -addi $sp, $sp, 4 -li $s0, 0 -# from src: $s0 to dst: local_c2i_at_A2I_internal_31 -sw $s0, -128($fp) - -# Load from local_c2i_at_A2I_internal_31 to $t0 -lw $t0, -128($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_29 -sw $t0, -120($fp) - -# GotoNode -j END_10 -TRUE_10: -li $s0, 9 -# from src: $s0 to dst: local_c2i_at_A2I_internal_32 -sw $s0, -132($fp) - -# Load from local_c2i_at_A2I_internal_32 to $t0 -lw $t0, -132($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_29 -sw $t0, -120($fp) - -END_10: -# Load from local_c2i_at_A2I_internal_29 to $t0 -lw $t0, -120($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_26 -sw $t0, -108($fp) - -# GotoNode -j END_9 -TRUE_9: -li $s0, 8 -# from src: $s0 to dst: local_c2i_at_A2I_internal_33 -sw $s0, -136($fp) - -# Load from local_c2i_at_A2I_internal_33 to $t0 -lw $t0, -136($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_26 -sw $t0, -108($fp) - -END_9: -# Load from local_c2i_at_A2I_internal_26 to $t0 -lw $t0, -108($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_23 -sw $t0, -96($fp) - -# GotoNode -j END_8 -TRUE_8: -li $s0, 7 -# from src: $s0 to dst: local_c2i_at_A2I_internal_34 -sw $s0, -140($fp) - -# Load from local_c2i_at_A2I_internal_34 to $t0 -lw $t0, -140($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_23 -sw $t0, -96($fp) - -END_8: -# Load from local_c2i_at_A2I_internal_23 to $t0 -lw $t0, -96($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_20 -sw $t0, -84($fp) - -# GotoNode -j END_7 -TRUE_7: -li $s0, 6 -# from src: $s0 to dst: local_c2i_at_A2I_internal_35 -sw $s0, -144($fp) - -# Load from local_c2i_at_A2I_internal_35 to $t0 -lw $t0, -144($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_20 -sw $t0, -84($fp) - -END_7: -# Load from local_c2i_at_A2I_internal_20 to $t0 -lw $t0, -84($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_17 -sw $t0, -72($fp) - -# GotoNode -j END_6 -TRUE_6: -li $s0, 5 -# from src: $s0 to dst: local_c2i_at_A2I_internal_36 -sw $s0, -148($fp) - -# Load from local_c2i_at_A2I_internal_36 to $t0 -lw $t0, -148($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_17 -sw $t0, -72($fp) - -END_6: -# Load from local_c2i_at_A2I_internal_17 to $t0 -lw $t0, -72($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_14 -sw $t0, -60($fp) - -# GotoNode -j END_5 -TRUE_5: -li $s0, 4 -# from src: $s0 to dst: local_c2i_at_A2I_internal_37 -sw $s0, -152($fp) - -# Load from local_c2i_at_A2I_internal_37 to $t0 -lw $t0, -152($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_14 -sw $t0, -60($fp) - -END_5: -# Load from local_c2i_at_A2I_internal_14 to $t0 -lw $t0, -60($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_11 -sw $t0, -48($fp) - -# GotoNode -j END_4 -TRUE_4: -li $s0, 3 -# from src: $s0 to dst: local_c2i_at_A2I_internal_38 -sw $s0, -156($fp) - -# Load from local_c2i_at_A2I_internal_38 to $t0 -lw $t0, -156($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_11 -sw $t0, -48($fp) - -END_4: -# Load from local_c2i_at_A2I_internal_11 to $t0 -lw $t0, -48($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_8 -sw $t0, -36($fp) - -# GotoNode -j END_3 -TRUE_3: -li $s0, 2 -# from src: $s0 to dst: local_c2i_at_A2I_internal_39 -sw $s0, -160($fp) - -# Load from local_c2i_at_A2I_internal_39 to $t0 -lw $t0, -160($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_8 -sw $t0, -36($fp) - -END_3: -# Load from local_c2i_at_A2I_internal_8 to $t0 -lw $t0, -36($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_5 -sw $t0, -24($fp) - -# GotoNode -j END_2 -TRUE_2: -li $s0, 1 -# from src: $s0 to dst: local_c2i_at_A2I_internal_40 -sw $s0, -164($fp) - -# Load from local_c2i_at_A2I_internal_40 to $t0 -lw $t0, -164($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_5 -sw $t0, -24($fp) - -END_2: -# Load from local_c2i_at_A2I_internal_5 to $t0 -lw $t0, -24($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_2 -sw $t0, -12($fp) - -# GotoNode -j END_1 -TRUE_1: -li $s0, 0 -# from src: $s0 to dst: local_c2i_at_A2I_internal_41 -sw $s0, -168($fp) - -# Load from local_c2i_at_A2I_internal_41 to $t0 -lw $t0, -168($fp) -# from src: $t0 to dst: local_c2i_at_A2I_internal_2 -sw $t0, -12($fp) - -END_1: -# ReturnNode -# Load from local_c2i_at_A2I_internal_2 to $v0 -lw $v0, -12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 168 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2c_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -168 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -# from src: $s0 to dst: local_i2c_at_A2I_internal_0 -sw $s0, -4($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_0 to $t1 -lw $t1, -4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_1 -sw $t1, -8($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_1 to $t0 -lw $t0, -8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_21 -li $s0, 1 -# from src: $s0 to dst: local_i2c_at_A2I_internal_3 -sw $s0, -16($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_3 to $t1 -lw $t1, -16($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_4 -sw $t1, -20($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_4 to $t0 -lw $t0, -20($fp) -li $t1, 0 -bne $t0, $t1, TRUE_22 -li $s0, 2 -# from src: $s0 to dst: local_i2c_at_A2I_internal_6 -sw $s0, -28($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_6 to $t1 -lw $t1, -28($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_7 -sw $t1, -32($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_7 to $t0 -lw $t0, -32($fp) -li $t1, 0 -bne $t0, $t1, TRUE_23 -li $s0, 3 -# from src: $s0 to dst: local_i2c_at_A2I_internal_9 -sw $s0, -40($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_9 to $t1 -lw $t1, -40($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_10 -sw $t1, -44($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_10 to $t0 -lw $t0, -44($fp) -li $t1, 0 -bne $t0, $t1, TRUE_24 -li $s0, 4 -# from src: $s0 to dst: local_i2c_at_A2I_internal_12 -sw $s0, -52($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_12 to $t1 -lw $t1, -52($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_13 -sw $t1, -56($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_13 to $t0 -lw $t0, -56($fp) -li $t1, 0 -bne $t0, $t1, TRUE_25 -li $s0, 5 -# from src: $s0 to dst: local_i2c_at_A2I_internal_15 -sw $s0, -64($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_15 to $t1 -lw $t1, -64($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_16 -sw $t1, -68($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_16 to $t0 -lw $t0, -68($fp) -li $t1, 0 -bne $t0, $t1, TRUE_26 -li $s0, 6 -# from src: $s0 to dst: local_i2c_at_A2I_internal_18 -sw $s0, -76($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_18 to $t1 -lw $t1, -76($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_19 -sw $t1, -80($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_19 to $t0 -lw $t0, -80($fp) -li $t1, 0 -bne $t0, $t1, TRUE_27 -li $s0, 7 -# from src: $s0 to dst: local_i2c_at_A2I_internal_21 -sw $s0, -88($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_21 to $t1 -lw $t1, -88($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_22 -sw $t1, -92($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_22 to $t0 -lw $t0, -92($fp) -li $t1, 0 -bne $t0, $t1, TRUE_28 -li $s0, 8 -# from src: $s0 to dst: local_i2c_at_A2I_internal_24 -sw $s0, -100($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_24 to $t1 -lw $t1, -100($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_25 -sw $t1, -104($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_25 to $t0 -lw $t0, -104($fp) -li $t1, 0 -bne $t0, $t1, TRUE_29 -li $s0, 9 -# from src: $s0 to dst: local_i2c_at_A2I_internal_27 -sw $s0, -112($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2c_at_A2I_internal_27 to $t1 -lw $t1, -112($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2c_at_A2I_internal_28 -sw $t1, -116($fp) - -# IfGotoNode -# Load from local_i2c_at_A2I_internal_28 to $t0 -lw $t0, -116($fp) -li $t1, 0 -bne $t0, $t1, TRUE_30 -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I abort -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 0 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2c_at_A2I_internal_30 -sw $v0, -124($fp) - -addi $sp, $sp, 4 -# Load from data_15 to $s0 -la $s0, data_15 -# from src: $s0 to dst: local_i2c_at_A2I_internal_31 -sw $s0, -128($fp) - -# Load from local_i2c_at_A2I_internal_31 to $t0 -lw $t0, -128($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_29 -sw $t0, -120($fp) - -# GotoNode -j END_30 -TRUE_30: -# Load from data_14 to $s0 -la $s0, data_14 -# from src: $s0 to dst: local_i2c_at_A2I_internal_32 -sw $s0, -132($fp) - -# Load from local_i2c_at_A2I_internal_32 to $t0 -lw $t0, -132($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_29 -sw $t0, -120($fp) - -END_30: -# Load from local_i2c_at_A2I_internal_29 to $t0 -lw $t0, -120($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_26 -sw $t0, -108($fp) - -# GotoNode -j END_29 -TRUE_29: -# Load from data_13 to $s0 -la $s0, data_13 -# from src: $s0 to dst: local_i2c_at_A2I_internal_33 -sw $s0, -136($fp) - -# Load from local_i2c_at_A2I_internal_33 to $t0 -lw $t0, -136($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_26 -sw $t0, -108($fp) - -END_29: -# Load from local_i2c_at_A2I_internal_26 to $t0 -lw $t0, -108($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_23 -sw $t0, -96($fp) - -# GotoNode -j END_28 -TRUE_28: -# Load from data_12 to $s0 -la $s0, data_12 -# from src: $s0 to dst: local_i2c_at_A2I_internal_34 -sw $s0, -140($fp) - -# Load from local_i2c_at_A2I_internal_34 to $t0 -lw $t0, -140($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_23 -sw $t0, -96($fp) - -END_28: -# Load from local_i2c_at_A2I_internal_23 to $t0 -lw $t0, -96($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_20 -sw $t0, -84($fp) - -# GotoNode -j END_27 -TRUE_27: -# Load from data_11 to $s0 -la $s0, data_11 -# from src: $s0 to dst: local_i2c_at_A2I_internal_35 -sw $s0, -144($fp) - -# Load from local_i2c_at_A2I_internal_35 to $t0 -lw $t0, -144($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_20 -sw $t0, -84($fp) - -END_27: -# Load from local_i2c_at_A2I_internal_20 to $t0 -lw $t0, -84($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_17 -sw $t0, -72($fp) - -# GotoNode -j END_26 -TRUE_26: -# Load from data_10 to $s0 -la $s0, data_10 -# from src: $s0 to dst: local_i2c_at_A2I_internal_36 -sw $s0, -148($fp) - -# Load from local_i2c_at_A2I_internal_36 to $t0 -lw $t0, -148($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_17 -sw $t0, -72($fp) - -END_26: -# Load from local_i2c_at_A2I_internal_17 to $t0 -lw $t0, -72($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_14 -sw $t0, -60($fp) - -# GotoNode -j END_25 -TRUE_25: -# Load from data_9 to $s0 -la $s0, data_9 -# from src: $s0 to dst: local_i2c_at_A2I_internal_37 -sw $s0, -152($fp) - -# Load from local_i2c_at_A2I_internal_37 to $t0 -lw $t0, -152($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_14 -sw $t0, -60($fp) - -END_25: -# Load from local_i2c_at_A2I_internal_14 to $t0 -lw $t0, -60($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_11 -sw $t0, -48($fp) - -# GotoNode -j END_24 -TRUE_24: -# Load from data_8 to $s0 -la $s0, data_8 -# from src: $s0 to dst: local_i2c_at_A2I_internal_38 -sw $s0, -156($fp) - -# Load from local_i2c_at_A2I_internal_38 to $t0 -lw $t0, -156($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_11 -sw $t0, -48($fp) - -END_24: -# Load from local_i2c_at_A2I_internal_11 to $t0 -lw $t0, -48($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_8 -sw $t0, -36($fp) - -# GotoNode -j END_23 -TRUE_23: -# Load from data_7 to $s0 -la $s0, data_7 -# from src: $s0 to dst: local_i2c_at_A2I_internal_39 -sw $s0, -160($fp) - -# Load from local_i2c_at_A2I_internal_39 to $t0 -lw $t0, -160($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_8 -sw $t0, -36($fp) - -END_23: -# Load from local_i2c_at_A2I_internal_8 to $t0 -lw $t0, -36($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_5 -sw $t0, -24($fp) - -# GotoNode -j END_22 -TRUE_22: -# Load from data_6 to $s0 -la $s0, data_6 -# from src: $s0 to dst: local_i2c_at_A2I_internal_40 -sw $s0, -164($fp) - -# Load from local_i2c_at_A2I_internal_40 to $t0 -lw $t0, -164($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_5 -sw $t0, -24($fp) - -END_22: -# Load from local_i2c_at_A2I_internal_5 to $t0 -lw $t0, -24($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_2 -sw $t0, -12($fp) - -# GotoNode -j END_21 -TRUE_21: -# Load from data_5 to $s0 -la $s0, data_5 -# from src: $s0 to dst: local_i2c_at_A2I_internal_41 -sw $s0, -168($fp) - -# Load from local_i2c_at_A2I_internal_41 to $t0 -lw $t0, -168($fp) -# from src: $t0 to dst: local_i2c_at_A2I_internal_2 -sw $t0, -12($fp) - -END_21: -# ReturnNode -# Load from local_i2c_at_A2I_internal_2 to $v0 -lw $v0, -12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 168 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_a2i_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -124 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_0 -sw $v0, -4($fp) - -addi $sp, $sp, 4 -li $s0, 0 -# from src: $s0 to dst: local_a2i_at_A2I_internal_1 -sw $s0, -8($fp) - -# Load from local_a2i_at_A2I_internal_0 to $t0 -lw $t0, -4($fp) -# Load from local_a2i_at_A2I_internal_1 to $t1 -lw $t1, -8($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_a2i_at_A2I_internal_2 -sw $t1, -12($fp) - -# IfGotoNode -# Load from local_a2i_at_A2I_internal_2 to $t0 -lw $t0, -12($fp) -li $t1, 0 -bne $t0, $t1, TRUE_41 -li $s0, 0 -# from src: $s0 to dst: local_a2i_at_A2I_internal_5 -sw $s0, -24($fp) - -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_6 -sw $s0, -28($fp) - -# ArgNode local_a2i_at_A2I_internal_6 to s0 -# Load from local_a2i_at_A2I_internal_6 to $s0 -lw $s0, -28($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_5 to s0 -# Load from local_a2i_at_A2I_internal_5 to $s0 -lw $s0, -24($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_4 -sw $v0, -20($fp) - -addi $sp, $sp, 12 -# Load from data_16 to $s0 -la $s0, data_16 -# from src: $s0 to dst: local_a2i_at_A2I_internal_7 -sw $s0, -32($fp) - - -# Comparing Strings -- -# Load from local_a2i_at_A2I_internal_4 to $s0 -lw $s0, -20($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_a2i_at_A2I_internal_7 to $s1 -lw $s1, -32($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_100: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_98 -beqz $a1, mips_label_99 -seq $v0, $a0, $a1 -beqz $v0, mips_label_99 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_100 -mips_label_99: -li $v0, 0 -j mips_label_97 -mips_label_98: -bnez $a1, mips_label_99 -li $v0, 1 -mips_label_97: -# from src: $v0 to dst: local_a2i_at_A2I_internal_8 -sw $v0, -36($fp) - -# IfGotoNode -# Load from local_a2i_at_A2I_internal_8 to $t0 -lw $t0, -36($fp) -li $t1, 0 -bne $t0, $t1, TRUE_42 -li $s0, 0 -# from src: $s0 to dst: local_a2i_at_A2I_internal_11 -sw $s0, -48($fp) - -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_12 -sw $s0, -52($fp) - -# ArgNode local_a2i_at_A2I_internal_12 to s0 -# Load from local_a2i_at_A2I_internal_12 to $s0 -lw $s0, -52($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_11 to s0 -# Load from local_a2i_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_10 -sw $v0, -44($fp) - -addi $sp, $sp, 12 -# Load from data_17 to $s0 -la $s0, data_17 -# from src: $s0 to dst: local_a2i_at_A2I_internal_13 -sw $s0, -56($fp) - - -# Comparing Strings -- -# Load from local_a2i_at_A2I_internal_10 to $s0 -lw $s0, -44($fp) -move $a0, $s0 -li $v0, 1 -syscall -# Load from local_a2i_at_A2I_internal_13 to $s1 -lw $s1, -56($fp) -move $t8, $s0 -move $t9, $s1 -mips_label_104: -lb $a0, 0($t8) -lb $a1, 0($t9) -beqz $a0, mips_label_102 -beqz $a1, mips_label_103 -seq $v0, $a0, $a1 -beqz $v0, mips_label_103 -addi $t8, $t8, 1 -addi $t9, $t9, 1 -j mips_label_104 -mips_label_103: -li $v0, 0 -j mips_label_101 -mips_label_102: -bnez $a1, mips_label_103 -li $v0, 1 -mips_label_101: -# from src: $v0 to dst: local_a2i_at_A2I_internal_14 -sw $v0, -60($fp) - -# IfGotoNode -# Load from local_a2i_at_A2I_internal_14 to $t0 -lw $t0, -60($fp) -li $t1, 0 -bne $t0, $t1, TRUE_43 -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_16 -sw $v0, -68($fp) - -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_16 to $t0 -lw $t0, -68($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_15 -sw $t0, -64($fp) - -# GotoNode -j END_43 -TRUE_43: -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_19 -sw $s0, -80($fp) - -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_21 -sw $v0, -88($fp) - -addi $sp, $sp, 4 -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_22 -sw $s0, -92($fp) - -# Load from local_a2i_at_A2I_internal_21 to $t0 -lw $t0, -88($fp) -# Load from local_a2i_at_A2I_internal_22 to $t1 -lw $t1, -92($fp) -sub $t2, $t0, $t1 -# from src: $t2 to dst: local_a2i_at_A2I_internal_20 -sw $t2, -84($fp) - -# ArgNode local_a2i_at_A2I_internal_20 to s0 -# Load from local_a2i_at_A2I_internal_20 to $s0 -lw $s0, -84($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_19 to s0 -# Load from local_a2i_at_A2I_internal_19 to $s0 -lw $s0, -80($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_18 -sw $v0, -76($fp) - -addi $sp, $sp, 12 -# ArgNode local_a2i_at_A2I_internal_18 to s0 -# Load from local_a2i_at_A2I_internal_18 to $s0 -lw $s0, -76($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_17 -sw $v0, -72($fp) - -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_17 to $t0 -lw $t0, -72($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_15 -sw $t0, -64($fp) - -END_43: -# Load from local_a2i_at_A2I_internal_15 to $t0 -lw $t0, -64($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_9 -sw $t0, -40($fp) - -# GotoNode -j END_42 -TRUE_42: -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_26 -sw $s0, -108($fp) - -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_28 -sw $v0, -116($fp) - -addi $sp, $sp, 4 -li $s0, 1 -# from src: $s0 to dst: local_a2i_at_A2I_internal_29 -sw $s0, -120($fp) - -# Load from local_a2i_at_A2I_internal_28 to $t0 -lw $t0, -116($fp) -# Load from local_a2i_at_A2I_internal_29 to $t1 -lw $t1, -120($fp) -sub $t2, $t0, $t1 -# from src: $t2 to dst: local_a2i_at_A2I_internal_27 -sw $t2, -112($fp) - -# ArgNode local_a2i_at_A2I_internal_27 to s0 -# Load from local_a2i_at_A2I_internal_27 to $s0 -lw $s0, -112($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_at_A2I_internal_26 to s0 -# Load from local_a2i_at_A2I_internal_26 to $s0 -lw $s0, -108($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_25 -sw $v0, -104($fp) - -addi $sp, $sp, 12 -# ArgNode local_a2i_at_A2I_internal_25 to s0 -# Load from local_a2i_at_A2I_internal_25 to $s0 -lw $s0, -104($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I a2i_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 24 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_at_A2I_internal_24 -sw $v0, -100($fp) - -addi $sp, $sp, 8 -# Load from local_a2i_at_A2I_internal_24 to $t0 -lw $t0, -100($fp) -nor $t1, $t0, $t0 -# from src: $t1 to dst: local_a2i_at_A2I_internal_23 -sw $t1, -96($fp) - -# Load from local_a2i_at_A2I_internal_23 to $t0 -lw $t0, -96($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_9 -sw $t0, -40($fp) - -END_42: -# Load from local_a2i_at_A2I_internal_9 to $t0 -lw $t0, -40($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_3 -sw $t0, -16($fp) - -# GotoNode -j END_41 -TRUE_41: -li $s0, 0 -# from src: $s0 to dst: local_a2i_at_A2I_internal_30 -sw $s0, -124($fp) - -# Load from local_a2i_at_A2I_internal_30 to $t0 -lw $t0, -124($fp) -# from src: $t0 to dst: local_a2i_at_A2I_internal_3 -sw $t0, -16($fp) - -END_41: -# ReturnNode -# Load from local_a2i_at_A2I_internal_3 to $v0 -lw $v0, -16($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 124 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_a2i_aux_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -60 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_1 -sw $s0, -8($fp) - -# Load from local_a2i_aux_at_A2I_internal_1 to $t0 -lw $t0, -8($fp) -# from src: $t0 to dst: local_a2i_aux_at_A2I_int_0 -sw $t0, -4($fp) - -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String length -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_3 -sw $v0, -16($fp) - -addi $sp, $sp, 4 -# Load from local_a2i_aux_at_A2I_internal_3 to $t0 -lw $t0, -16($fp) -# from src: $t0 to dst: local_a2i_aux_at_A2I_j_2 -sw $t0, -12($fp) - -li $s0, 0 -# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_5 -sw $s0, -24($fp) - -# Load from local_a2i_aux_at_A2I_internal_5 to $t0 -lw $t0, -24($fp) -# from src: $t0 to dst: local_a2i_aux_at_A2I_i_4 -sw $t0, -20($fp) - -START_47: -# Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, -20($fp) -# Load from local_a2i_aux_at_A2I_j_2 to $t1 -lw $t1, -12($fp) -slt $t2, $t0, $t1 -# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_6 -sw $t2, -28($fp) - -# IfGotoNode -# Load from local_a2i_aux_at_A2I_internal_6 to $t0 -lw $t0, -28($fp) -li $t1, 0 -bne $t0, $t1, CONTINUE_47 -# GotoNode -j END_47 -CONTINUE_47: -li $s0, 10 -# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_9 -sw $s0, -40($fp) - -# Load from local_a2i_aux_at_A2I_int_0 to $t0 -lw $t0, -4($fp) -# Load from local_a2i_aux_at_A2I_internal_9 to $t1 -lw $t1, -40($fp) -mult $t0, $t1 -mflo $t0 -# from src: $t0 to dst: local_a2i_aux_at_A2I_internal_8 -sw $t0, -36($fp) - -li $s0, 1 -# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_12 -sw $s0, -52($fp) - -# ArgNode local_a2i_aux_at_A2I_internal_12 to s0 -# Load from local_a2i_aux_at_A2I_internal_12 to $s0 -lw $s0, -52($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_a2i_aux_at_A2I_i_4 to s0 -# Load from local_a2i_aux_at_A2I_i_4 to $s0 -lw $s0, -20($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode s to s0 -# Load from s to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String substr -# Load from s to $s0 -lw $s0, 8($fp) -lw $s1, 12($s0) -addi $s2, $s1, 20 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_11 -sw $v0, -48($fp) - -addi $sp, $sp, 12 -# ArgNode local_a2i_aux_at_A2I_internal_11 to s0 -# Load from local_a2i_aux_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I c2i -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_a2i_aux_at_A2I_internal_10 -sw $v0, -44($fp) - -addi $sp, $sp, 8 -# Load from local_a2i_aux_at_A2I_internal_8 to $t0 -lw $t0, -36($fp) -# Load from local_a2i_aux_at_A2I_internal_10 to $t1 -lw $t1, -44($fp) -add $t2, $t0, $t1 -# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_7 -sw $t2, -32($fp) - -# Load from local_a2i_aux_at_A2I_internal_7 to $t0 -lw $t0, -32($fp) -# from src: $t0 to dst: local_a2i_aux_at_A2I_int_0 -sw $t0, -4($fp) - -li $s0, 1 -# from src: $s0 to dst: local_a2i_aux_at_A2I_internal_14 -sw $s0, -60($fp) - -# Load from local_a2i_aux_at_A2I_i_4 to $t0 -lw $t0, -20($fp) -# Load from local_a2i_aux_at_A2I_internal_14 to $t1 -lw $t1, -60($fp) -add $t2, $t0, $t1 -# from src: $t2 to dst: local_a2i_aux_at_A2I_internal_13 -sw $t2, -56($fp) - -# Load from local_a2i_aux_at_A2I_internal_13 to $t0 -lw $t0, -56($fp) -# from src: $t0 to dst: local_a2i_aux_at_A2I_i_4 -sw $t0, -20($fp) - -# GotoNode -j START_47 -END_47: -# ReturnNode -# Load from local_a2i_aux_at_A2I_int_0 to $v0 -lw $v0, -4($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 60 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2a_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -56 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -# from src: $s0 to dst: local_i2a_at_A2I_internal_0 -sw $s0, -4($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_at_A2I_internal_0 to $t1 -lw $t1, -4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2a_at_A2I_internal_1 -sw $t1, -8($fp) - -# IfGotoNode -# Load from local_i2a_at_A2I_internal_1 to $t0 -lw $t0, -8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_49 -li $s0, 0 -# from src: $s0 to dst: local_i2a_at_A2I_internal_4 -sw $s0, -20($fp) - -# Load from local_i2a_at_A2I_internal_4 to $t0 -lw $t0, -20($fp) -# Load from i to $t1 -lw $t1, 8($fp) -slt $t2, $t0, $t1 -# from src: $t2 to dst: local_i2a_at_A2I_internal_3 -sw $t2, -16($fp) - -# IfGotoNode -# Load from local_i2a_at_A2I_internal_3 to $t0 -lw $t0, -16($fp) -li $t1, 0 -bne $t0, $t1, TRUE_50 -li $s0, 1 -# from src: $s0 to dst: local_i2a_at_A2I_internal_10 -sw $s0, -44($fp) - -# Load from local_i2a_at_A2I_internal_10 to $t0 -lw $t0, -44($fp) -nor $t1, $t0, $t0 -# from src: $t1 to dst: local_i2a_at_A2I_internal_9 -sw $t1, -40($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_at_A2I_internal_9 to $t1 -lw $t1, -40($fp) -mult $t0, $t1 -mflo $t0 -# from src: $t0 to dst: local_i2a_at_A2I_internal_8 -sw $t0, -36($fp) - -# ArgNode local_i2a_at_A2I_internal_8 to s0 -# Load from local_i2a_at_A2I_internal_8 to $s0 -lw $s0, -36($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_at_A2I_internal_7 -sw $v0, -32($fp) - -addi $sp, $sp, 8 -# ArgNode local_i2a_at_A2I_internal_7 to s0 -# Load from local_i2a_at_A2I_internal_7 to $s0 -lw $s0, -32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Load from data_16 to $s0 -la $s0, data_16 -# from src: $s0 to dst: local_i2a_at_A2I_internal_11 -sw $s0, -48($fp) - -# ArgNode local_i2a_at_A2I_internal_11 to s0 -# Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String concat -# Load from local_i2a_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_at_A2I_internal_6 -sw $v0, -28($fp) - -addi $sp, $sp, 8 -# Load from local_i2a_at_A2I_internal_6 to $t0 -lw $t0, -28($fp) -# from src: $t0 to dst: local_i2a_at_A2I_internal_5 -sw $t0, -24($fp) - -# GotoNode -j END_50 -TRUE_50: -# ArgNode i to s0 -# Load from i to $s0 -lw $s0, 8($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_at_A2I_internal_12 -sw $v0, -52($fp) - -addi $sp, $sp, 8 -# Load from local_i2a_at_A2I_internal_12 to $t0 -lw $t0, -52($fp) -# from src: $t0 to dst: local_i2a_at_A2I_internal_5 -sw $t0, -24($fp) - -END_50: -# Load from local_i2a_at_A2I_internal_5 to $t0 -lw $t0, -24($fp) -# from src: $t0 to dst: local_i2a_at_A2I_internal_2 -sw $t0, -12($fp) - -# GotoNode -j END_49 -TRUE_49: -# Load from data_5 to $s0 -la $s0, data_5 -# from src: $s0 to dst: local_i2a_at_A2I_internal_13 -sw $s0, -56($fp) - -# Load from local_i2a_at_A2I_internal_13 to $t0 -lw $t0, -56($fp) -# from src: $t0 to dst: local_i2a_at_A2I_internal_2 -sw $t0, -12($fp) - -END_49: -# ReturnNode -# Load from local_i2a_at_A2I_internal_2 to $v0 -lw $v0, -12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 56 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_i2a_aux_at_A2I: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -52 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -li $s0, 0 -# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_0 -sw $s0, -4($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_0 to $t1 -lw $t1, -4($fp) -slt $t2, $t0, $t1 -slt $t3, $t1, $t0 -add $t0, $t2, $t3 -slti $t1, $t0, 1 -# from src: $t1 to dst: local_i2a_aux_at_A2I_internal_1 -sw $t1, -8($fp) - -# IfGotoNode -# Load from local_i2a_aux_at_A2I_internal_1 to $t0 -lw $t0, -8($fp) -li $t1, 0 -bne $t0, $t1, TRUE_53 -li $s0, 10 -# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_5 -sw $s0, -24($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_5 to $t1 -lw $t1, -24($fp) -div $t2, $t0, $t1 -mflo $t0 -# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_4 -sw $t0, -20($fp) - -# Load from local_i2a_aux_at_A2I_internal_4 to $t0 -lw $t0, -20($fp) -# from src: $t0 to dst: local_i2a_aux_at_A2I_next_3 -sw $t0, -16($fp) - -li $s0, 10 -# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_10 -sw $s0, -44($fp) - -# Load from local_i2a_aux_at_A2I_next_3 to $t0 -lw $t0, -16($fp) -# Load from local_i2a_aux_at_A2I_internal_10 to $t1 -lw $t1, -44($fp) -mult $t0, $t1 -mflo $t0 -# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_9 -sw $t0, -40($fp) - -# Load from i to $t0 -lw $t0, 8($fp) -# Load from local_i2a_aux_at_A2I_internal_9 to $t1 -lw $t1, -40($fp) -sub $t2, $t0, $t1 -# from src: $t2 to dst: local_i2a_aux_at_A2I_internal_8 -sw $t2, -36($fp) - -# ArgNode local_i2a_aux_at_A2I_internal_8 to s0 -# Load from local_i2a_aux_at_A2I_internal_8 to $s0 -lw $s0, -36($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2c -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_7 -sw $v0, -32($fp) - -addi $sp, $sp, 8 -# ArgNode local_i2a_aux_at_A2I_internal_7 to s0 -# Load from local_i2a_aux_at_A2I_internal_7 to $s0 -lw $s0, -32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode local_i2a_aux_at_A2I_next_3 to s0 -# Load from local_i2a_aux_at_A2I_next_3 to $s0 -lw $s0, -16($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a_aux -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 32 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_11 -sw $v0, -48($fp) - -addi $sp, $sp, 8 -# ArgNode local_i2a_aux_at_A2I_internal_11 to s0 -# Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode String concat -# Load from local_i2a_aux_at_A2I_internal_11 to $s0 -lw $s0, -48($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_i2a_aux_at_A2I_internal_6 -sw $v0, -28($fp) - -addi $sp, $sp, 8 -# Load from local_i2a_aux_at_A2I_internal_6 to $t0 -lw $t0, -28($fp) -# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_2 -sw $t0, -12($fp) - -# GotoNode -j END_53 -TRUE_53: -# Load from data_15 to $s0 -la $s0, data_15 -# from src: $s0 to dst: local_i2a_aux_at_A2I_internal_12 -sw $s0, -52($fp) - -# Load from local_i2a_aux_at_A2I_internal_12 to $t0 -lw $t0, -52($fp) -# from src: $t0 to dst: local_i2a_aux_at_A2I_internal_2 -sw $t0, -12($fp) - -END_53: -# ReturnNode -# Load from local_i2a_aux_at_A2I_internal_2 to $v0 -lw $v0, -12($fp) - -# Restore registers -lw $s6, 0($sp) -addi $sp, $sp, 4 -lw $s5, 0($sp) -addi $sp, $sp, 4 -lw $s4, 0($sp) -addi $sp, $sp, 4 -lw $s3, 0($sp) -addi $sp, $sp, 4 -lw $s2, 0($sp) -addi $sp, $sp, 4 -lw $s1, 0($sp) -addi $sp, $sp, 4 -lw $s0, 0($sp) -addi $sp, $sp, 4 -lw $ra, 0($sp) -addi $sp, $sp, 4 - -# Clean stack variable space -addi $sp, $sp, 52 -# Return -lw $fp, 0($sp) -addi $sp, $sp, 4 -jr $ra -function_main_at_Main: -# Set stack frame -addi $sp, $sp, -4 -sw $fp, 0($sp) -move $fp, $sp - -# Allocate memory for Local variables -addi $sp, $sp, -56 - - -# Saving Registers -addi $sp, $sp, -4 -sw $ra, 0($sp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -addi $sp, $sp, -4 -sw $s1, 0($sp) -addi $sp, $sp, -4 -sw $s2, 0($sp) -addi $sp, $sp, -4 -sw $s3, 0($sp) -addi $sp, $sp, -4 -sw $s4, 0($sp) -addi $sp, $sp, -4 -sw $s5, 0($sp) -addi $sp, $sp, -4 -sw $s6, 0($sp) - -# Generating body code -# Load from data_18 to $s0 -la $s0, data_18 -# from src: $s0 to dst: local_main_at_Main_internal_2 -sw $s0, -12($fp) - -# ArgNode local_main_at_Main_internal_2 to s0 -# Load from local_main_at_Main_internal_2 to $s0 -lw $s0, -12($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Allocate space for A2I -li $a0, 16 -li $v0, 9 +# Allocate space for Object +li $a0, 16 +li $v0, 9 syscall move $s1, $v0 -# from src: $s1 to dst: local_main_at_Main_internal_3 -sw $s1, -16($fp) +# from src: $s1 to dst: local_main_at_Main_internal_2 +sw $s1, -12($fp) -li $s0, 5 +li $s0, 0 sw $s0, 0($s1) li $s0, 16 sw $s0, 4($s1) -la $s0, classname_A2I +la $s0, classname_Object sw $s0, 8($s1) -li $s0, 88 +li $s0, 0 sw $s0, 12($s1) -# ArgNode local_main_at_Main_internal_3 to s0 -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, -16($fp) +# ArgNode local_main_at_Main_internal_2 to s0 +# Load from local_main_at_Main_internal_2 to $s0 +lw $s0, -12($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # StaticCallNode -jal ctor_A2I -# from src: $v0 to dst: local_main_at_Main_internal_3 -sw $v0, -16($fp) +jal ctor_Object +# from src: $v0 to dst: local_main_at_Main_internal_2 +sw $v0, -12($fp) -# ArgNode local_main_at_Main_internal_3 to s0 -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, -16($fp) +addi $sp, $sp, 4 +# ArgNode local_main_at_Main_internal_2 to s0 +# Load from local_main_at_Main_internal_2 to $s0 +lw $s0, -12($fp) addi $sp, $sp, -4 sw $s0, 0($sp) -# DynamicCallNode A2I a2i -# Load from local_main_at_Main_internal_3 to $s0 -lw $s0, -16($fp) +# DynamicCallNode Object type_name +# Load from local_main_at_Main_internal_2 to $s0 +lw $s0, -12($fp) lw $s1, 12($s0) -addi $s2, $s1, 20 +addi $s2, $s1, 4 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 # from src: $v0 to dst: local_main_at_Main_internal_1 sw $v0, -8($fp) -addi $sp, $sp, 8 -# Load from local_main_at_Main_internal_1 to $t0 -lw $t0, -8($fp) -# from src: $t0 to dst: local_main_at_Main_a_0 -sw $t0, -4($fp) - -li $s0, 678987 -# from src: $s0 to dst: local_main_at_Main_internal_6 -sw $s0, -28($fp) - -# ArgNode local_main_at_Main_internal_6 to s0 -# Load from local_main_at_Main_internal_6 to $s0 -lw $s0, -28($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# Allocate space for A2I -li $a0, 16 -li $v0, 9 -syscall -move $s1, $v0 -# from src: $s1 to dst: local_main_at_Main_internal_7 -sw $s1, -32($fp) - -li $s0, 5 -sw $s0, 0($s1) -li $s0, 16 -sw $s0, 4($s1) -la $s0, classname_A2I -sw $s0, 8($s1) -li $s0, 88 -sw $s0, 12($s1) -# ArgNode local_main_at_Main_internal_7 to s0 -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, -32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# StaticCallNode -jal ctor_A2I -# from src: $v0 to dst: local_main_at_Main_internal_7 -sw $v0, -32($fp) - -# ArgNode local_main_at_Main_internal_7 to s0 -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, -32($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode A2I i2a -# Load from local_main_at_Main_internal_7 to $s0 -lw $s0, -32($fp) -lw $s1, 12($s0) -addi $s2, $s1, 28 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_main_at_Main_internal_5 -sw $v0, -24($fp) - -addi $sp, $sp, 8 -# Load from local_main_at_Main_internal_5 to $t0 -lw $t0, -24($fp) -# from src: $t0 to dst: local_main_at_Main_b_4 -sw $t0, -20($fp) - -# ArgNode local_main_at_Main_a_0 to s0 -# Load from local_main_at_Main_a_0 to $s0 -lw $s0, -4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_int -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 16 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_main_at_Main_internal_8 -sw $v0, -36($fp) - -addi $sp, $sp, 8 -# Load from data_19 to $s0 -la $s0, data_19 -# from src: $s0 to dst: local_main_at_Main_internal_10 -sw $s0, -44($fp) - -# ArgNode local_main_at_Main_internal_10 to s0 -# Load from local_main_at_Main_internal_10 to $s0 -lw $s0, -44($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_string -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_main_at_Main_internal_9 -sw $v0, -40($fp) - -addi $sp, $sp, 8 -# ArgNode local_main_at_Main_b_4 to s0 -# Load from local_main_at_Main_b_4 to $s0 -lw $s0, -20($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# ArgNode self to s0 -# Load from self to $s0 -lw $s0, 4($fp) -addi $sp, $sp, -4 -sw $s0, 0($sp) -# DynamicCallNode Main out_string -# Load from self to $s0 -lw $s0, 4($fp) -lw $s1, 12($s0) -addi $s2, $s1, 12 -addu $s3, $s2, $s7 -lw $s4, 0($s3) -jalr $s4 -# from src: $v0 to dst: local_main_at_Main_internal_11 -sw $v0, -48($fp) - -addi $sp, $sp, 8 -# Load from data_20 to $s0 -la $s0, data_20 -# from src: $s0 to dst: local_main_at_Main_internal_13 -sw $s0, -56($fp) - -# ArgNode local_main_at_Main_internal_13 to s0 -# Load from local_main_at_Main_internal_13 to $s0 -lw $s0, -56($fp) +addi $sp, $sp, 4 +# ArgNode local_main_at_Main_internal_1 to s0 +# Load from local_main_at_Main_internal_1 to $s0 +lw $s0, -8($fp) addi $sp, $sp, -4 sw $s0, 0($sp) # ArgNode self to s0 @@ -4283,13 +1757,13 @@ addi $s2, $s1, 12 addu $s3, $s2, $s7 lw $s4, 0($s3) jalr $s4 -# from src: $v0 to dst: local_main_at_Main_internal_12 -sw $v0, -52($fp) +# from src: $v0 to dst: local_main_at_Main_internal_0 +sw $v0, -4($fp) addi $sp, $sp, 8 # ReturnNode -# Load from local_main_at_Main_internal_12 to $v0 -lw $v0, -52($fp) +# Load from local_main_at_Main_internal_0 to $v0 +lw $v0, -4($fp) # Restore registers lw $s6, 0($sp) @@ -4310,8 +1784,8 @@ lw $ra, 0($sp) addi $sp, $sp, 4 # Clean stack variable space -addi $sp, $sp, 56 +addi $sp, $sp, 12 # Return lw $fp, 0($sp) addi $sp, $sp, 4 -jr $ra \ No newline at end of file +jr $ra From e5cea6a0a4b50ceae4d8e7dfbc7c25efe9875868 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 10:37:48 -0500 Subject: [PATCH 160/191] fixing the passed type on the function call --- src/engine/codegen/to_cil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 15a02cbd..2d006fe6 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -341,7 +341,7 @@ def visit(self, node: cool.FunctionCallNode, scope): # self.register_instruction(ArgNode(obj)) packed = self.define_internal_local() alloc = self.define_internal_local() - self.register_instruction(AllocateNode(alloc, 'String')) + self.register_instruction(AllocateNode(alloc, typex)) self.register_instruction(ArgNode(alloc)) self.register_instruction(StaticCallNode(f"ctor_{typex}", alloc)) self.register_instruction(EmptyArgs(1)) From d90e9a8795571204caefc55c17b42970d091db60 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 10:51:32 -0500 Subject: [PATCH 161/191] notNode implemented --- src/engine/codegen/to_mips.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 6aff4c53..2a88a2f1 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -324,6 +324,14 @@ def visit(self, node: IsVoidNode): self.mips.label(label) self.store_memory(reg.t1, node.dest) + @visitor.when(NotNode) + def visit(self, node: NotNode): + self.mips.comment("NotNode") + self.load_memory(reg.s0, node.expression) + self.mips.li(reg.s1, 1) + self.mips.sub(reg.s2, reg.s1, reg.s0) + self.store_memory(reg.s2, node.dest) + @visitor.when(AllocateNode) def visit(self, node: AllocateNode): # ---------- @@ -508,7 +516,8 @@ def visit(self, node: TypeNameNode): self.mips.comment(f"TypeNameNode {node.dest} Type:{node.type}") self.load_memory(reg.t0, node.type) # ptr at 3rd position in memory ( 2 in base 0) - self.mips.load_memory(reg.t1, self.mips.offset(reg.t0, 2 * self.data_size)) + self.mips.load_memory( + reg.t1, self.mips.offset(reg.t0, 2 * self.data_size)) self.store_memory(reg.t1, node.dest) def get_string_length(self, src, dst): From ae14378d63d2a1283d8d08cc187161fc6634ba57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 17 Dec 2020 11:09:53 -0500 Subject: [PATCH 162/191] Improve Read Str ( remove last /n) --- src/engine/codegen/to_mips.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 2a88a2f1..3f8df1af 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -686,6 +686,29 @@ def visit(self, node): self.mips.li(reg.a1, 1024) self.mips.read_string() + self.mips.empty_line() + self.mips.comment("Remove last character from string") + + start = self.get_label() + end = self.get_label() + + self.mips.label(start) + # load byte by byte + self.mips.lb(reg.s2, self.mips.offset(reg.a0)) + # jump end if reached end line + self.mips.beq(reg.s2, 0, end) + # pointer += 1 + self.mips.addi(reg.a0, reg.a0, 1) + self.mips.j(start) + self.mips.label(end) + # go back 1 position + self.mips.addi(reg.a0, reg.a0, -1) + # change /n to /0 + self.mips.sb(reg.zero, self.mips.offset(reg.a0)) + + + + @visitor.when(PrintStrNode) def visit(self, node: PrintStrNode): self.mips.comment(f"Print str {node.str_addr}") From 2d5fbb300df52b19edff1c7908271c36656b17b9 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 11:18:23 -0500 Subject: [PATCH 163/191] removing syscall --- src/engine/codegen/to_mips.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 2a88a2f1..79d6a5be 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -596,8 +596,8 @@ def visit(self, node: StringEqualNode): loop_label = self.get_label() self.load_memory(reg.s0, node.msg1) - self.mips.move(reg.a0, reg.s0) - self.mips.syscall(1) + # self.mips.move(reg.a0, reg.s0) + # self.mips.syscall(1) self.load_memory(reg.s1, node.msg2) From 72df25858764bca00bc894bd78064db629c621a2 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 13:36:10 -0500 Subject: [PATCH 164/191] substr y concat work just fine --- src/engine/codegen/cil.py | 14 +++----------- src/engine/codegen/to_mips.py | 7 ++++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 8d595cc8..4055a5bf 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -166,7 +166,7 @@ def define_string_type(self): length_var = self.define_internal_local() self.register_instruction(LengthNode(length_var, real_value)) - eol = self.register_data(r'\n') + eol = self.register_data('\\n') msg_eol = self.define_internal_local() self.register_instruction(LoadNode(msg_eol, eol.name)) @@ -190,17 +190,9 @@ def define_string_type(self): self.register_instruction(ErrorNode()) self.register_instruction(no_error_label2) - # self.register_instruction(PlusNode(sum_var, start, length)) - # self.register_instruction(LessEqNode(cmp_var3, sum_var, length_var)) - # self.register_instruction(IfGotoNode(cmp_var3, no_error_label3.label)) - # error_msg = self.register_data("Invalid substring").name - # self.register_instruction(ConcatNode(msg_eol, error_msg, eol)) - # self.register_instruction(PrintStrNode(msg_eol)) - # self.register_instruction(no_error_label3) - # self.register_instruction(ErrorNode()) - self.register_instruction(SubstringNode( result, real_value, start, length)) + self.register_instruction(ReturnNode(result)) self.current_method = self.current_function = None @@ -272,7 +264,7 @@ def define_object_type(self): full_msg = self.define_internal_local() abort = self.register_data("Abort called from class ") - eol = self.register_data(r'\n') + eol = self.register_data('\\n') abort_msg = self.define_internal_local() self.register_instruction(LoadNode(abort_msg, abort.name)) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 9e45d0cb..ab9c52a5 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -571,6 +571,7 @@ def copy_str(self, src, dst, result): @visitor.when(ConcatNode) def visit(self, node: ConcatNode): + self.load_memory(reg.s0, node.msg1) self.load_memory(reg.s1, node.msg2) @@ -578,6 +579,7 @@ def visit(self, node: ConcatNode): self.get_string_length(reg.s1, reg.s5) self.mips.add(reg.a0, reg.s4, reg.s5) + self.mips.addi(reg.a0, reg.a0, 1) self.mips.sbrk() self.mips.move(reg.s3, reg.v0) @@ -665,6 +667,7 @@ def copy_substr(self, src, dst, length): @visitor.when(SubstringNode) def visit(self, node): + self.load_memory(reg.s0, node.msg1) self.load_memory(reg.s1, node.length) self.load_memory(reg.s3, node.start) @@ -672,6 +675,7 @@ def visit(self, node): self.mips.add(reg.s0, reg.s0, reg.s3) self.mips.move(reg.a0, reg.s1) + self.mips.addi(reg.a0, reg.a0, 1) self.mips.sbrk() self.copy_substr(reg.s0, reg.v0, reg.s1) @@ -706,9 +710,6 @@ def visit(self, node): # change /n to /0 self.mips.sb(reg.zero, self.mips.offset(reg.a0)) - - - @visitor.when(PrintStrNode) def visit(self, node: PrintStrNode): self.mips.comment(f"Print str {node.str_addr}") From d7c8fd26846bf8b0e32e090bf39987e7b90ab833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 17 Dec 2020 16:19:29 -0500 Subject: [PATCH 165/191] Implement conforms node --- src/engine/codegen/to_mips.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 9e45d0cb..f810e305 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -737,3 +737,24 @@ def visit(self, node: ReturnNode): @visitor.when(VoidNode) def visit(self, node: VoidNode): self.store_memory(reg.zero, node.dest) + + @visitor.when(ConformsNode) + def visit(self, node: ConformsNode): + self.mips.comment(f"Conforms Node {node.dest} = {node.type} {node.expr}") + _id = self.global_descriptor.Types[node.type].id + self.load_memory(reg.s0, node.expr) + self.mips.empty_line() + + self.mips.li(reg.s2, _id) + self.mips.subu(reg.s3, reg.s2, reg.s1) + one = self.get_label() + end = self.get_label() + self.mips.beq(reg.s3, reg.zero, one) + self.store_memory(reg.zero, node.dest) + self.mips.j(end) + self.mips.label(one) + self.mips.li(reg.s3, 1) + self.store_memory(reg.s3, node.dest) + self.mips.label(end) + + From 8a9fff741fa4fcb5d74c0a2107bb470d7e70babd Mon Sep 17 00:00:00 2001 From: thenai310 Date: Thu, 17 Dec 2020 16:44:00 -0500 Subject: [PATCH 166/191] assignNode changed --- src/engine/codegen/to_cil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 2d006fe6..fcde0b4b 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -198,7 +198,7 @@ def visit(self, node: cool.AssignNode, scope: Scope): else: var_info = var_info.real_name self.register_instruction(AssignNode(var_info, expr)) - return 0 + return expr @visitor.when(cool.NewNode) def visit(self, node: cool.NewNode, scope): From 9f01d09e83847390c9c505211cafdfcf1d4b2aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Thu, 17 Dec 2020 19:51:13 -0500 Subject: [PATCH 167/191] Fix read string error --- src/engine/codegen/to_mips.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 99a82c0f..02d88792 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -695,6 +695,7 @@ def visit(self, node): start = self.get_label() end = self.get_label() + second_end = self.get_label() self.mips.label(start) # load byte by byte @@ -707,8 +708,12 @@ def visit(self, node): self.mips.label(end) # go back 1 position self.mips.addi(reg.a0, reg.a0, -1) + self.mips.lb(reg.s3, self.mips.offset(reg.a0)) + self.mips.li(reg.s4, 10) + self.mips.bne(reg.s3, reg.s4, second_end) # change /n to /0 self.mips.sb(reg.zero, self.mips.offset(reg.a0)) + self.mips.label(second_end) @visitor.when(PrintStrNode) def visit(self, node: PrintStrNode): From 775b1c5867a5da861b0c1793cb16f43f44c47cd1 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 21:11:35 -0500 Subject: [PATCH 168/191] case extend for every specific type --- src/engine/codegen/cil.py | 9 +++-- src/engine/codegen/to_cil.py | 65 ++++++++++++++++++++++++++++++--- src/engine/parser/ast_parser.py | 2 +- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/engine/codegen/cil.py b/src/engine/codegen/cil.py index 8d595cc8..e8c18d8c 100644 --- a/src/engine/codegen/cil.py +++ b/src/engine/codegen/cil.py @@ -77,10 +77,11 @@ def register_data(self, value): return data_node def sort_case_list(self, case_expressions): - return sorted(case_expressions, reverse=True, - key=lambda x: self.context.inheritance_deep(x.type.lex)) - - ################################### + return sorted( + case_expressions, reverse=True, + key=lambda x: self.context.inheritance_deep(x.type.lex) + ) + ################################### def define_int_type(self): self.current_type = self.context.get_type('Int') diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 96ed779a..46970b5e 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -22,6 +22,56 @@ def define_unary_node(self, node: cool.UnaryNode, scope, cil_node: Node): self.register_instruction(cil_node(result, expr)) return result + def get_children_types_inheritance(self, type_names: List[str]): + for_visit = set(type_names) + types = set(type_names) + while len(for_visit): + for_visit_child = set() + for typex in for_visit: + children = [] + for child, parent in self.context.inheritance.items(): + if parent == typex: + children.append(child) + for_visit_child.add(child) + types.add(child) + + for_visit = for_visit_child + + print(type_names) + print(types) + + return types + + def extend_case_list(self, case_expressions: List[cool.CaseActionExpression]): + cases_by_type = { + case.type.lex: case + for case in case_expressions + } + types = self.get_children_types_inheritance( + type_names=list(cases_by_type.keys()) + ) + types = sorted( + types, + key=lambda t: self.context.inheritance_deep(t), + reverse=True + ) + ordered_cases = [] + for typex in [self.context.get_type(t) for t in types]: + temp = typex + while True: + if temp.name in cases_by_type: + case = cases_by_type[temp.name] + new_case = cool.CaseActionExpression( + case.id, + typex.name, + case.expression, + ) + ordered_cases.append(new_case) + break + temp = self.context.get_type( + self.context.inheritance[typex.name]) # get_parent + return ordered_cases + def sort_class_declar(self, program: cool.ProgramNode): self.context: Context program.declarations = sorted( @@ -267,16 +317,20 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): # TODO: Label error logic if is void self.register_instruction(TypeOfNode(expr, exp_type)) - case_expressions = self.sort_case_list(node.branches) + case_expressions = self.extend_case_list(node.branches) + print(case_expressions) for i, case in enumerate(case_expressions): - next_branch_label = LabelNode(f'CASE_{case.id.lex}_{i}') + next_branch_label = LabelNode( + f'CASE_{case.id.lex}_{i}_{label_counter}' + ) child_scope = scope.create_child() expr_i = self.visit( case, child_scope, expr=expr, expr_type=exp_type, next_label=next_branch_label, + label_id=label_counter ) self.register_instruction(AssignNode(result, expr_i)) self.register_instruction(GotoNode(end_label.label)) @@ -290,12 +344,13 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): return result @visitor.when(cool.CaseActionExpression) - def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_type=None, next_label=None): + def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_type=None, next_label=None, label_id=0): test_res = self.define_internal_local() - matching_label = LabelNode(f'CASE_MATCH_{node.id.lex}_{node.type.lex}') + matching_label = LabelNode( + f'CASE_MATCH_{node.id.lex}_{node.type.lex}_{label_id}') self.register_instruction(ConformsNode(test_res, expr, node.type.lex)) - self.register_instruction(IfGotoNode(expr, matching_label.label)) + self.register_instruction(IfGotoNode(test_res, matching_label.label)) self.register_instruction( GotoNode(next_label.label) ) diff --git a/src/engine/parser/ast_parser.py b/src/engine/parser/ast_parser.py index e4d7cdbd..8c10a6eb 100644 --- a/src/engine/parser/ast_parser.py +++ b/src/engine/parser/ast_parser.py @@ -38,7 +38,7 @@ def __iter__(self): class CaseActionExpression(DeclarationNode): def __init__(self, idx, typex, expression=Node): self.id = idx - self.type = typex + self.type = Token(typex, 'ID') if isinstance(typex, str) else typex self.expression = expression self.line = self.id.line self.column = self.id.column From e9b1ec620d0c528acd384da4d8bdcc22232bdf0b Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 21:29:04 -0500 Subject: [PATCH 169/191] remove prints --- src/engine/codegen/to_cil.py | 17 ++++++++--------- src/main.py | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 46970b5e..b279113d 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -37,8 +37,8 @@ def get_children_types_inheritance(self, type_names: List[str]): for_visit = for_visit_child - print(type_names) - print(types) + # print(type_names) + # print(types) return types @@ -311,14 +311,12 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): label_counter = self.label_counter_gen() expr = self.visit(node.expression, scope) result = self.define_internal_local() - exp_type = self.define_internal_local() end_label = LabelNode(f'END_{label_counter}') error_label = LabelNode(f'ERROR_CASE_{label_counter}') # TODO: Label error logic if is void - self.register_instruction(TypeOfNode(expr, exp_type)) case_expressions = self.extend_case_list(node.branches) - print(case_expressions) + # print(case_expressions) for i, case in enumerate(case_expressions): next_branch_label = LabelNode( @@ -328,7 +326,6 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): expr_i = self.visit( case, child_scope, expr=expr, - expr_type=exp_type, next_label=next_branch_label, label_id=label_counter ) @@ -344,13 +341,15 @@ def visit(self, node: cool.CaseOfNode, scope: Scope): return result @visitor.when(cool.CaseActionExpression) - def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, expr_type=None, next_label=None, label_id=0): + def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, next_label=None, label_id=0): test_res = self.define_internal_local() matching_label = LabelNode( f'CASE_MATCH_{node.id.lex}_{node.type.lex}_{label_id}') - self.register_instruction(ConformsNode(test_res, expr, node.type.lex)) - self.register_instruction(IfGotoNode(test_res, matching_label.label)) + self.register_instruction( + ConformsNode(test_res, expr, node.type.lex)) + self.register_instruction( + IfGotoNode(test_res, matching_label.label)) self.register_instruction( GotoNode(next_label.label) ) diff --git a/src/main.py b/src/main.py index 920b23b2..a54affca 100644 --- a/src/main.py +++ b/src/main.py @@ -111,6 +111,5 @@ def codegen(ast, context, output_cil=False): if __name__ == "__main__": args = sys.argv if not len(args) in (3, 4): - print('') exit(1) compile_code(*args[1:]) From c212569b6d6f03377a220c75edad45d246173f8c Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Thu, 17 Dec 2020 21:45:13 -0500 Subject: [PATCH 170/191] fix errors in arguments reverted --- src/engine/codegen/to_cil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 6054f953..ac92541d 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -425,10 +425,11 @@ def visit(self, node: cool.FunctionCallNode, scope): def visit(self, node: cool.MemberCallNode, scope: Scope): type_name = self.current_type.name result = self.define_internal_local() + rev_args = [] for arg in node.args: # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = [arg_value] + rev_args + rev_args = rev_args + [arg_value] for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name From 90b94234761f722f13f1879aaf181bfbad6673d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 02:57:14 -0500 Subject: [PATCH 171/191] fix while return --- src/engine/codegen/to_cil.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index ac92541d..0c20eab7 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -304,7 +304,9 @@ def visit(self, node: cool.WhileLoopNode, scope): self.register_instruction(GotoNode(start_label.label)) self.register_instruction(end_label) - return 0 + result = self.define_internal_local() + self.register_instruction(VoidNode(result)) + return zero @visitor.when(cool.CaseOfNode) def visit(self, node: cool.CaseOfNode, scope: Scope): From 6bc7873888fbd885206a290a0581bbfa6c518523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 02:59:57 -0500 Subject: [PATCH 172/191] fix typo --- src/engine/codegen/to_cil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 0c20eab7..2cf21bf6 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -306,7 +306,7 @@ def visit(self, node: cool.WhileLoopNode, scope): result = self.define_internal_local() self.register_instruction(VoidNode(result)) - return zero + return result @visitor.when(cool.CaseOfNode) def visit(self, node: cool.CaseOfNode, scope: Scope): From 3122e8d16427ee38410ad98bd4f30d3419cec854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 11:21:23 -0500 Subject: [PATCH 173/191] Fix conforms node --- src/engine/codegen/to_mips.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 02d88792..395bab79 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -432,8 +432,6 @@ def visit(self, node: DynamicCallNode): offset = type_descritptor.get_method_index( node.method) * self.data_size - # print("offset", offset, node.method, node.type, type_descritptor.methods) - # print(node.obj, node.type) self.load_memory(reg.s0, node.obj) # vtable ptr in position 4 (0 .. 3) @@ -749,13 +747,15 @@ def visit(self, node: ConformsNode): self.mips.comment(f"Conforms Node {node.dest} = {node.type} {node.expr}") _id = self.global_descriptor.Types[node.type].id self.load_memory(reg.s0, node.expr) + self.mips.load_memory(reg.s1, self.mips.offset(reg.s0)) self.mips.empty_line() self.mips.li(reg.s2, _id) - self.mips.subu(reg.s3, reg.s2, reg.s1) + one = self.get_label() end = self.get_label() - self.mips.beq(reg.s3, reg.zero, one) + + self.mips.beq(reg.s1, reg.s2, one) self.store_memory(reg.zero, node.dest) self.mips.j(end) self.mips.label(one) From 9e847afde1a3f4ff544a8220dee1753f2d021afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 11:22:09 -0500 Subject: [PATCH 174/191] Fix case action expression node --- src/engine/codegen/to_cil.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 2cf21bf6..b15d5483 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -356,10 +356,10 @@ def visit(self, node: cool.CaseActionExpression, scope: Scope, expr=None, next_l GotoNode(next_label.label) ) self.register_instruction(matching_label) - l_var = self.define_internal_local() typex = self.context.get_type(node.type.lex) - scope.define_variable(l_var, typex) - self.register_instruction(AssignNode(l_var, expr)) + var_info = scope.define_variable(node.id.lex, typex) + var_info.real_name = self.register_local(var_info) + self.register_instruction(AssignNode(var_info.real_name, expr)) case_action_expr = self.visit(node.expression, scope) return case_action_expr From 34db285d5b80270f1c25247e5a9674c7bd6e50e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 12:03:39 -0500 Subject: [PATCH 175/191] Fix reversed member args --- src/engine/codegen/to_cil.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index b15d5483..1f875778 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -429,9 +429,8 @@ def visit(self, node: cool.MemberCallNode, scope: Scope): result = self.define_internal_local() rev_args = [] for arg in node.args: - # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = rev_args + [arg_value] + rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name From 374e9cc78c83612a36187a026a94ea8009e67156 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 18 Dec 2020 12:22:45 -0500 Subject: [PATCH 176/191] initialize variables in empty let declarations --- src/engine/codegen/to_cil.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index b15d5483..2f3e45ed 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -377,9 +377,15 @@ def visit(self, node: cool.LetInNode, scope: Scope): def visit(self, node: cool.LetVariableDeclaration, scope: Scope): var_info = scope.define_variable(node.id.lex, node.type) var_info.real_name = self.register_local(var_info) - value = self.visit(node.expression, scope) + if node.expression: + value = self.visit(node.expression, scope) + self.register_instruction(AssignNode(var_info.real_name, value)) + else: + node = cool.NewNode(node.type) + new_instance = self.visit(node) + self.register_instruction(AssignNode( + var_info.real_name, new_instance)) - self.register_instruction(AssignNode(var_info.real_name, value)) return var_info.real_name @visitor.when(cool.FunctionCallNode) From b57daf25f66e6ee9e714caa8faca55e6a09e8c18 Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 18 Dec 2020 12:30:47 -0500 Subject: [PATCH 177/191] visiting done properly --- src/engine/codegen/to_cil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 4d90e02b..879a022c 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -382,7 +382,7 @@ def visit(self, node: cool.LetVariableDeclaration, scope: Scope): self.register_instruction(AssignNode(var_info.real_name, value)) else: node = cool.NewNode(node.type) - new_instance = self.visit(node) + new_instance = self.visit(node, scope) self.register_instruction(AssignNode( var_info.real_name, new_instance)) From 677c287f92bbd8cb6ca32f7edcf37cde4617022d Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 18 Dec 2020 13:48:21 -0500 Subject: [PATCH 178/191] empty let declaration fixed --- src/engine/codegen/to_cil.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 879a022c..1041624c 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -381,12 +381,13 @@ def visit(self, node: cool.LetVariableDeclaration, scope: Scope): value = self.visit(node.expression, scope) self.register_instruction(AssignNode(var_info.real_name, value)) else: - node = cool.NewNode(node.type) - new_instance = self.visit(node, scope) - self.register_instruction(AssignNode( - var_info.real_name, new_instance)) - - return var_info.real_name + typex = node.type.lex + if typex == 'String': + result = self.register_data("").name + self.register_instruction( + AssignNode(var_info.real_name, result)) + else: + self.register_instruction(VoidNode(var_info.real_name)) @visitor.when(cool.FunctionCallNode) def visit(self, node: cool.FunctionCallNode, scope): @@ -435,8 +436,9 @@ def visit(self, node: cool.MemberCallNode, scope: Scope): result = self.define_internal_local() rev_args = [] for arg in node.args: + # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = [arg_value] + rev_args + rev_args = rev_args + [arg_value] for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name From f32b88818f6b6d6964801a90cd8ae673d3a16bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 13:58:19 -0500 Subject: [PATCH 179/191] Revert member call argument order --- src/engine/codegen/to_cil.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 1041624c..2ca6c07f 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -415,6 +415,7 @@ def visit(self, node: cool.FunctionCallNode, scope): rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) + rev_args = rev_args + [arg_value] rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) From 1e391a8dd2270a0243071c1912b6a00a8a6e5cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Marti=20Cede=C3=B1o?= Date: Fri, 18 Dec 2020 14:01:15 -0500 Subject: [PATCH 180/191] Fix member call and function call argument error --- src/engine/codegen/to_cil.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 2ca6c07f..11d4b938 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -415,7 +415,7 @@ def visit(self, node: cool.FunctionCallNode, scope): rev_args = [] for arg in node.args: arg_value = self.visit(arg, scope) - rev_args = rev_args + [arg_value] + # rev_args = rev_args + [arg_value] rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) @@ -439,7 +439,8 @@ def visit(self, node: cool.MemberCallNode, scope: Scope): for arg in node.args: # FIXME: revert Args ???? arg_value = self.visit(arg, scope) - rev_args = rev_args + [arg_value] + # rev_args = rev_args + [arg_value] + rev_args = [arg_value] + rev_args for arg_value in rev_args: self.register_instruction(ArgNode(arg_value)) self_inst = scope.find_variable('self').name From 7b8024537838439b2c53150463fdbf5946eac04f Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Fri, 18 Dec 2020 14:14:50 -0500 Subject: [PATCH 181/191] fix extend case lists --- src/engine/codegen/to_cil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/codegen/to_cil.py b/src/engine/codegen/to_cil.py index 879a022c..7921617e 100644 --- a/src/engine/codegen/to_cil.py +++ b/src/engine/codegen/to_cil.py @@ -69,7 +69,7 @@ def extend_case_list(self, case_expressions: List[cool.CaseActionExpression]): ordered_cases.append(new_case) break temp = self.context.get_type( - self.context.inheritance[typex.name]) # get_parent + self.context.inheritance[temp.name]) # get_parent return ordered_cases def sort_class_declar(self, program: cool.ProgramNode): From cc2d740f365d3ed94240bab33d931b4d8b53919e Mon Sep 17 00:00:00 2001 From: thenai310 Date: Fri, 18 Dec 2020 15:27:21 -0500 Subject: [PATCH 182/191] fixing the complement Node --- src/engine/codegen/to_mips.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine/codegen/to_mips.py b/src/engine/codegen/to_mips.py index 395bab79..837db300 100644 --- a/src/engine/codegen/to_mips.py +++ b/src/engine/codegen/to_mips.py @@ -249,9 +249,11 @@ def visit(self, node: AssignNode): @visitor.when(ComplementNode) def visit(self, node: ComplementNode): - self.load_memory(reg.t0, node.expression) - self.mips.nor(reg.t1, reg.t0, reg.t0) - self.store_memory(reg.t1, node.dest) + self.load_memory(reg.s0, node.expression) + self.mips.li(reg.s1, -1) + self.mips.mult(reg.s0, reg.s1) + self.mips.mflo(reg.s0) + self.store_memory(reg.s0, node.dest) @visitor.when(PlusNode) def visit(self, node: PlusNode): @@ -744,14 +746,15 @@ def visit(self, node: VoidNode): @visitor.when(ConformsNode) def visit(self, node: ConformsNode): - self.mips.comment(f"Conforms Node {node.dest} = {node.type} {node.expr}") + self.mips.comment( + f"Conforms Node {node.dest} = {node.type} {node.expr}") _id = self.global_descriptor.Types[node.type].id self.load_memory(reg.s0, node.expr) self.mips.load_memory(reg.s1, self.mips.offset(reg.s0)) self.mips.empty_line() - + self.mips.li(reg.s2, _id) - + one = self.get_label() end = self.get_label() @@ -762,5 +765,3 @@ def visit(self, node: ConformsNode): self.mips.li(reg.s3, 1) self.store_memory(reg.s3, node.dest) self.mips.label(end) - - From deaa0802e64eb65aefebfa83d8976b67a39a7599 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Fri, 18 Dec 2020 16:52:03 -0500 Subject: [PATCH 183/191] danis changes --- Informe/informe.tex | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Informe/informe.tex b/Informe/informe.tex index ea08d916..1efc9946 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -52,7 +52,7 @@ % Autores %----------------------------------------------------------------------------------- \author{\\ - \name Jorge Daniel Valle Días \email \href{mailto:jorge.valle@estudiantes.matcom.uh.cu}{jorge.valle@estudiantes.matcom.uh.cu} + \name Jorge Daniel Valle Díaz \email \href{mailto:jorge.valle@estudiantes.matcom.uh.cu}{jorge.valle@estudiantes.matcom.uh.cu} \\ \addr Grupo C412 \AND \name Leonel Alejandro Garc\'ia L\'opez \email \href{mailto:l.garcia3@estudiantes.matcom.uh.cu}{l.garcia3@estudiantes.matcom.uh.cu} \\ \addr Grupo C412 \AND @@ -69,7 +69,7 @@ %----------------------------------------------------------------------------------- % Headings %----------------------------------------------------------------------------------- -\jcematcomheading{\the\year}{1-\pageref{end}}{Jorge Daniel Valle Días, Leonel Alejandro Garc\'ia L\'opez, Roberto Marti Cede\~no} +\jcematcomheading{\the\year}{1-\pageref{end}}{Jorge Daniel Valle Díaz, Leonel Alejandro Garc\'ia L\'opez, Roberto Marti Cede\~no} %----------------------------------------------------------------------------------- \ShortHeadings{Ejemplo JCE}{Autores} @@ -166,9 +166,30 @@ \section{Código intermedio y código de máquina} \subsection{Código intermedio} - Cuarto recorrido del ast, en el cual se conforma la representación del árbol de código intermedio de cool. En el mismo nos dimos a la tarea de simplificar la complejidad de cool para llevarlo a mips sin mucha dificultad. Entre las transformaciones no evidente las siguientes: + Del AST obtenido en las fases anteriores, en un cuarto recorrido se realizó una transformación hacia un AST de CIL que facilitara que el comportamiento obtenido en COOL sea mas factible a un representacion en MIPS. + Aqui existio una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los metodos necesarios para dicha conversion. + En esta fase surgió la necesidad de resolver un conjunto de escpecificaciones como son: + + Es también en esta fase donde se da por fin una implementación real a los tipos y + funciones básicas definidas por el lenguaje. Estas hacen uso de nodos especiales + del AST que solo son instanciadas para su uso desde COOL a través de las funciones + básicas. Ejemplo son los métodos para la entrada y salida de datos brindada por la + clase IO . Con estas estructuras definidas en el AST de CIL , durante la traducción a + MIPS , ellas serán generadas automáticamente. \begin{itemize} \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en mips) + \item \textbf{De los tipos por valor} El problema de los tipos por valor Int y Bool, y de los Strings como casos especiales, al ser usados como un objeto por referencia. Para esto se definió una representación en memorias para los casos en + que esto ocurriera. Todos estos tipos cuando fuera necesario tratarlos como objetos + por referencias, para por ejemplo acceder a las funciones heredadas de la clase + Object o las propiamente definidas por el tipo String , serían encapsulados en + instancias similares a los otros tipos, la cual contaría con un atributo value en el cual + se almacenaría el valor real de los mismos. + \item \textbf{Inicializaci\'on de atributos} Una de las especificaciones que se tuvo en cuenta para la generación de CIL fue la inicialización + de los atributos, tanto los heredados como los propios de la clase. Cuando se crea una instancia + de una clase se deben inicializar todos sus atributos con su expresión inicial, si tienen alguna; + en otro caso se usa su expresión por defecto. Con el objetivo de lograr esto se creó para cada + tipo un constructor, cuyo cuerpo consiste en un bloque, dándole un valor a cada uno de sus + atributos. Este es llamado cada vez que se instancia un tipo. \item \textbf{Para las estructuras \textit{CaseOf}} de cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el mas cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. \end{itemize} From f8df1ca7c3180469108ad525939f6d9bd877d494 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Sat, 19 Dec 2020 06:52:16 -0500 Subject: [PATCH 184/191] case actions ordering explanation --- Informe/informe.pdf | Bin 148011 -> 149028 bytes Informe/informe.tex | 1 + 2 files changed, 1 insertion(+) diff --git a/Informe/informe.pdf b/Informe/informe.pdf index cd2ad3b8d3528910a2b484b94311e8036bbada41..8ac454134b4670cc8f7baf0c705676d347d7e2d9 100644 GIT binary patch delta 40095 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 S09Z^|Pz;-eMftS~_J06r0m$tD delta 39055 zcmV(wK;85Vu+qoEfU<4;9Id%B}^4Q!ORB z`oGOMLuNvDWSdaVp?8xRy_?Efk#&E@-5*S{-rKnKJpZ5JD8l45|98&HnPQZh#35F?CRFsQSaNI;Ut&IwJBXUKm(I&re* z3;^^>o?|p>lpxjxYo-|&CNo5yjK0-W059|CKR>*6S}sFLP5F_v`^b9aoNj3=bgs2MV?qGTjz!j8CLwDo zk9eb5?X#bruG|AjS^ZXGY8!t*`W2?U`k#@NdFwX{g8~ve({}W1|}8QPnLKhp>N=){tK($t~i7 zHuwH1=9)PrR71v6VU@D&h9AOUH*13SS7DT9YV0Iu-t+pzjEJuVD- zV&@QipYE3w*ligvWNHRzP*k?X&NiAHuWxw384d>vl#9oHnqPj&C#h9epRw56JaS|I z)nwU_4CTV;dT%K7j7fj;De7?0;ml&<1De~-WNpbOPi}Jg{;>0l6MY)i5_=4a6NsAz zg?n*!Thrx=t0~Jo^{9{Dh8dpL^iNo~z>}P<@&Cv!NLu2ra&UF&2SXZt`t!?Idi7I1 z`6l)0FD(>p8~9tLg3py@3e;y1ce|T^0P^JgunJ{vWOHWztvEXD627un1f7#k{}0H1{OwUUVxZ_ zs5T2TfSH+%k(rqlo`OQ%+SLyDUpYL5CeYc%8sxzHFAFhepo#0dOx(ovf89_4fFG09lX&&;_1C4CLtLY;9@f`kv>% zj{s^j8UPCq4;THP?f?;cptH4^i332v#MKID|DMsz#15baGP4G{di_rbYJMwMS4UnZ zCJzq}MiYA%Mv$|mAPqghf5Y0<3ZM#f0Xn+_%>jS33{W(&2maL>BRmB_-OAeKKMFOF zg{y~&GZ64Du(LJ;I=H;MxH*^uodNIJ0ctYx03}DD!+(tB|6@Q8_-i--7Dkr8!~Ny` zM<8p5Kb=j?%s}>zCJtWK4we85Ydau7Nm8EC)zg(8VB%o@hoOm`e+%f{-^AU-+RnuE z-QdsCO#qT2DgcxB4*%-U#mw2-(ba{~#oF$V9-00K^FC$?2Xiryy*<#u)dl{K`oyiB zfoAV>_hS0%aBUqx9u7YLMHbc$<`#dnVeaP0q~T!gwb1T%Fy3 zem?(J{4auMVF8$1o4Eo^ftJ<|@c%@A7XvN+gWu2J+1eAJ$NWw|769`fpTD0B-Wg^N zaW-@m7<~`Pk;{t2Pc4mm4g|;f5O7a4&Zu!@cZ95$|lx- z)$uQ183zjxfagEuzR&5uCA-!ccfZlh(;s2Uy0sphQ zq98l-|ErU6e>HjE1rY~JyT8Y1?ILOI2{c!>b~Us54_*Ev*Z5=6?5rJt${-i(Kdu%4 z0}C_r|Ixi~mznMR_2Kf)$v;)V_vQKDloAeRAoD-AjP?D5O`M%gyx`vt`5kcpd|2Ms z(H!XcCyN10j1C~zcNf5WbAA8|kTd)rC(6kIU=sO5fAk;31z-~U2XViX>Tkrw0$`H* z2eAW~WdA{&04Di=(0dexzY#YxfJylu#0p?i{Rh4KY5t9P-u+DeMl3w<$n5QfzWqP&ePfyaRr~uL!36pnvcKED zzeWC~elOJVAN6}8$M;nN{j1yeR}+)dzu3z6Wsq*A)JM)^_IqBz$Kd zldA{lUmovA<@PU+_jdoR+k=Ja$H>;LdaY6@fk`V(Zdv3>?NPl zuhAOxYT_lRuT2J-@@y$gW`gx0jmlezXO3Bk;u5c1q>cGp?C(5lKg`YHPvP&GvYX?sGS^C!(XUR$TXSev=V zZFtu=9e25v0^)B#eK**2`ClqdvHY3|G9rtic*l=CCY>-w>r|A-lHx5qQe>JP#gD@7 zwvnT*t&9=`zTOqxx&_vmd^w7Bh)QzAOx#bnq`zQiP|Ku6esFay3JH={

GR8CY&!x1uB5-9S7DeBMpWHUz`h@g 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�WvAl8S^&4LR+;!Mf^x_ z{1)odRyQkxi!7D6ID|Irg?evNry5tVI#bNCb$j&kEJdpKvC9`v59~JW>D5vyT9OP) z=c3J;zsal1FJz0I3N$rz!^9r`7J+y;lXuU$SHb2UEn4%Y;XgNEqj<9P*X~XFwI09A z!Sv2!C;YaLxWobGXc{$(i2E$$fzaWXAT&K{zpq2SHk)3kSGZsGyTixgEKJh%g#8ur zG-{ew?(Z+zbEaZzu!KD}$1NhU3attr`Wt>3N~&U_H}3UMM4L$owA1Hr4I66Ec-Vc( zb*)j{Me8k2nwF;(Gh58DcuH)8=n+=|_B zfq}Q04FH0{H*K5z*AzDo+>#3b0uTu3Eh+#E0ETAXv%FDpyOcl(7;r}g5DdEG7z6+V zGClrDafcBMf!-Aj0^P0!@MhGJnO*;+xGfL}hC=S9g(L2yfB+DHOiHVp6t}Jm00@D? zZyC9X!EU$xpBNmLY4uNvJB&~;?ADarbO{2wWA3J@h|Id16sS8!VDQ`J1OVYcdrYN1o=Ns&Hs1D06;fNZ~Fnm5a8RyU^ozdyL3`iX2B4!J5&e&2y$Bz;)d+DbR-f1`JYk!zaD`Az?}jC zf#5sDH!=9lpAP@I6+kd3@Rn~N2!;TFGgGW@Jl=-DH#_83FK+JZ%_h8+_U6JOZfU<+ z_y2Nzz!2oEKHi+WsnCDtBm3Vz-UJa~cqY&Wi(25eCMXyQyQAsmLLf3-Y_R0+LzTc_ zIYlT0d0zo2r=TDYR#1{tke5>g0ObJ+3P`v#hvfh7NalANELs8x5f6`|mJ-o_0et?T Az5oCK From 7b132d4fddb9abcb00de1cec1dbd53ca3befcd66 Mon Sep 17 00:00:00 2001 From: lagcleaner Date: Mon, 21 Dec 2020 04:04:54 -0500 Subject: [PATCH 191/191] grammar details --- Informe/informe.pdf | Bin 156942 -> 178847 bytes Informe/informe.tex | 59 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Informe/informe.pdf b/Informe/informe.pdf index e31522d1781456498c8f55a85a10811afa185369..7c47606e230f95a00c63ecc397e60dc6e357b0e1 100644 GIT binary patch delta 88934 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 z%0A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

IOyPl?u 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 XZ3<} diff --git a/Informe/informe.tex b/Informe/informe.tex index ea08d916..e95fabb0 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -170,6 +170,7 @@ \subsection{Código intermedio} \begin{itemize} \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en mips) \item \textbf{Para las estructuras \textit{CaseOf}} de cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el mas cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. + Luego esta lista que llamamos \textbf{CaseActionExpressions} se extende de manera ordenada para a\~nadir los tipos mas espec\'ificos de los que se encontraban originalmente que a su vez como expresi\'on a realizar ser\'ia la mismo que el ancestro del que extendio, quedando una lista con bloques de case donde antes solo una opci\'on (conservando el orden anterior pero solo por bloques), de forma tal que en tiempo de ejecuci\'on el primer \textit{matching} fuese el correcto a realizar. \end{itemize} From f408b66b0953876eaa359af5b0b7b5451dac4987 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 17:23:43 -0500 Subject: [PATCH 185/191] Add memory and vtable description --- Informe/informe.tex | 91 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/Informe/informe.tex b/Informe/informe.tex index cc308659..08b54629 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -146,9 +146,8 @@ \section{Lexer}\label{sec:dev} \section{Parser} La fase de análisis sintáctico ha sido una de las fases mas controversiales a la hora de la realización del proyecto. Se empleó en una primera fase el parser LR1 tomado de clase práctica y los proyectos previos de la asignatura. La gramática que se definió durante la primera entrega del proyecto contenía ambigüedades, las cuales fueron detectada comprobando las pruebas correspondientes a la parte de semántica. - Dado el tiempo restante que se disponía para la entrega, el equipo decidió tratar de adelantar todas las funcionalidades posibles para minimizar los cambios después de la fecha de entrega. + Finalmente el equipo desición emplear el módulo Yacc de ply para definir la gramáticay evitar las ambigüedades que se desprendían de la implementación inicial. - Actualmente se esta valorando la posibilidad de emplear el módulo yacc de ply para definir la gramática y evitar las ambigüedades que se desprenden de nuestra implementación inicial. \section{Análisis Semántico} @@ -157,7 +156,7 @@ \section{Análisis Semántico} \begin{description} \item [Recolector de tipos:] Primer recorrido del ast, en el cual se conforman los tipos nativos y los definidos en el archivo de código a procesar. En este mismo recorrido también se detectan los problemas relacionados con la herencia cíclica. \item [Constructor de tipos:] Segundo recorrido del ast, en el cual se construyen los tipos, se definen sus métodos y atributos. - \item [Verificador de tipos:] Tercer y ultimo recorrido del ast, en el cual se verifica la estructura de cada uno de los nodos del ast, este recorrido es el que mas abarca las reglas semánticas del lenguaje cool. + \item [Verificador de tipos:] Tercer y ultimo recorrido del ast, en el cual se verifica la estructura de cada uno de los nodos del ast, este recorrido es el que mas abarca las reglas semánticas del lenguaje Cool. \end{description} \section{Código intermedio y código de máquina} @@ -166,9 +165,8 @@ \section{Código intermedio y código de máquina} \subsection{Código intermedio} - Del AST obtenido en las fases anteriores, en un cuarto recorrido se realizó una transformación hacia un AST de CIL que facilitara que el comportamiento obtenido en COOL sea mas factible a un representacion en MIPS. - Aqui existio una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los metodos necesarios para dicha conversion. - En esta fase surgió la necesidad de resolver un conjunto de escpecificaciones como son: + Del AST obtenido en las fases anteriores, en un cuarto recorrido se realizó una transformación hacia un AST de CIL que facilitara que el comportamiento obtenido en COOL sea mas factible a un representación en MIPS. + Es también en esta fase donde se da por fin una implementación real a los tipos y funciones básicas definidas por el lenguaje. Estas hacen uso de nodos especiales @@ -176,8 +174,11 @@ \subsection{Código intermedio} básicas. Ejemplo son los métodos para la entrada y salida de datos brindada por la clase IO . Con estas estructuras definidas en el AST de CIL , durante la traducción a MIPS , ellas serán generadas automáticamente. + + Aquí existió una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los métodos necesarios para dicha conversión. + En esta fase surgió la necesidad de resolver un conjunto de especificaciones como son: \begin{itemize} - \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en mips) + \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) \item \textbf{De los tipos por valor} El problema de los tipos por valor Int y Bool, y de los Strings como casos especiales, al ser usados como un objeto por referencia. Para esto se definió una representación en memorias para los casos en que esto ocurriera. Todos estos tipos cuando fuera necesario tratarlos como objetos por referencias, para por ejemplo acceder a las funciones heredadas de la clase @@ -190,15 +191,83 @@ \subsection{Código intermedio} en otro caso se usa su expresión por defecto. Con el objetivo de lograr esto se creó para cada tipo un constructor, cuyo cuerpo consiste en un bloque, dándole un valor a cada uno de sus atributos. Este es llamado cada vez que se instancia un tipo. - \item \textbf{Para las estructuras \textit{CaseOf}} de cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el mas cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. - Luego esta lista que llamamos \textbf{CaseActionExpressions} se extende de manera ordenada para a\~nadir los tipos mas espec\'ificos de los que se encontraban originalmente que a su vez como expresi\'on a realizar ser\'ia la mismo que el ancestro del que extendio, quedando una lista con bloques de case donde antes solo una opci\'on (conservando el orden anterior pero solo por bloques), de forma tal que en tiempo de ejecuci\'on el primer \textit{matching} fuese el correcto a realizar. + \item \textbf{Para las estructuras \textit{CaseOf}} de Cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el mas cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. + Luego esta lista que llamamos \textbf{CaseActionExpressions} se extiende de manera ordenada para a\~nadir los tipos mas espec\'ificos de los que se encontraban originalmente que a su vez como expresi\'on a realizar ser\'ia la mismo que el ancestro del que extendió, quedando una lista con bloques de case donde antes solo una opci\'on (conservando el orden anterior pero solo por bloques), de forma tal que en tiempo de ejecuci\'on el primer \textit{matching} fuese el correcto a realizar. \end{itemize} + + \subsection{Código de máquina} + \'Ultimo recorrido, en este caso del árbol de sintaxis de representación intermedia. Mediante el cual se genera el código a ejecutar en el microprocesador con arquitectura MIPS. Es en este recorrido donde se crean los datos y la representación en memoria que sustentan el sitema de tipos de Cool. + + +\section{Representación y trabajo con la memoria} + +El equipo se desidió por una arquitectura en memoria que tiene por un lado la representación física del objeto con sus atributos y por otro una tabla de métodos virtuales global, la cual contiene todas las referencias a todas las implementaciones concretas de los métodos de las clases. + +\subsection{Representación en memoria} + +A continuación en la tabla \ref{fig:memory} presentamos en esquema seguido en memoria de una clase de Cool bajo la solución propuesta. + +El identificador de la clase se emplea además de su función básica para la comparación entre clases. El tamaño en memoria de la clase se emplea tanto para la copia como para el tamaño en bytes a reservar. La referencia al nombre de la clase representa la etiqueta correspondiente al nombre de la clase que representa la instancia en memoria y se emplea principalmente para los llamados al método typename. El desplazamiento representa la posición de la etiqueta correspondiente al primer método de la tabla virtual que corresponde a la clase que se tiene en cuestión. Finalizando, se encuentran, si existen, los atributos de la clase. + +\begin{table}[h] + \centering + \begin{tabular}{|c|} + \hline + Identificador de la clase \\ + \hline + Tamaño en memoria de la clase \\ + \hline + Referencia al nombre de la clase \\ + \hline + Desplazamiento en la tabla virtual \\ + \hline + Atributo 1 \\ + \hline + Atributo 2 \\ + \hline + ... \\ + \hline + Atributo n \\ + \hline + \end{tabular} + \caption{Distribución en memoria de una clase de Cool.} + \label{fig:memory} + +\end{table} + +\subsection{Tabla de métodos virtuales} + +Para dar solución al problema del ligamiento dinámico que resulta de la herencia se ideó la construcción de una tabla de métodos virtuales global. La tabla contiene todos los métodos correspondientes a todas las clases que se generan a partir de un programa en Cool. Una posible tabla virtual de un programa en Cool tendría una estructura como la siguiente: + +\newpage + +\begin{table}[h] + \centering + \begin{tabular}{|c|} + \hline + Método 1 de la clase 1 \\ + \hline + Método 2 de la clase 1 \\ + \hline + Método 1 de la clase 2 \\ + \hline + Método 1 de la clase 3 \\ + \hline + ... \\ + \hline + Método p de la clase n \\ + \hline + \end{tabular} + \caption{Distribución en memoria de la tabla de métodos virtuales.} + \label{fig:vtable} +\end{table} +La principal idea detrás de la tabla radica en la imposibilidad de tener toda la información de tipos en tiempo de compilación, el ligamiento de cada clase con su implementación de un método particular se deja para tiempo de ejecución. -\subsection{Código de máquina} - \'Ultimo recorrido, en este caso del árbol de sintaxis de representación intermedia. Mediante el cual se genera el código a ejecutar en el microprocesador con arquitectura MIPS. +Cada clase se construye siguiendo el mismo patrón, de forma tal de que en el recorrido de generación de código se conocen todos los métodos y todos los atributos de cada clase y lo más importante: Dadas dos clases A y B, si A desciende de B o B de A, los atributos y métodos de A y B comunes aparecen en el mismo orden tanto en la tabla como en su espacio en memoria de cada instancia. +Esta convención permitió que si una clase T tiene un tipo estático P en tiempo de compilación, pero realmente en ejecución tiene un tipo dinámico J, y J desciende de T, cualquier implementación de los métodos de T en J comparte el mismo orden en la tabla virtual. Por lo que conociendo el tipo estático y llamando al método correspondiente en la tabla virtual al tipo T, se esta llamando realmente al método de T que J sobrescribió. \label{end} From f654a6861b620326226d6098d590dab0ebdb6b0f Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 17:48:42 -0500 Subject: [PATCH 186/191] Fix typo --- Informe/informe.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Informe/informe.tex b/Informe/informe.tex index 08b54629..2f0092f8 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -161,7 +161,7 @@ \section{Análisis Semántico} \section{Código intermedio y código de máquina} -El equipo decidió realizar una representación intermedia del lenguaje cool antes de pasar a la generación de código de máquina. Para ello se definieron 2 nuevos recorridos a árboles de sintaxis. +El equipo decidió realizar una representación intermedia del lenguaje Cool antes de pasar a la generación de código de máquina. Para ello se definieron 2 nuevos recorridos a árboles de sintaxis. \subsection{Código intermedio} @@ -178,7 +178,7 @@ \subsection{Código intermedio} Aquí existió una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los métodos necesarios para dicha conversión. En esta fase surgió la necesidad de resolver un conjunto de especificaciones como son: \begin{itemize} - \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) + \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en Cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) \item \textbf{De los tipos por valor} El problema de los tipos por valor Int y Bool, y de los Strings como casos especiales, al ser usados como un objeto por referencia. Para esto se definió una representación en memorias para los casos en que esto ocurriera. Todos estos tipos cuando fuera necesario tratarlos como objetos por referencias, para por ejemplo acceder a las funciones heredadas de la clase From 11f09dfb022c1f493c4e4ac55a96d0afabea42e7 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 18:02:37 -0500 Subject: [PATCH 187/191] Improve report --- Informe/informe.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Informe/informe.tex b/Informe/informe.tex index 2f0092f8..12e6912a 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -161,7 +161,7 @@ \section{Análisis Semántico} \section{Código intermedio y código de máquina} -El equipo decidió realizar una representación intermedia del lenguaje Cool antes de pasar a la generación de código de máquina. Para ello se definieron 2 nuevos recorridos a árboles de sintaxis. +El equipo decidió realizar una representación intermedia del lenguaje Cool antes de pasar a la generación de código de máquina. Para ello se definieron 2 nuevos recorridos a árboles de sintaxis abstracta, uno para llevar de Cool a CIL y otro para llevar CIL a MIPS. \subsection{Código intermedio} @@ -178,7 +178,7 @@ \subsection{Código intermedio} Aquí existió una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los métodos necesarios para dicha conversión. En esta fase surgió la necesidad de resolver un conjunto de especificaciones como son: \begin{itemize} - \item \textbf{Relacionado a la herencia} mantenemos como tipos de cil como el conjunto de atributos de los respectivos en Cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) + \item \textbf{Relacionado a la herencia} Mantenemos como tipos de CIL como el conjunto de atributos de los respectivos en Cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) \item \textbf{De los tipos por valor} El problema de los tipos por valor Int y Bool, y de los Strings como casos especiales, al ser usados como un objeto por referencia. Para esto se definió una representación en memorias para los casos en que esto ocurriera. Todos estos tipos cuando fuera necesario tratarlos como objetos por referencias, para por ejemplo acceder a las funciones heredadas de la clase From 309a725d57a4ad63992d21f053d1092e89fca9d3 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 18:07:12 -0500 Subject: [PATCH 188/191] Fix grammatical errors --- Informe/informe.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Informe/informe.tex b/Informe/informe.tex index 12e6912a..c4d4c64a 100644 --- a/Informe/informe.tex +++ b/Informe/informe.tex @@ -165,7 +165,7 @@ \section{Código intermedio y código de máquina} \subsection{Código intermedio} - Del AST obtenido en las fases anteriores, en un cuarto recorrido se realizó una transformación hacia un AST de CIL que facilitara que el comportamiento obtenido en COOL sea mas factible a un representación en MIPS. + Del AST obtenido en las fases anteriores, en un cuarto recorrido se realizó una transformación hacia un AST de CIL que facilitara que el comportamiento obtenido en COOL sea más factible a un representación en MIPS. Es también en esta fase donde se da por fin una implementación real a los tipos y @@ -175,7 +175,7 @@ \subsection{Código intermedio} clase IO . Con estas estructuras definidas en el AST de CIL , durante la traducción a MIPS , ellas serán generadas automáticamente. - Aquí existió una vez mas apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los métodos necesarios para dicha conversión. + Aquí existió una vez más apoyo en los elementos de clase practica, al contar con un transpliador base para definir todas la convenciones tomadas, asi como contener los métodos necesarios para dicha conversión. En esta fase surgió la necesidad de resolver un conjunto de especificaciones como son: \begin{itemize} \item \textbf{Relacionado a la herencia} Mantenemos como tipos de CIL como el conjunto de atributos de los respectivos en Cool pero con los de sus antecesores en la jerarqu\'ia de tipos(los m\'etodos y la tabla virtual queda para resolverse en MIPS) @@ -191,8 +191,8 @@ \subsection{Código intermedio} en otro caso se usa su expresión por defecto. Con el objetivo de lograr esto se creó para cada tipo un constructor, cuyo cuerpo consiste en un bloque, dándole un valor a cada uno de sus atributos. Este es llamado cada vez que se instancia un tipo. - \item \textbf{Para las estructuras \textit{CaseOf}} de Cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el mas cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. - Luego esta lista que llamamos \textbf{CaseActionExpressions} se extiende de manera ordenada para a\~nadir los tipos mas espec\'ificos de los que se encontraban originalmente que a su vez como expresi\'on a realizar ser\'ia la mismo que el ancestro del que extendió, quedando una lista con bloques de case donde antes solo una opci\'on (conservando el orden anterior pero solo por bloques), de forma tal que en tiempo de ejecuci\'on el primer \textit{matching} fuese el correcto a realizar. + \item \textbf{Para las estructuras \textit{CaseOf}} de Cool realizamos un ordenamiento (dicho ordenamiento fue realizado de acuerdo a la profundidad de los tipos en la jerarqu\'ias, desde el m\'as espec\'ifico, hasta el más cercano a \textit{Object}) de los \textit{case actions} para realizar un \textit{matching} no iterativo y a partir del primer tipo presente en la jerarqu\'ia del objeto resultante de la expresi\'on del case. + Luego esta lista que llamamos \textbf{CaseActionExpressions} se extiende de manera ordenada para a\~nadir los tipos más espec\'ificos de los que se encontraban originalmente que a su vez como expresi\'on a realizar ser\'ia la mismo que el ancestro del que extendió, quedando una lista con bloques de case donde antes solo una opci\'on (conservando el orden anterior pero solo por bloques), de forma tal que en tiempo de ejecuci\'on el primer \textit{matching} fuese el correcto a realizar. \end{itemize} \subsection{Código de máquina} @@ -201,7 +201,7 @@ \subsection{Código intermedio} \section{Representación y trabajo con la memoria} -El equipo se desidió por una arquitectura en memoria que tiene por un lado la representación física del objeto con sus atributos y por otro una tabla de métodos virtuales global, la cual contiene todas las referencias a todas las implementaciones concretas de los métodos de las clases. +El equipo se decidió por una arquitectura en memoria que tiene por un lado la representación física del objeto con sus atributos y por otro una tabla de métodos virtuales global, la cual contiene todas las referencias a todas las implementaciones concretas de los métodos de las clases. \subsection{Representación en memoria} From 3fac400f0815f2afefd9413705898e9a27bbcec1 Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 18:29:24 -0500 Subject: [PATCH 189/191] Upload PDF --- Informe/informe.pdf | Bin 149028 -> 156946 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Informe/informe.pdf b/Informe/informe.pdf index 8ac454134b4670cc8f7baf0c705676d347d7e2d9..5cd20ac67fa6295bddaf76bc66cb51d9792c410d 100644 GIT binary patch delta 104863 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%0AU*6?ZfG55 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 From 95ae1fd00d53a4da254a57306f9383ea074d0a3f Mon Sep 17 00:00:00 2001 From: rmarticedeno Date: Sat, 19 Dec 2020 19:35:42 -0500 Subject: [PATCH 190/191] Strange pdf issue fix --- Informe/informe.pdf | Bin 156946 -> 156942 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Informe/informe.pdf b/Informe/informe.pdf index 5cd20ac67fa6295bddaf76bc66cb51d9792c410d..e31522d1781456498c8f55a85a10811afa185369 100644 GIT binary patch delta 9174 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 z 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 delta 9180 zcmaiZbySt@w=Lb>4bsi-pg}?!>5>qTE=j3PNOwphA&7*uk_t$7gMc)W5(_|oXZnSF2W{&6CmdG^A-1QZ*p6f zGZFR~ao2PFFvG8HAYrf{*GGZG4ZyIDpDm+OMEhRZ%JSxKMW$=Z*1q>fhFz=YwscwV ze?GcG3}RD7>);v`|Iug38h?6jPk+q9Mj_O(CNOPp*jWjVsL_1IEj-+#cHXpdh)Uyb zZd&gTdN}2Twu$nnV4hC!AxL^s@U_e6XTQ5YL8SwarIEO~aM0KJ$jyjS(MwX9*1g7g zl@P43(rW!Y=Lg(jD#ls;puN6x)&dz)^LOX)>Dg*Kk867~Tu%OWf(LXd>viyAe(_zc ziBz0((_X4FtDG^S`N)e%99<~yACwFZXC+!Lbc=&xG%a|KJdh239ysIMmp~e~wU}zo z+tqPloR0tKZ-Sj>s&@HQ!9v#p3u|?@R(uX_*-F1$^emU&+Vujwz+%Onw%;B7&1pxB z&XWt$ukD2VyZli&+~M1DO-kZ7jE?UYph~mxV#C2I-}|^%2I3Y1DXL*heW)2DY~V(! z2dsT-*5E2Bjen-sS;*}iY4ia4j!R>VC=wfiZJ8xizt1BMu-0A2B=waZLSiz!_E73n zz{L8vRo&q;s(cXndfWT-*>Y|#2nEFV-yex=lT9qmmAS{^F!>$k8FJm(2W{&+1i{_V=>7N%AhVcyhS&dHE-RbIEuM&a=sD)K&~wgMS4(}?G{NoS`u zMuw;*Q0n${84gOo_cN)LK^T|v*p@lY`ffRi{yYfJZ(_}tG8r8xMOiVaygOpelL)75 z`W3uM;@i|me(C5Uv=n2?~HBX&!`qs+s4+Hm&VR^vkw6PNz4%FV9H%HeGJ zi^`s$?u)BR&`_A+GD>o^adcuJYcALkCiW`qZGm0L!^#SL);R}4$4_w7QFW)%j=5Xg z=PvB75X>V#S;~p-OA;u*k|((`W+c_X&>X8r@>}NJ^y>au(O#S*7rXqH=5Hhg$B<{bj8a>IDsdF7Zrdwv}+F%TYXPjiz z6`m_IH0xw9`k=cm!uG>CjZa9fuldvbQ8MK+v2K|0KN6I`P`QV=P=tl|a1PS2;Ok6} zjT3AiTCi~t{*&D!SEu3vKR8rAdHzd9P5AH}RT z$M`7!Xc=+Y)lcL|>j^PS$9;}XLXY(}Jxh0gdMx4cHS{lrLCYH=$3Tc==|OjV8tRR#Y=#U)!Y)sH!hd^IaxLF?rnpE-?q ze`mf#5;}oY;!)Xg{41;F9wyroqEu4X>`T>t7jD<8JX)HSlyc{nJh8icB-5~R^VPEf zCa6W6f@}!+D5h%=6VD3jSAl{i3LkU-p+ZuNBAuTIiabb&*T%|#U+kB}+0~qWG%=C< zfwCxoOyb;j=%dvt-6WC*Ag53^`&8Az1+h#d$kD{h^K~ zF}#-;C8B%b{HtJlCBC!VXE=A@1qZ7h&K}XBi=>4E8(AGFs>~iW-bx#x%`67T54l&@ zIEP;)n^*c$`aY$t<>B&x;v8M>w%+xVba5v&rl@Qxm&s4?YMz#tV{7<)4hVcV)@|~V z!<0Bjr}pP!Cu5vLYe5c1{^p)$li913;{f1gdV|?$!}!Qo=$|Hvw~S)28H)0nhW^ij z9eX$loDx&anjxciRP*L2r>KB=wf$n1_Sfuc9 zkJOd)(vmMDe}`s7%sRYGb~B=TU;7J@=2brZE{083?;w3KF3u7ik* zO=&8p>SCNZH<#4b5_4G5Ia#9q9&LbK)GTpi)O7ZG!Zy!eluA^e1}l|sXUY2yiz8