Skip to content

Commit

Permalink
Integer promotion is complete
Browse files Browse the repository at this point in the history
  • Loading branch information
James Johnson committed Oct 18, 2019
1 parent 54f3ab2 commit 31080fb
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ install:
- find . -type f -exec sed -i "s/{{VERSION}}/${VERSION}/g" {} \;
- pip install -r requirements.txt
- pip install .
- pip install pytest-cov
- pip install pytest-xdist

script: bin/run_tests
deploy:
Expand Down
6 changes: 1 addition & 5 deletions bin/run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,4 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

cd $DIR/../tests

if [[ $# -ne 1 ]] ; then
python -m unittest $(echo test_*.py | sed 's/.py//g' | sed 's/^\.\///')
else
python -m unittest $@
fi
pytest -n 5 --cov-report term --cov pfp "$@"
77 changes: 45 additions & 32 deletions pfp/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,8 @@ def __iadd__(self, other):
return self

def __isub__(self, other):
self._pfp__value -= get_value(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value - root)
return self

def __imul__(self, other):
Expand Down Expand Up @@ -1587,34 +1588,50 @@ def __iadd__(self, other):
return self

def __isub__(self, other):
self._pfp__value -= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value - root)
return self

def __imul__(self, other):
self._pfp__value *= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value * root)
return self

def __idiv__(self, other):
self._pfp__value /= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(int(self._pfp__value / root))
return self

def __iand__(self, other):
self._pfp__value &= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value & root)
return self

def __ixor__(self, other):
self._pfp__value ^= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value ^ root)
return self

def __ior__(self, other):
self._pfp__value |= get_value(other)
other = self._pfp__promote(other)
root = get_value(other)
self._pfp__set_value(self._pfp__value | root)
return self

def __ifloordiv__(self, other):
self._pfp__value //= get_value(other)
return self
# will always be floordiv with IntBase numbers
return self.__idiv__(self, other)

def __imod__(self, other):
# NOTE: We are not doing the same style of integer promotion here.
# this current implementation matches the C implementation.
#
# See the test_imod function in test_integer_promotion.py
self._pfp__value %= get_value(other)
return self

Expand All @@ -1639,16 +1656,16 @@ def __add__(self, other):

def __sub__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value - get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res -= other
return res

def __mul__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value * get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res *= other
return res

def __truediv__(self, other):
Expand All @@ -1663,38 +1680,34 @@ def __truediv__(self, other):

def __div__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value / get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res /= other
return res

def __and__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value & get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res &= other
return res

def __xor__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value ^ get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res ^= other
return res

def __or__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value | get_value(other)
)
res._pfp__set_value(self)
# takes care of promotion already
res |= other
return res

def __floordiv__(self, other):
res = self.__class__()
res._pfp__set_value(
self._pfp__value // get_value(other)
)
return res
return self.__div__(self, other)

def __mod__(self, other):
res = self.__class__()
Expand Down
8 changes: 5 additions & 3 deletions pfp/interp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2135,20 +2135,22 @@ def _handle_enum(self, node, scope, ctxt, stream):

enum_vals = {}
curr_val = enum_cls()
curr_val._pfp__value = -1
curr_val._pfp__value = 0
prev_val = None
for enumerator in node.values.enumerators:
if enumerator.value is not None:
curr_val_parsed = self._handle_node(
enumerator.value, scope, ctxt, stream
)
curr_val = enum_cls()
curr_val._pfp__set_value(curr_val_parsed._pfp__value)
else:
curr_val = curr_val + 1
elif prev_val is not None:
curr_val = prev_val + 1
curr_val._pfp__freeze()
enum_vals[enumerator.name] = curr_val
enum_vals[fields.PYVAL(curr_val)] = enumerator.name
scope.add_local(enumerator.name, curr_val)
prev_val = curr_val

if node.name is not None:
enum_cls = EnumDef(node.name, enum_cls, enum_vals)
Expand Down
Loading

0 comments on commit 31080fb

Please sign in to comment.