Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
rhs_pointer = rhs_type.is_pointer_operand()
if rhs_pointer:
rhs_sizeof = cast(PointerType, rhs_type).type.sizeof()
if ((lhs_pointer and rhs_pointer and lhs_sizeof != rhs_sizeof) or
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
lhs_pointer = lhs_type.is_pointer_operand()
if lhs_pointer:
lhs_sizeof = cast(PointerType, lhs_type).type.sizeof()
rhs_pointer = rhs_type.is_pointer_operand()
if rhs_pointer:
rhs_sizeof = cast(PointerType, rhs_type).type.sizeof()
if ((lhs_pointer and rhs_pointer and lhs_sizeof != rhs_sizeof) or
(lhs_pointer and not rhs_pointer and not rhs_type.is_integer()) or
(rhs_pointer and not lhs_pointer) or
(not lhs_pointer and not rhs_pointer and
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary - ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer and rhs_pointer:
return Object(self.prog_, self.prog_._type_index._ptrdiff_t(),
value=(lhs - rhs) // lhs_sizeof)
elif lhs_pointer:
return Object(self.prog_, lhs_type, value=lhs - lhs_sizeof * rhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs - rhs)
def _arithmetic_operator(self, op: Callable, op_name: str, lhs: Any,
rhs: Any) -> 'Object':
lhs, lhs_type, rhs, rhs_type = self._binary_operands(lhs, rhs)
if not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic():
raise TypeError(f'invalid operands to binary {op_name} ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=op(lhs, rhs))
def __round__(self, ndigits: Optional[int] = None) -> Union[int, 'Object']:
if not self._real_type.is_arithmetic():
raise TypeError(f'cannot round {self.type_.name!r}')
if ndigits is None:
return round(self.value_())
return Object(self.prog_, self.type_,
value=round(self.value_(), ndigits))
(not lhs_type.is_arithmetic() or not rhs_type.is_arithmetic()))):
raise TypeError(f'invalid operands to binary + ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
if lhs_pointer:
assert isinstance(lhs_type, PointerType)
return Object(self.prog_, lhs_type,
value=lhs + lhs_type.type.sizeof() * rhs)
elif rhs_pointer:
assert isinstance(rhs_type, PointerType)
return Object(self.prog_, rhs_type,
value=rhs + rhs_type.type.sizeof() * lhs)
else:
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=lhs + rhs)
Normally the dot operator (".") can be used to accomplish the same
thing, but this method can be used if there is a name conflict with an
Object member or method.
"""
if isinstance(self._real_type, PointerType):
address = self.value_()
type_ = self._real_type.type.real_type()
else:
address = self.address_
type_ = self._real_type
try:
# mypy doesn't understand the except AttributeError.
member_type, offset = type_.member(name) # type: ignore
except AttributeError:
raise ValueError(f'member access must be on a struct or union, not {self.type_.name!r}') from None
return Object(self.prog_, member_type, address=address + offset)
def _integer_operator(self, op: Callable, op_name: str,
lhs: Any, rhs: Any) -> 'Object':
lhs, lhs_type, rhs, rhs_type = self._binary_operands(lhs, rhs)
if not lhs_type.is_integer() or not rhs_type.is_integer():
raise TypeError(f'invalid operands to binary {op_name} ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
type_, lhs, rhs = self._usual_arithmetic_conversions(lhs, lhs_type,
rhs, rhs_type)
return Object(self.prog_, type_, value=op(lhs, rhs))
def _shift_operator(self, op: Callable, op_name: str, lhs: Any,
rhs: Any) -> 'Object':
lhs, lhs_type, rhs, rhs_type = self._binary_operands(lhs, rhs)
if not lhs_type.is_integer() or not rhs_type.is_integer():
raise TypeError(f'invalid operands to binary {op_name} ({lhs_type.name!r} and {rhs_type.name!r})')
lhs_type = lhs_type.operand_type()
rhs_type = rhs_type.operand_type()
lhs_type = self.prog_._type_index._integer_promotions(lhs_type)
rhs_type = self.prog_._type_index._integer_promotions(rhs_type)
return Object(self.prog_, lhs_type, value=op(lhs, rhs))