Exemplo n.º 1
0
    def visit(self, node, scope):
        left_infered = node.left.inferenced_type  #.clone()
        right_infered = node.right.inferenced_type  #.clone()

        self.visit(node.left, scope)
        self.visit(node.right, scope)

        new_left = node.left.inferenced_type
        new_right = node.right.inferenced_type

        int_type = self.context.get_type("Int")
        if not equal(left_infered, new_left):
            left_clone = new_left.clone()
            if not conforms(left_infered, int_type):
                self.add_error(
                    node.left,
                    f"Type Error: Arithmetic Error: Left member type({left_clone.name}) does not conforms to Int type."
                )

        if not equal(right_infered, new_right):
            right_clone = new_left.clone()
            if not conforms(right_infered, int_type):
                self.add_error(
                    node.right,
                    f"Type Error: Arithmetic Error: Right member type({right_clone.name}) does not conforms to Int type."
                )
Exemplo n.º 2
0
    def visit(self, node, scope):
        condition_infered = node.condition.inferenced_type.clone()
        then_infered = node.then_body.inferenced_type.clone()
        else_infered = node.else_body.inferenced_type.clone()

        self.visit(node.condition, scope)
        self.visit(node.then_body, scope)
        self.visit(node.else_body, scope)

        new_condition_infered = node.condition.inferenced_type
        new_then_infered = node.then_body.inferenced_type
        new_else_infered = node.else_body.inferenced_type

        if not equal(condition_infered, new_condition_infered):
            self.add_error(
                node,
                f"Type Error: If's condition type({new_condition_infered.name}) does not conforms to Bool type."
            )

        if equal(then_infered, new_then_infered) and equal(
                else_infered, new_else_infered):
            return

        joined_type = join(new_then_infered, new_else_infered)
        node.inferenced_type = joined_type
Exemplo n.º 3
0
    def visit(self, node, scope):
        left_infered = node.left.inferenced_type  #.clone()
        right_infered = node.right.inferenced_type  #.clone()

        self.visit(node.left, scope)
        self.visit(node.right, scope)

        new_left = node.left.inferenced_type
        new_right = node.right.inferenced_type
        left_clone = new_left.clone()
        right_clone = new_right.clone()

        if equal(left_infered, new_left) and equal(right_infered, new_right):
            return

        if not conforms(left_clone, new_right) and not conforms(
                right_clone, new_left):
            self.add_error(
                node,
                f"Type Error: Left expression type({new_left.name}) does not conforms to right expression type({new_right.name})"
            )
Exemplo n.º 4
0
    def visit(self, node, scope):
        condition_infered = node.condition.inferenced_type.clone()
        self.visit(node.condition, scope)
        new_cond_infered = node.condition.inferenced_type

        if not equal(condition_infered, new_cond_infered):
            self.add_error(
                node,
                f"Type Error: Loop's condition type({new_cond_infered.name}) does not conforms to Bool type."
            )

        self.visit(node.body, scope)
Exemplo n.º 5
0
 def visit(self, node, scope):
     expr_infered = node.expr.inferenced_type  #.clone()
     self.visit(node.expr, scope)
     new_expr = node.expr.inferenced_type
     expr_clone = new_expr.clone()
     int_type = self.context.get_type("Int")
     if equal(expr_infered, new_expr):
         return
     if not conforms(new_expr, int_type):
         self.add_error(
             node.value,
             f"Type Error: Not's expresion type({expr_clone.name} does not conforms to Int type"
         )
Exemplo n.º 6
0
    def visit(self, node, scope: Scope):
        self.visit(node.case_expr, scope)

        type_list = []
        change = False
        for option in node.options:
            child = scope.next_child()
            option_infered = option.inferenced_type.clone()
            self.visit(option, child)
            new_option_infered = option.inferenced_type
            type_list.append(new_option_infered)
            change = change or not equal(option_infered, new_option_infered)

        if change:
            joined_type = join_list(type_list)
            node.inferenced_type = joined_type
Exemplo n.º 7
0
    def visit(self, node, scope: Scope):
        if not node.expr:
            return

        expr_infered = node.expr.inferenced_type.clone()
        self.visit(node.expr, scope)
        new_expr_inferred = node.expr.inferenced_type

        if equal(expr_infered, new_expr_inferred):
            return

        node_infered = node.inferenced_type
        new_clone_infered = new_expr_inferred.clone()
        if not conforms(new_expr_inferred, node_infered):
            self.add_error(
                node,
                f"Semantic Error: Variable \'{node.id}\' expression type({new_clone_infered.name}) does not conforms to declared type({node_infered.name})."
            )
Exemplo n.º 8
0
    def visit(self, node, scope):
        if not node.expr:
            return

        node_infered = node.inferenced_type
        expr_infered = node.expr.inferenced_type.clone()

        self.visit(node.expr, scope)
        new_expr_infered = node.expr.inferenced_type

        if equal(expr_infered, new_expr_infered):
            return

        new_clone_inferred = new_expr_infered.clone()
        if not conforms(new_expr_infered, node_infered):
            self.add_error(
                node,
                f"Type Error: In class '{self.current_type.name}' attribue '{node.id}' expression type({new_clone_inferred.name}) does not conforms to declared type ({node_infered.name})."
            )
Exemplo n.º 9
0
    def visit(self, node, scope: Scope):
        if not node.defined and node.id != "self":
            return

        expr_infered = node.expr.inferenced_type.clone()
        self.visit(node.expr, scope)
        new_expr_infered = node.expr.inferenced_type

        if equal(expr_infered, new_expr_infered):
            return

        var_type = scope.find_variable(node.id).type
        new_clone_infered = new_expr_infered.clone()
        if not conforms(new_expr_infered, var_type):
            self.add_error(
                node,
                f"Type Error: Cannot assign new value to variable '{node.id}'. Expression type({new_clone_infered.name}) does not conforms to declared type ({var_type.name})."
            )
            var_type = ErrorType()

        node.inferenced_type = var_type
Exemplo n.º 10
0
    def visit(self, node, scopex: Scope):
        scope = scopex.next_child()

        ret_type_infered = node.body.inferenced_type.clone()
        self.visit(node.body, scope)
        new_type_infered = node.body.inferenced_type

        if equal(ret_type_infered, new_type_infered):
            return

        current_method = self.current_type.get_method(node.id)
        ret_type_decl = current_method.return_type.swap_self_type(
            self.current_type)
        new_clone_infered = new_type_infered.clone()

        if not conforms(new_type_infered, ret_type_decl):
            self.add_error(
                node,
                f"Type Error: In Class \'{self.current_type.name}\' method \'{current_method.name}\' return expression type({new_clone_infered.name}) does not conforms to declared return type ({ret_type_decl.name})"
            )
            ret_type_expr = ErrorType()

        node.inferenced_type = ret_type_expr
        ret_type_decl.swap_self_type(self.current_type, back=True)
Exemplo n.º 11
0
    def visit(self, node, scope):
        caller = node.inferenced_caller
        if node.type and node.expr:
            bridge_infered = node.expr.inferenced_type.clone()
            self.visit(node.expr, scope)
            bridge = node.expr.inferenced_type
            if not equal(bridge_infered, bridge):
                bridge_clone = bridge.clone()
                if not conforms(bridge, caller):
                    self.add_error(
                        node,
                        f"Semantic Error: Cannot effect dispatch because expression type({bridge_clone.name}) does not conforms to caller type({caller.name})."
                    )
                    caller = ErrorType()
        elif node.expr:
            self.visit(node.expr, scope)
            caller = node.expr.inferenced_type

        if len(caller.type_set) > 1:
            methods_by_name = self.context.get_method_by_name(
                node.id, len(node.args))
            types = [typex for _, typex in methods_by_name]
            conforms(caller, TypeBag(set(types), types))
            if len(caller.heads) > 1:
                error = f"Semantic Error: Method \"{node.id}\" found in {len(caller.heads)} unrelated types:\n"
                error += "   -Found in: "
                error += ", ".join(typex.name for typex in caller.heads)
                self.add_error(node, error)
                caller = ErrorType()
            elif len(caller.heads) == 0:
                self.add_error(
                    node,
                    f"There is no method called {node.id} which takes {len(node.args)} paramters."
                )
                caller = ErrorType()

        if len(caller.heads) == 1:
            caller_type = caller.heads[0]
            method = caller_type.get_method(node.id)

            if len(node.args) != len(method.param_types):
                self.add_error(
                    node,
                    f"Semantic Error: Method '{node.id}' from class '{caller_type.name}' takes {len(node.args)} arguments but {method.param_types} were given.'"
                )
                node.inferenced_type = ErrorType()

            decl_return_type = method.return_type.clone()
            decl_return_type.swap_self_type(caller_type)

            type_set = set()
            heads = []
            type_set = smart_add(type_set, heads, decl_return_type)
            for i in range(len(node.args)):
                arg = node.args[i]
                p_type = method.param_types[i]
                arg_infered = arg.inferenced_type.clone()
                self.visit(arg, scope)
                new_arg_infered = arg.inferenced_type
                new_clone_infered = new_arg_infered.clone()
                if not conforms(new_arg_infered, p_type):
                    self.add_error(
                        node.arg,
                        f"Type Error: Argument expression type ({new_clone_infered.name}) does not conforms parameter declared type({p_type.name})"
                    )
            node.inferenced_type = TypeBag(type_set, heads)
        else:
            node.inferenced_type = ErrorType()
        node.inferenced_caller = caller