Implement RFC 42: Const from shape-castable.

This commit is contained in:
Vegard Storheil Eriksen 2024-01-30 23:05:15 +01:00 committed by Catherine
parent 089213e19f
commit 5e2f3b7992
2 changed files with 28 additions and 2 deletions

View file

@ -839,8 +839,15 @@ class Value(metaclass=ABCMeta):
raise NotImplementedError # :nocov:
class _ConstMeta(ABCMeta):
def __call__(cls, value, shape=None, src_loc_at=0, **kwargs):
if isinstance(shape, ShapeCastable):
return shape.const(value)
return super().__call__(value, shape, **kwargs, src_loc_at=src_loc_at + 1)
@final
class Const(Value):
class Const(Value, metaclass=_ConstMeta):
"""A constant, literal integer value.
Parameters
@ -898,7 +905,7 @@ class Const(Value):
"shape {!r}; this is likely an off-by-one error"
.format(self.value, shape),
category=SyntaxWarning,
stacklevel=2)
stacklevel=3)
shape = Shape.cast(shape, src_loc_at=1 + src_loc_at)
self.width = shape.width
self.signed = shape.signed

View file

@ -470,6 +470,25 @@ class ConstTestCase(FHDLTestCase):
with self.assertRaises(TypeError):
hash(Const(0))
def test_shape_castable(self):
class MockConstValue:
def __init__(self, value):
self.value = value
class MockConstShape(ShapeCastable):
def as_shape(self):
return unsigned(8)
def __call__(self, value):
return value
def const(self, init):
return MockConstValue(init)
s = Const(10, MockConstShape())
self.assertIsInstance(s, MockConstValue)
self.assertEqual(s.value, 10)
class OperatorTestCase(FHDLTestCase):
def test_bool(self):