Example #1
0
    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
Example #2
0
    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()
Example #3
0
    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)
Example #4
0
    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])