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)
def pointer_subsc(self, point, arith, il_code): """Return the LValue for this node. This function is called in the case where one operand is a pointer and the other operand is an integer. """ if not point.ctype.arg.is_complete(): err = "cannot subscript pointer to incomplete type" raise CompilerError(err, self.op.r) shift = get_size(point.ctype.arg, arith, il_code) out = ILValue(point.ctype) il_code.add(math_cmds.Add(out, point, shift)) return IndirectLValue(out)
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)
def _nonarith(self, left, right, il_code): """Make addition code if either operand is non-arithmetic type.""" # One operand should be pointer to complete object type, and the # other should be any integer type. if left.ctype.is_pointer() and right.ctype.is_integral(): arith, pointer = right, left elif right.ctype.is_pointer() and left.ctype.is_integral(): arith, pointer = left, right else: err = "invalid operand types for addition" raise CompilerError(err, self.op.r) if not pointer.ctype.arg.is_complete(): err = "invalid arithmetic on pointer to incomplete type" raise CompilerError(err, self.op.r) # Multiply by size of objects out = ILValue(pointer.ctype) shift = get_size(pointer.ctype.arg, arith, il_code) il_code.add(math_cmds.Add(out, pointer, shift)) return out