Example #1
0
def resolve_type(base_type: symbols.BasicType,
                 is_array: bool,
                 array_size_expr: 'tree.ExpressionNode' = None,
                 lineno: int = None):
    real_type = base_type
    if is_array:
        if base_type == symbols.TYPE_VOID:
            raise errors.AtomCTypeError("array of type void", lineno)

        array_size = None
        if array_size_expr:
            if not array_size_expr.is_const():
                raise errors.AtomCTypeError(
                    "array size must be a constant expression",
                    array_size_expr.lineno)
            if array_size_expr.type != symbols.TYPE_INT:
                raise errors.AtomCTypeError(
                    "array size must be an integer expression",
                    array_size_expr.lineno)

            array_size = array_size_expr.calculate_const()
            if array_size <= 0:
                raise errors.AtomCTypeError(
                    "array size must be strictly positive",
                    array_size_expr.lineno)

        real_type = symbols.ArrayType(base_type, array_size)

    return real_type
Example #2
0
 def _on_validate(self):
     if not self.operand_left.is_lval():
         raise errors.AtomCTypeError(
             f"assignment requires lvalue as left operand; {self.operand_left} is not an lvalue",
             self.lineno)
     implicit_cast_error = typecheck.check_cast_implicit(
         self.operand_right.type, self.operand_left.type)
     if implicit_cast_error:
         raise errors.AtomCTypeError(
             f"invalid assignment - {implicit_cast_error}", self.lineno)
     return True
Example #3
0
    def _on_validate(self) -> bool:
        array_type = self.array_variable.type
        if not isinstance(array_type, symbols.ArrayType):
            raise errors.AtomCTypeError(
                "Subscript operator [] applied to non-array expression",
                self.lineno)

        if typecheck.check_cast_implicit(self.index_expression.type,
                                         symbols.TYPE_INT):
            raise errors.AtomCTypeError(
                "Array index expression must be of integer type", self.lineno)
        return True
Example #4
0
    def _on_validate(self):
        left_type = self.operand_left.type
        right_type = self.operand_left.type
        if not typecheck.is_numeric(left_type):
            raise errors.AtomCTypeError(
                "logical comparison operators can only be applied to numeric types",
                self.lineno)
        if not typecheck.is_numeric(right_type):
            raise errors.AtomCTypeError(
                "logical comparison operators can only be applied to numeric types",
                self.lineno)

        return True
Example #5
0
 def _on_validate(self):
     if self.return_type != symbols.TYPE_VOID and not any(
             isinstance(child, ReturnStatementNode)
             for child in self._children):
         raise errors.AtomCTypeError(
             "missing return from non-void function", self.lineno)
     return True
Example #6
0
    def _on_validate(self):
        condition_type = self.condition.type
        if not typecheck.is_numeric(condition_type):
            raise errors.AtomCTypeError(
                f"expression of type {condition_type} cannot be used as a logical test",
                self.condition.lineno)

        return True
Example #7
0
    def _on_validate(self):
        operand_type = self.operand.type
        if not typecheck.is_numeric(operand_type):
            raise errors.AtomCTypeError(
                "arithmetic operators can only be applied to numeric types",
                self.lineno)

        return True
Example #8
0
 def _get_type(self) -> symbols.SymbolType:
     if not typecheck.is_numeric(
             self.operand_left.type) or not typecheck.is_numeric(
                 self.operand_right.type):
         raise errors.AtomCTypeError(
             "Arithmetic expressions only support numeric operands",
             self.lineno)
     return typecheck.greatest_type(self.operand_left.type,
                                    self.operand_left.type)
Example #9
0
    def _on_validate(self):
        operand_type = self.operand.type
        if not typecheck.is_numeric(operand_type) and not isinstance(
                operand_type, symbols.ArrayType):
            raise errors.AtomCTypeError(
                "logical operators can only be applied to numeric and array types",
                self.lineno)

        return True
Example #10
0
    def _on_validate(self) -> bool:
        var = self.symbol_table.get_symbol(self.symbol_name)
        if var is None:
            raise errors.AtomCDomainError(
                f"undefined variable {self.symbol_name}", self.lineno)

        if not isinstance(var, symbols.VariableSymbol):
            raise errors.AtomCTypeError(
                f"symbol {var} cannot be used as a value", self.lineno)

        return True
Example #11
0
    def _on_validate(self):
        if self.current_function is None:
            raise errors.AtomCDomainError("return statement outside function",
                                          self.lineno)

        if self.value is None and self.current_function.return_type != symbols.TYPE_VOID:
            raise errors.AtomCTypeError("void return in non-void function",
                                        self.lineno)

        if self.value is not None:
            if self.current_function.return_type == symbols.TYPE_VOID:
                raise errors.AtomCTypeError("non-void return in void function",
                                            self.lineno)

            implicit_cast_error = typecheck.check_cast_implicit(
                self.value.type, self.current_function.return_type)
            if implicit_cast_error:
                raise errors.AtomCTypeError(
                    f"bad return type - {implicit_cast_error}", self.lineno)

        return True
Example #12
0
    def _on_validate(self) -> bool:
        function_symbol = self.symbol_table.get_symbol(self.function_name)
        if function_symbol is None:
            raise errors.AtomCDomainError(
                f"undefined function {self.function_name}", self.lineno)
        if not isinstance(function_symbol, symbols.FunctionSymbol):
            raise errors.AtomCDomainError(
                f"{self.function_name} is not a function", self.lineno)

        if len(self.args) != len(function_symbol.args):
            raise errors.AtomCTypeError(
                f"not enough arguments in call to function {self.function_name}",
                self.lineno)

        for narg, (arg_value,
                   arg_def) in enumerate(zip(self.args, function_symbol.args)):
            implicit_cast_error = typecheck.check_cast_implicit(
                arg_value.type, arg_def.type)
            if implicit_cast_error:
                raise errors.AtomCTypeError(
                    f"in call to {self.function_name} - argument {narg} type mismatch; {implicit_cast_error}",
                    self.lineno)
        return True
Example #13
0
    def _on_validate(self):
        struct_type = self.struct_variable.type
        if isinstance(struct_type, symbols.StructType):
            struct_symbol = struct_type.struct_symbol
            member_symbol = struct_symbol.get_member_symbol(self.member_name)
            if member_symbol is None:
                raise errors.AtomCDomainError(
                    f"struct {struct_symbol.name} has no field named {self.member_name}",
                    self.lineno)

            return member_symbol.type
        else:
            raise errors.AtomCTypeError(
                "Dot notation member access requires a struct as left operand",
                self.lineno)
Example #14
0
 def _on_validate(self):
     if self.base_type == symbols.TYPE_VOID:
         raise errors.AtomCTypeError(
             "Cannot declare variables of type void", self.lineno)
     return True
Example #15
0
 def _on_validate(self):
     explicit_cast_error = typecheck.check_cast_explicit(
         self.cast_expr.type, self.type)
     if explicit_cast_error:
         raise errors.AtomCTypeError(explicit_cast_error, self.lineno)
     return True