def visit(self, node: CaseNode, scope): expr, typex = self.visit(node.expr, scope) result = self.define_internal_local() end_label = cil.LabelNode(f'end__{self.idx}') error_label = cil.LabelNode(f'error__{self.idx}') isvoid = self.check_void(expr) self.add_instruction(cil.GotoIfNode(isvoid, error_label.label)) try: new_scope = scope.expr_dict[node] except: new_scope = scope sorted_case_list = self.sort_nodes(node.case_list) for i, case in enumerate(sorted_case_list): next_label = cil.LabelNode(f'next__{self.idx}_{i}') expr_i = self.visit(case, new_scope.create_child(), expr, next_label, typex) self.add_instruction(cil.AssignNode(result, expr_i)) self.add_instruction(cil.GotoNode(end_label.label)) self.add_instruction(next_label) self.add_instruction(cil.ErrorNode('case_error')) self.add_instruction(error_label) self.add_instruction(cil.ErrorNode('case_void_error')) self.add_instruction(end_label) return result, typex
def visit(self, node: WhileNode, scope): start_label = cil.LabelNode(f'start__{self.idx}') end_label = cil.LabelNode(f'end__{self.idx}') result = self.define_internal_local() self.add_instruction(cil.VoidConstantNode(result)) self.add_instruction(start_label) cond, _ = self.visit(node.cond, scope) self.add_instruction(cil.GotoIfFalseNode(cond, end_label.label)) expr, typex = self.visit(node.expr, scope) self.add_instruction(cil.AssignNode(result, expr)) self.add_instruction(cil.GotoNode(start_label.label)) self.add_instruction(end_label) return result, ObjectType()
def visit(self, node: CallNode, scope): obj, otype = self.visit(node.obj, scope) meth = otype.get_method(node.id, node.pos) args_node = [cil.ArgNode(obj, self.index)] + self.handle_arguments( node.args, scope, meth.param_types) rtype = meth.return_type result = None if isinstance( rtype, VoidType) else self.define_internal_local() continue_label = cil.LabelNode(f'continue__{self.index}') isvoid = self.check_void(obj) self.add_instruction(cil.GotoIfFalseNode(isvoid, continue_label.label)) self.add_instruction(cil.ErrorNode('dispatch_error')) self.add_instruction(continue_label) if otype in [StringType(), IntType(), BoolType()]: self.add_instruction( cil.StaticCallNode(otype.name, node.id, result, args_node, rtype.name)) else: self.add_instruction( cil.DynamicCallNode(otype.name, obj, node.id, result, args_node, rtype.name)) return result, self._return_type(otype, node)
def visit(self, node: ConditionalNode, scope): cond, _ = self.visit(node.cond, scope) true_label = cil.LabelNode(f"true__{self.idx}") end_label = cil.LabelNode(f"end__{self.idx}") result = self.define_internal_local() self.add_instruction(cil.GotoIfNode(cond, true_label.label)) false_expr, ftypex = self.visit(node.else_stm, scope) self.add_instruction(cil.AssignNode(result, false_expr)) self.add_instruction(cil.GotoNode(end_label.label)) self.add_instruction(true_label) true_expr, ttypex = self.visit(node.stm, scope) self.add_instruction(cil.AssignNode(result, true_expr)) self.add_instruction(end_label) return result, get_common_basetype([ttypex, ftypex])