File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -47,7 +47,7 @@ def _pt_lookup(self, field: type[Base] | Base) -> str:
4747
4848 @property
4949 @functools .lru_cache # noqa: B019
50- def _pt_fields (self ) -> dict :
50+ def _pt_fields (self ) -> dict [ Base , str ] :
5151 return {getattr (self , x ): x for x in self ._PT_DEF .keys ()}
5252
5353
@@ -136,8 +136,10 @@ def __str__(self) -> str:
136136 for fname in self ._PT_DEF .keys ():
137137 finst = getattr (self , fname )
138138 lsb , msb = self ._PT_RANGES [fname ]
139+ width = msb - lsb + 1
139140 lines .append (
140- f" - [{ msb :{max_bits }} :{ lsb :{max_bits }} ] { fname :{max_name }} = 0x{ int (finst ):X} "
141+ f" |- [{ msb :{max_bits }} :{ lsb :{max_bits }} ] { fname :{max_name }} "
142+ f"= 0x{ int (finst ):0{(width + 3 ) // 4 }X} "
141143 )
142144 return "\n " .join (lines )
143145
Original file line number Diff line number Diff line change @@ -15,7 +15,13 @@ def _pt_name(cls) -> str:
1515 if cls ._PT_ATTACHED_TO is not None :
1616 return cls ._PT_ATTACHED_TO ._pt_lookup (cls )
1717 else :
18- return NumericPrimitive ._pt_name (cls )
18+ return f"{ ['Unsigned' , 'Signed' ][cls ._PT_SIGNED ]} Scalar[{ cls ._PT_WIDTH } ]"
19+
20+ def __str__ (self ) -> str :
21+ return f"{ type (self )._pt_name ()} : 0x{ int (self ):0{(self ._PT_WIDTH + 3 ) // 4 }X} "
22+
23+ def __repr__ (self ):
24+ return str (self )
1925
2026
2127class Scalar (NumericPrimitive ):
Original file line number Diff line number Diff line change 33#
44
55import functools
6+ import textwrap
67
78from .array import ArraySpec
89from .assembly import Assembly
@@ -30,6 +31,19 @@ def __init__(
3031 # NOTE: Fields are not constructed at this point, instead they are filled
3132 # in lazily as they are requested by the consumer
3233
34+ def __str__ (self ) -> str :
35+ parts = {}
36+ for finst , fname in self ._pt_fields .items ():
37+ parts [fname ] = str (finst )
38+ max_prefix = max (map (len , parts .keys ()))
39+ return f"{ type (self ).__name__ } : 0x{ int (self ):X} (union):\n " + "\n " .join (
40+ (f" |- { p :{max_prefix }s} -> " + textwrap .indent (v , " " * (max_prefix + 8 )).lstrip ())
41+ for p , v in parts .items ()
42+ )
43+
44+ def __repr__ (self ) -> str :
45+ return self .__str__ ()
46+
3347 def __getattribute__ (self , fname : str ):
3448 # Attempt to resolve the attribute from existing properties
3549 try :
Original file line number Diff line number Diff line change @@ -94,10 +94,18 @@ class TestStruct:
9494 cd : Scalar [3 ]
9595 ef : Scalar [9 ]
9696
97- inst = TestStruct ._pt_unpack ((39 << 15 ) | (5 << 12 ) | 123 )
98- assert inst .ab .value == 123
99- assert inst .cd .value == 5
100- assert inst .ef .value == 39
97+ value = (39 << 15 ) | (5 << 12 ) | 123
98+ inst = TestStruct ._pt_unpack (value )
99+ assert inst .ab .value == (ab_value := 123 )
100+ assert inst .cd .value == (cd_value := 5 )
101+ assert inst .ef .value == (ef_value := 39 )
102+
103+ assert str (inst ) == (
104+ f"TestStruct: 0x{ value :06X} \n "
105+ f" |- [11: 0] ab = 0x{ ab_value :03X} \n "
106+ f" |- [14:12] cd = 0x{ cd_value :01X} \n "
107+ f" |- [23:15] ef = 0x{ ef_value :03X} "
108+ )
101109
102110
103111def test_struct_unpacking_from_msb ():
Original file line number Diff line number Diff line change @@ -140,12 +140,27 @@ class Packet:
140140 raw : Scalar [32 ]
141141 header : Header
142142
143- inst = Packet ._pt_unpack ((0x7 << 28 ) | (0x5 << 24 ) | (0x75 << 16 ) | 0x1234 )
144- assert int (inst .raw ) == (0x7 << 28 ) | (0x5 << 24 ) | (0x75 << 16 ) | 0x1234
145- assert int (inst .header .address ) == 0x1234
146- assert int (inst .header .length ) == 0x75
147- assert int (inst .header .mode ) == 0x5
148- assert int (inst .header .flags ) == 0x7
143+ hdr_addr_val = 0x1234
144+ hdr_len_val = 0x75
145+ hdr_mode_val = 0x5
146+ hdr_flags_val = 0x7
147+ value = (hdr_flags_val << 28 ) | (hdr_mode_val << 24 ) | (hdr_len_val << 16 ) | hdr_addr_val
148+ inst = Packet ._pt_unpack (value )
149+ assert int (inst .raw ) == value
150+ assert int (inst .header .address ) == hdr_addr_val
151+ assert int (inst .header .length ) == hdr_len_val
152+ assert int (inst .header .mode ) == hdr_mode_val
153+ assert int (inst .header .flags ) == hdr_flags_val
154+
155+ assert str (inst ) == (
156+ f"Packet: 0x{ value :08X} (union):\n "
157+ f" |- raw -> Unsigned Scalar[32]: 0x{ value :08X} \n "
158+ f" |- header -> Header: 0x{ value :08X} \n "
159+ f" |- [15: 0] address = 0x{ hdr_addr_val :04X} \n "
160+ f" |- [23:16] length = 0x{ hdr_len_val :02X} \n "
161+ f" |- [27:24] mode = 0x{ hdr_mode_val :01X} \n "
162+ f" |- [31:28] flags = 0x{ hdr_flags_val :01X} "
163+ )
149164
150165
151166def test_union_bad_widths ():
You can’t perform that action at this time.
0 commit comments