Skip to content

Commit 5e2f3b7

Browse files
zypwhitequark
authored andcommitted
Implement RFC 42: Const from shape-castable.
1 parent 089213e commit 5e2f3b7

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

amaranth/hdl/_ast.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -839,8 +839,15 @@ def _rhs_signals(self):
839839
raise NotImplementedError # :nocov:
840840

841841

842+
class _ConstMeta(ABCMeta):
843+
def __call__(cls, value, shape=None, src_loc_at=0, **kwargs):
844+
if isinstance(shape, ShapeCastable):
845+
return shape.const(value)
846+
return super().__call__(value, shape, **kwargs, src_loc_at=src_loc_at + 1)
847+
848+
842849
@final
843-
class Const(Value):
850+
class Const(Value, metaclass=_ConstMeta):
844851
"""A constant, literal integer value.
845852
846853
Parameters
@@ -898,7 +905,7 @@ def __init__(self, value, shape=None, *, src_loc_at=0):
898905
"shape {!r}; this is likely an off-by-one error"
899906
.format(self.value, shape),
900907
category=SyntaxWarning,
901-
stacklevel=2)
908+
stacklevel=3)
902909
shape = Shape.cast(shape, src_loc_at=1 + src_loc_at)
903910
self.width = shape.width
904911
self.signed = shape.signed

tests/test_hdl_ast.py

+19
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,25 @@ def test_hash(self):
470470
with self.assertRaises(TypeError):
471471
hash(Const(0))
472472

473+
def test_shape_castable(self):
474+
class MockConstValue:
475+
def __init__(self, value):
476+
self.value = value
477+
478+
class MockConstShape(ShapeCastable):
479+
def as_shape(self):
480+
return unsigned(8)
481+
482+
def __call__(self, value):
483+
return value
484+
485+
def const(self, init):
486+
return MockConstValue(init)
487+
488+
s = Const(10, MockConstShape())
489+
self.assertIsInstance(s, MockConstValue)
490+
self.assertEqual(s.value, 10)
491+
473492

474493
class OperatorTestCase(FHDLTestCase):
475494
def test_bool(self):

0 commit comments

Comments
 (0)