def visit(self, node: cil.AbortNode): type_name_address = self.get_address('typename') self.add_inst( mips.CommentNode("<abort>"), # "Abort called from class " mips.LINode(v0, 4), mips.LANode(a0, "s2"), mips.SysCallNode(), ) self.visit(cil.TypeNameNode('typename', 'self')) self.add_inst( # Typename mips.LWNode(a0, (type_name_address, fp)), mips.LWNode(a0, (4, a0)), mips.LINode(v0, 4), mips.SysCallNode(), # \n mips.LINode(v0, 4), mips.LANode(a0, 's3'), mips.SysCallNode(), # Abort mips.LINode(v0, 10).with_comm("Finish program execution"), mips.SysCallNode(), mips.CommentNode("</abort>"))
def visit(self, node: cil.CaseMatchRuntimeErrorNode): self.add_inst( mips.CommentNode(f"<case-match-runtime-error>"), mips.LINode(v0, 4), mips.LANode(a0, 's4'), mips.SysCallNode(), mips.LINode(v0, 10), mips.SysCallNode(), mips.CommentNode(f"</case-match-runtime-error>"), )
def visit(self, node: cil.ReadStringNode): self.add_inst(mips.CommentNode(f"<readstring:{node.dest}>")) address = self.get_address(node.dest) self.add_inst(mips.LINode(a0, 512), mips.JALNode('malloc'), mips.MoveNode(t2, v0)) self.add_inst( mips.MoveNode(a0, t2), mips.LINode(a1, 512), mips.LINode(v0, 8), mips.SysCallNode(), ) self.visit(cil.StaticCallNode('String__init', node.dest)) self.add_inst(mips.LWNode(t0, (address, fp)), mips.SWNode(t2, 4, t0)) # Remove eol self.add_inst(mips.MoveNode(a0, t2), mips.JALNode('remove_eol')) self.add_inst(mips.CommentNode(f"</readstring:{node.dest}>"))
def visit(self, node: cil.GotoIfNode): condition = self.get_address(node.condition) self.add_inst( mips.CommentNode(f"<gotoif:{node.condition}-{node.label}>"), mips.LWNode(t0, (condition, fp)), mips.LWNode(t0, (4, t0)), mips.LINode(t1, 1), mips.BEQNode(t0, t1, node.label), mips.CommentNode(f"</gotoif:{node.condition}-{node.label}>"), )
def visit(self, node: cil.ReadIntNode): address = self.get_address(node.dest) self.add_inst(mips.CommentNode(f"<readint:{node.dest}>"), mips.LINode(v0, 5), mips.SysCallNode(), mips.MoveNode(t2, v0)) self.visit(cil.StaticCallNode("Int__init", node.dest)) self.add_inst(mips.LWNode(t1, (address, fp)), mips.SWNode(t2, 4, t1), mips.LWNode(v0, (address, fp)), mips.CommentNode(f"</readint:{node.dest}>"))
def visit(self, node: cil.PrintStringNode): address = self.get_address(node.addr) self.add_inst( mips.CommentNode(f"<printstring:{node.addr}>"), mips.LWNode(t0, (address, fp)), mips.ADDUNode(a0, t0, 4), mips.LINode(v0, 4), mips.LWNode(a0, (0, a0)), mips.SysCallNode(), mips.CommentNode(f"</printstring:{node.addr}>"), )
def visit(self, node: cil.ReturnNode): if node.value is not None: if isinstance(node.value, int): load_to_v0 = mips.LINode(v0, node.value) else: dest_offset = self.get_address(node.value) load_to_v0 = mips.LWNode(v0, (dest_offset, fp)) self.add_inst( mips.CommentNode(f"<return:{node.value}>"), load_to_v0, mips.CommentNode(f"</return:{node.value}>"), )
def visit(self, node: cil.AssignNode): dest = self.get_address(node.dest) if isinstance(node.source, int): load_inst = mips.LINode(t0, node.source) elif node.source == "void": load_inst = mips.LANode(t0, "void") else: src = self.get_address(node.source) load_inst = mips.LWNode(t0, (src, fp)) self.add_inst( mips.CommentNode(f"<assignode:{node.dest}-{node.source}>"), load_inst, mips.SWNode(t0, dest, fp), mips.CommentNode(f"</assignode:{node.dest}-{node.source}>"), )
def visit(self, node: cil.SetAttrNode): if node.value == 'void': load_value_inst = mips.LWNode(t0, 'void') elif isinstance(node.value, int): load_value_inst = mips.LINode(t0, node.value) else: value_address = self.get_address(node.value) load_value_inst = mips.LWNode(t0, (value_address, fp)) instance = self.get_address(node.instance) self.add_inst( mips.CommentNode( f"<setattribute:{node.attr.name}-{node.instance}>"), # sum 1 to attr index because at offset 0 is the type pointer load_value_inst, mips.LWNode(t1, (instance, fp)), mips.SWNode(t0, 4 * (node.attr.index + 1), t1).with_comm( f"Set attr '{node.attr}' of {node.instance} = {node.value}"), mips.CommentNode( f"</setattribute:{node.attr.name}-{node.instance}>"), )
def visit(self, node: cil.FunctionNode): params = [x.name for x in node.params] local_vars = [x.name for x in node.local_vars] local_vars_size = len(local_vars) * dw self.cur_function = mips.FunctionNode(node.name, params, local_vars) self.functions[node.name] = self.cur_function # Push local vars push_instructions = (mips.push_register_instructions(ra) + mips.push_register_instructions(fp) + [mips.ADDINode(fp, sp, 8)] + [mips.ADDINode(sp, sp, -local_vars_size)]) self.add_inst( mips.CommentNode(f"<function:{node.name}>"), *push_instructions, ) for instruction in node.instructions: self.visit(instruction) # Pop local vars pop_instructions = ([mips.ADDINode(sp, sp, local_vars_size)] + mips.pop_register_instructions(fp) + mips.pop_register_instructions(ra)) return_instructions = ([mips.LINode(v0, 10), mips.SysCallNode()] if self.cur_function.name == "main" else [mips.JRNode(ra)]) self.add_inst( *pop_instructions, *return_instructions, mips.CommentNode(f"</function:{node.name}>"), )
def visit(self, node: cil.ExprVoidRuntimeErrorNode): self.add_inst(mips.CommentNode(f"<expr-void-runtime-error>"), mips.LINode(v0, 4), mips.LANode(a0, 's5'), mips.SysCallNode(), mips.LINode(v0, 10), mips.SysCallNode(), mips.CommentNode(f"</expr-void-runtime-error>"))