Exemplo n.º 1
0
    def process(self, decl_info, il_code, symbol_table, c):
        """Process given DeclInfo object.

        This includes error checking, adding the variable to the symbol
        table, and registering it with the IL.
        """
        if not decl_info.identifier:
            err = "missing identifier name in declaration"
            raise CompilerError(err, decl_info.range)

        # TODO: prohibit all declarations of incomplete types?
        if decl_info.ctype == ctypes.void:
            err = "variable of void type declared"
            raise CompilerError(err, decl_info.range)

        var = symbol_table.add(decl_info.identifier, decl_info.ctype)

        # Variables declared to be EXTERN
        if decl_info.storage == DeclInfo.EXTERN:
            il_code.register_extern_var(var, decl_info.identifier.content)

            # Extern variable should not have initializer
            if decl_info.init:
                err = "extern variable has initializer"
                raise CompilerError(err, decl_info.range)

        # Variables declared to be static
        elif decl_info.storage == DeclInfo.STATIC:
            # These should be in .data section, but not global
            raise NotImplementedError("static variables unsupported")

        # Global variables
        elif c.is_global:
            # Global functions are extern by default
            if decl_info.ctype.is_function():
                il_code.register_extern_var(var, decl_info.identifier.content)
            else:
                # These should be common if uninitialized, or data if
                # initialized
                raise NotImplementedError(
                    "non-extern global variables unsupported")

        # Local variables
        else:
            il_code.register_local_var(var)

        # Initialize variable if needed
        if decl_info.init:
            init_val = decl_info.init.make_il(il_code, symbol_table, c)
            lval = DirectLValue(var)

            if lval.ctype().is_arith() or lval.ctype().is_pointer():
                lval.set_to(init_val, il_code, decl_info.identifier.r)
            else:
                err = "declared variable is not of assignable type"
                raise CompilerError(err, decl_info.range)
Exemplo n.º 2
0
    def do_init(self, var, storage, il_code, symbol_table, c):
        """Create code for initializing given variable.

        Caller must check that this object has an initializer.
        """
        # little bit hacky, but will be fixed when full initializers are
        # implemented shortly

        init = self.init.make_il(il_code, symbol_table, c)
        if storage == symbol_table.STATIC and not init.literal:
            err = ("non-constant initializer for variable with static "
                   "storage duration")
            raise CompilerError(err, self.init.r)
        elif storage == symbol_table.STATIC:
            il_code.static_initialize(var, getattr(init.literal, "val", None))
        elif var.ctype.is_arith() or var.ctype.is_pointer():
            lval = DirectLValue(var)
            lval.set_to(init, il_code, self.identifier.r)
        else:
            err = "declared variable is not of assignable type"
            raise CompilerError(err, self.range)
Exemplo n.º 3
0
    def do_init(self, var, storage, il_code, symbol_table, c):
        """Create code for initializing given variable.

        Caller must check that this object has an initializer.
        """
        # little bit hacky, but will be fixed when full initializers are
        # implemented shortly

        init = self.init.make_il(il_code, symbol_table, c)
        if storage == symbol_table.STATIC and not init.literal:
            err = ("non-constant initializer for variable with static "
                   "storage duration")
            raise CompilerError(err, self.init.r)
        elif storage == symbol_table.STATIC:
            il_code.static_initialize(var, getattr(init.literal, "val", None))
        elif var.ctype.is_arith() or var.ctype.is_pointer():
            lval = DirectLValue(var)
            lval.set_to(init, il_code, self.identifier.r)
        else:
            err = "declared variable is not of assignable type"
            raise CompilerError(err, self.range)