示例#1
0
def bind_struct_type(base_type: symbols.BasicType,
                     symbol_table: symbols.SymbolTable = None,
                     lineno: int = None):
    if isinstance(base_type, symbols.StructType):
        struct_name = base_type.struct_name
        base_type.set_symbol(symbol_table)
        if base_type.struct_symbol is None:
            raise errors.AtomCDomainError(f"Undefined symbol {struct_name}",
                                          lineno)
        if not isinstance(base_type.struct_symbol, symbols.StructSymbol):
            raise errors.AtomCDomainError(f"{struct_name} is not a struct",
                                          lineno)
示例#2
0
文件: symbols.py 项目: axnsan12/atomc
    def add_symbol(self, symbol: Symbol):
        existing = self._get_symbol_this(symbol.name)
        if existing:
            raise errors.AtomCDomainError(
                "Attempt to redefine existing symbol {} in scope {}".format(
                    existing, self.scope_name), symbol.lineno)

        physical_storages = (StorageType.GLOBAL, StorageType.LOCAL,
                             StorageType.STRUCT)
        if symbol.storage == StorageType.ARG:
            last_arg = next((s for s in reversed(self._symbols.values())
                             if s.storage == StorageType.ARG),
                            None)  # type: Symbol
            symbol.offset = last_arg.offset - symbol.type.sizeof if last_arg else -TYPE_INT.sizeof - symbol.type.sizeof
        elif symbol.storage in physical_storages:
            last_symbol = next((s for s in reversed(self._symbols.values())
                                if s.storage in physical_storages),
                               None)  # type: Symbol
            if last_symbol and last_symbol.storage != symbol.storage:
                raise ValueError(
                    f"Mixed storage types in symbol table - {symbol.storage} and {last_symbol.storage}"
                )
            symbol.offset = last_symbol.offset + last_symbol.type.sizeof if last_symbol else 0

        self._symbols[symbol.name] = symbol
        symbol.table = self
示例#3
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
示例#4
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
示例#5
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)
示例#6
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
示例#7
0
    def _on_validate(self):
        if self.current_loop is None:
            raise errors.AtomCDomainError("break statement outside loop",
                                          self.lineno)

        return True