hdl.ast: simplify enum handling.

This commit is contained in:
whitequark 2019-10-11 11:16:00 +00:00
parent d72d4a55fd
commit 7ff4c6ce43
2 changed files with 10 additions and 15 deletions

View file

@ -40,11 +40,6 @@ def _enum_shape(enum_type):
return (width, signed) return (width, signed)
def _enum_to_bits(enum_value):
width, signed = _enum_shape(type(enum_value))
return format(enum_value.value & ((1 << width) - 1), "b").rjust(width, "0")
class Value(metaclass=ABCMeta): class Value(metaclass=ABCMeta):
@staticmethod @staticmethod
def cast(obj): def cast(obj):
@ -300,14 +295,14 @@ class Value(metaclass=ABCMeta):
.format(pattern, len(self)), .format(pattern, len(self)),
SyntaxWarning, stacklevel=3) SyntaxWarning, stacklevel=3)
continue continue
if isinstance(pattern, int): if isinstance(pattern, str):
matches.append(self == pattern)
elif isinstance(pattern, (str, Enum)):
if isinstance(pattern, Enum):
pattern = _enum_to_bits(pattern)
mask = int(pattern.replace("0", "1").replace("-", "0"), 2) mask = int(pattern.replace("0", "1").replace("-", "0"), 2)
pattern = int(pattern.replace("-", "0"), 2) pattern = int(pattern.replace("-", "0"), 2)
matches.append((self & mask) == pattern) matches.append((self & mask) == pattern)
elif isinstance(pattern, int):
matches.append(self == pattern)
elif isinstance(pattern, Enum):
matches.append(self == pattern.value)
else: else:
assert False assert False
if not matches: if not matches:
@ -1304,12 +1299,12 @@ class Switch(Statement):
# Map: 2 -> "0010"; "0010" -> "0010" # Map: 2 -> "0010"; "0010" -> "0010"
new_keys = () new_keys = ()
for key in keys: for key in keys:
if isinstance(key, (bool, int)): if isinstance(key, str):
key = "{:0{}b}".format(key, len(self.test))
elif isinstance(key, str):
pass pass
elif isinstance(key, int):
key = format(key, "b").rjust(len(self.test), "0")
elif isinstance(key, Enum): elif isinstance(key, Enum):
key = _enum_to_bits(key) key = format(key.value, "b").rjust(len(self.test), "0")
else: else:
raise TypeError("Object '{!r}' cannot be used as a switch key" raise TypeError("Object '{!r}' cannot be used as a switch key"
.format(key)) .format(key))

View file

@ -346,7 +346,7 @@ class OperatorTestCase(FHDLTestCase):
def test_matches_enum(self): def test_matches_enum(self):
s = Signal.enum(SignedEnum) s = Signal.enum(SignedEnum)
self.assertRepr(s.matches(SignedEnum.FOO), """ self.assertRepr(s.matches(SignedEnum.FOO), """
(== (& (sig s) (const 2'd3)) (const 2'd3)) (== (sig s) (const 1'sd-1))
""") """)
def test_matches_width_wrong(self): def test_matches_width_wrong(self):