Beispiel #1
0
    def visit(self, node: ProgramNode, scope: Scope):
        self.current_function = self.register_function('entry')
        idx = self.index
        instance = self.define_internal_local()
        result = self.define_internal_local()

        self.register_instruction(cil.AllocateNode('Main', instance))
        typex = self.context.get_type('Main', (0, 0))
        if typex.all_attributes():
            self.register_instruction(
                cil.StaticCallNode(typex.name, typex.name, None,
                                   [cil.ArgNode(instance)], typex.name))

        name = self.to_function_name('main', 'Main')
        self.register_instruction(
            cil.StaticCallNode('Main', 'main', result, [cil.ArgNode(instance)],
                               'Object'))
        self.register_instruction(cil.ReturnNode(0))
        self.current_function = None

        self.void_data = self.register_data(VOID_NAME).name

        self.create_built_in()
        for declaration, child_scope in zip(node.declarations, scope.children):
            self.visit(declaration, child_scope)

        return cil.ProgramNode(self.dottypes, self.dotdata, self.dotcode, idx)
Beispiel #2
0
    def visit(self, node: CallNode, scope: 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.register_instruction(
            cil.GotoIfFalseNode(isvoid, continue_label.label))
        self.register_instruction(cil.ErrorNode('dispatch_error'))
        self.register_instruction(continue_label)

        if otype in [StringType(), IntType(), BoolType()]:
            self.register_instruction(
                cil.StaticCallNode(otype.name, node.id, result, args_node,
                                   rtype.name))
        else:
            self.register_instruction(
                cil.DynamicCallNode(otype.name, obj, node.id, result,
                                    args_node, rtype.name))
        return result, self._return_type(otype, node)
Beispiel #3
0
    def handle_arguments(self, args, scope, param_types):
        args_node = []
        args = [self.visit(arg, scope) for arg in args]

        for (arg, typex), param_type in zip(args, param_types):
            if typex.name in ['String', 'Int', 'Bool'
                              ] and param_type.name == 'Object':
                auxiliar = self.define_internal_local()
                self.register_instruction(cil.BoxingNode(auxiliar, typex.name))
            else:
                auxiliar = arg
            args_node.append(cil.ArgNode(auxiliar, self.index))
        return args_node
Beispiel #4
0
    def visit(self, node: InstantiateNode, scope: Scope):
        instance = self.define_internal_local()
        typex = self.context.get_type(node.lex, node.pos)
        typex = get_type(typex, self.current_type)
        self.register_instruction(cil.AllocateNode(typex.name, instance))

        # calling the constructor to load all attributes
        # Si tiene atributos entonces tendrá constructor (esto se deberia optimizar mas)
        if typex.all_attributes():
            self.register_instruction(
                cil.StaticCallNode(typex.name, typex.name, instance,
                                   [cil.ArgNode(instance)], typex.name))

        return instance, typex
Beispiel #5
0
    def visit(self, node: StaticCallNode, scope: Scope):
        meth = self.current_type.get_method(node.id, node.pos)
        args_node = [cil.ArgNode('self', self.index)] + self.handle_arguments(
            node.args, scope, meth.param_types)

        rtype = meth.return_type
        if isinstance(rtype, VoidType):
            result = None
        else:
            result = self.define_internal_local()

        self.register_instruction(
            cil.DynamicCallNode(self.current_type.name, 'self', node.id,
                                result, args_node, rtype.name))
        return result, self._return_type(self.current_type, node)