Exemple #1
0
 def addr(self, il_code):
     self.fix_block_count(il_code)
     out = ILValue(PointerCType(self.ctype()))
     il_code.add(
         value_cmds.AddrRel(out, self.base, self.fixed_block,
                            self.fixed_count))
     return out
Exemple #2
0
    def generate_func_ctype(self, decl, prev_ctype):
        """ Generate a function ctype from a given a decl_node """

        # Prohibit storage class specifiers in parameters.
        for param in decl.args:
            decl_info = self.get_decl_infos(param)[0]
            if decl_info.storage:
                err = "storage class specified for function parameter"
                raise CompilerError(err, decl_info.span)

        # Create a new scope because if we create a new struct type inside the function parameters, it should be local
        # to those parameters.
        self.symbol_table.new_scope()
        args = [self.get_decl_infos(decl)[0].ctype for decl in decl.args]
        self.symbol_table.end_scope()

        # adjust array and function parameters
        has_void = False
        for i in range(len(args)):
            ctype = args[i]
            if ctype.is_array(): args[i] = PointerCType(ctype.elem)
            elif ctype.is_function(): args[i] = PointerCType(ctype)
            elif ctype.is_void(): has_void = True
        if has_void and len(args) > 1:
            decl_info = self.get_decl_infos(decl.args[0])[0]
            err = "'void' must be the only parameter"
            raise CompilerError(err, decl_info.span)
        if prev_ctype.is_function():
            err = "function cannot return function type"
            raise CompilerError(err, self.r)
        if prev_ctype.is_array():
            err = "function cannot return array type"
            raise CompilerError(err, self.r)

        if not args and not self.body:
            new_ctype = FunctionCType([], prev_ctype, True)
        elif has_void:
            new_ctype = FunctionCType([], prev_ctype, False)
        else:
            new_ctype = FunctionCType(args, prev_ctype, False)
        return new_ctype
Exemple #3
0
    def _lvalue(self, il_code, symbol_table, c):
        struct_addr = self.head.make_il(il_code, symbol_table, c)
        if not struct_addr.ctype.is_pointer():
            err = "first argument of '->' must have pointer type"
            raise CompilerError(err, self.r)

        offset, ctype = self.get_offset_info(struct_addr.ctype.arg)
        shift = ILValue(ctypes.longint)
        il_code.register_literal_var(shift, str(offset))

        out = ILValue(PointerCType(ctype))
        il_code.add(math_cmds.Add(out, struct_addr, shift))
        return IndirectLValue(out)
Exemple #4
0
    def make_ctype(self, decl, prev_ctype):
        """Generate a ctype from the given declaration. Return a `ctype, identifier token` tuple.
            decl - Node of decl_nodes to parse. See decl_tree.py for explanation about decl_nodes.
            prev_ctype - The ctype formed from all parts of the tree above the current one.
        """
        if isinstance(decl, decl_nodes.Pointer):
            new_ctype = PointerCType(prev_ctype, decl.const)
        elif isinstance(decl, decl_nodes.Array):
            new_ctype = self.generate_array_ctype(decl, prev_ctype)
        elif isinstance(decl, decl_nodes.Function):
            new_ctype = self.generate_func_ctype(decl, prev_ctype)
        elif isinstance(decl, decl_nodes.Identifier):
            return prev_ctype, decl.identifier

        return self.make_ctype(decl.child, new_ctype)
Exemple #5
0
    def make_il(self, il_code, symbol_table, c):
        lvalue = self.lvalue(il_code, symbol_table, c)

        # Decay array
        if lvalue.ctype().is_array():
            addr = lvalue.addr(il_code)
            return set_type(addr, PointerCType(lvalue.ctype().elem), il_code)

        # Decay function
        elif lvalue.ctype().is_function():
            return lvalue.addr(il_code)

        # Nothing to decay
        else:
            return lvalue.val(il_code)
Exemple #6
0
    def _lvalue(self, il_code, symbol_table, c):
        head_lv = self.head.lvalue(il_code, symbol_table, c)
        struct_ctype = head_lv.ctype() if head_lv else None
        offset, ctype = self.get_offset_info(struct_ctype)

        if isinstance(head_lv, DirectLValue):
            head_val = self.head.make_il(il_code, symbol_table, c)
            return RelativeLValue(ctype, head_val, offset)
        else:
            struct_addr = head_lv.addr(il_code)

            shift = ILValue(ctypes.longint)
            il_code.register_literal_var(shift, str(offset))

            out = ILValue(PointerCType(ctype))
            il_code.add(math_cmds.Add(out, struct_addr, shift))
            return IndirectLValue(out)
Exemple #7
0
 def addr(self, il_code):
     out = ILValue(PointerCType(self.il_value.ctype))
     il_code.add(value_cmds.AddrOf(out, self.il_value))
     return out