hdl._ast: add enum name argument to Format.Enum
.
Turns out that RTLIL enum representation requires such, so add a place to store it.
This commit is contained in:
parent
1fdd9bf4e9
commit
67f5b61bcc
|
@ -2769,8 +2769,11 @@ class Format(_FormatLike):
|
||||||
|
|
||||||
|
|
||||||
class Enum(_FormatLike):
|
class Enum(_FormatLike):
|
||||||
def __init__(self, value, /, variants):
|
def __init__(self, value, /, variants, *, name=None):
|
||||||
self._value = Value.cast(value)
|
self._value = Value.cast(value)
|
||||||
|
if name is not None and not isinstance(name, str):
|
||||||
|
raise TypeError(f"Enum name must be a string or None, not {name!r}")
|
||||||
|
self._name = name
|
||||||
if isinstance(variants, EnumMeta):
|
if isinstance(variants, EnumMeta):
|
||||||
self._variants = {Const.cast(member.value).value: member.name for member in variants}
|
self._variants = {Const.cast(member.value).value: member.name for member in variants}
|
||||||
else:
|
else:
|
||||||
|
@ -2796,7 +2799,8 @@ class Format(_FormatLike):
|
||||||
f" ({val!r} {name!r})"
|
f" ({val!r} {name!r})"
|
||||||
for val, name in self._variants.items()
|
for val, name in self._variants.items()
|
||||||
)
|
)
|
||||||
return f"(format-enum {self._value!r}{variants})"
|
name = "-" if self._name is None else repr(self._name)
|
||||||
|
return f"(format-enum {self._value!r} {name}{variants})"
|
||||||
|
|
||||||
|
|
||||||
class Struct(_FormatLike):
|
class Struct(_FormatLike):
|
||||||
|
|
|
@ -179,7 +179,7 @@ class EnumType(ShapeCastable, py_enum.EnumMeta):
|
||||||
def format(cls, value, format_spec):
|
def format(cls, value, format_spec):
|
||||||
if format_spec != "":
|
if format_spec != "":
|
||||||
raise ValueError(f"Format specifier {format_spec!r} is not supported for enums")
|
raise ValueError(f"Format specifier {format_spec!r} is not supported for enums")
|
||||||
return Format.Enum(value, cls)
|
return Format.Enum(value, cls, name=cls.__name__)
|
||||||
|
|
||||||
def _value_repr(cls, value):
|
def _value_repr(cls, value):
|
||||||
yield Repr(FormatEnum(cls), value)
|
yield Repr(FormatEnum(cls), value)
|
||||||
|
|
|
@ -1740,7 +1740,7 @@ class FormatEnumTestCase(FHDLTestCase):
|
||||||
def test_construct(self):
|
def test_construct(self):
|
||||||
a = Signal(3)
|
a = Signal(3)
|
||||||
fmt = Format.Enum(a, {1: "A", 2: "B", 3: "C"})
|
fmt = Format.Enum(a, {1: "A", 2: "B", 3: "C"})
|
||||||
self.assertRepr(fmt, "(format-enum (sig a) (1 'A') (2 'B') (3 'C'))")
|
self.assertRepr(fmt, "(format-enum (sig a) - (1 'A') (2 'B') (3 'C'))")
|
||||||
self.assertRepr(Format("{}", fmt), """
|
self.assertRepr(Format("{}", fmt), """
|
||||||
(format '{:s}' (switch-value (sig a)
|
(format '{:s}' (switch-value (sig a)
|
||||||
(case 001 (const 8'd65))
|
(case 001 (const 8'd65))
|
||||||
|
@ -1755,8 +1755,8 @@ class FormatEnumTestCase(FHDLTestCase):
|
||||||
B = 3
|
B = 3
|
||||||
C = 4
|
C = 4
|
||||||
|
|
||||||
fmt = Format.Enum(a, MyEnum)
|
fmt = Format.Enum(a, MyEnum, name="MyEnum")
|
||||||
self.assertRepr(fmt, "(format-enum (sig a) (0 'A') (3 'B') (4 'C'))")
|
self.assertRepr(fmt, "(format-enum (sig a) 'MyEnum' (0 'A') (3 'B') (4 'C'))")
|
||||||
self.assertRepr(Format("{}", fmt), """
|
self.assertRepr(Format("{}", fmt), """
|
||||||
(format '{:s}' (switch-value (sig a)
|
(format '{:s}' (switch-value (sig a)
|
||||||
(case 000 (const 8'd65))
|
(case 000 (const 8'd65))
|
||||||
|
@ -1774,6 +1774,9 @@ class FormatEnumTestCase(FHDLTestCase):
|
||||||
with self.assertRaisesRegex(TypeError,
|
with self.assertRaisesRegex(TypeError,
|
||||||
r"^Variant names must be strings, not 123$"):
|
r"^Variant names must be strings, not 123$"):
|
||||||
Format.Enum(a, {1: 123})
|
Format.Enum(a, {1: 123})
|
||||||
|
with self.assertRaisesRegex(TypeError,
|
||||||
|
r"^Enum name must be a string or None, not 123$"):
|
||||||
|
Format.Enum(a, {}, name=123)
|
||||||
|
|
||||||
|
|
||||||
class FormatStructTestCase(FHDLTestCase):
|
class FormatStructTestCase(FHDLTestCase):
|
||||||
|
|
|
@ -320,3 +320,13 @@ class EnumTestCase(FHDLTestCase):
|
||||||
A = 1
|
A = 1
|
||||||
B = py_enum.member(2)
|
B = py_enum.member(2)
|
||||||
self.assertIs(2, EnumB.B.value)
|
self.assertIs(2, EnumB.B.value)
|
||||||
|
|
||||||
|
def test_format(self):
|
||||||
|
class EnumA(Enum, shape=unsigned(2)):
|
||||||
|
A = 0
|
||||||
|
B = 1
|
||||||
|
|
||||||
|
sig = Signal(EnumA)
|
||||||
|
self.assertRepr(EnumA.format(sig, ""), """
|
||||||
|
(format-enum (sig sig) 'EnumA' (0 'A') (1 'B'))
|
||||||
|
""")
|
||||||
|
|
Loading…
Reference in a new issue