hdl.rec: respect modifications to signals in Record.like().
Fixes #126.
This commit is contained in:
		
							parent
							
								
									bfbeca4584
								
							
						
					
					
						commit
						0ab0a74ec1
					
				|  | @ -77,16 +77,32 @@ class Layout: | ||||||
| # Unlike most Values, Record *can* be subclassed. | # Unlike most Values, Record *can* be subclassed. | ||||||
| class Record(Value): | class Record(Value): | ||||||
|     @classmethod |     @classmethod | ||||||
|     def like(cls, other, name=None, name_suffix=None, src_loc_at=0): |     def like(cls, other, *, name=None, name_suffix=None, src_loc_at=0): | ||||||
|         if name is not None: |         if name is not None: | ||||||
|             new_name = str(name) |             new_name = str(name) | ||||||
|         elif name_suffix is not None: |         elif name_suffix is not None: | ||||||
|             new_name = other.name + str(name_suffix) |             new_name = other.name + str(name_suffix) | ||||||
|         else: |         else: | ||||||
|             new_name = tracer.get_var_name(depth=2 + src_loc_at, default=None) |             new_name = tracer.get_var_name(depth=2 + src_loc_at, default=None) | ||||||
|         return cls(other.layout, new_name) |  | ||||||
| 
 | 
 | ||||||
|     def __init__(self, layout, name=None, src_loc_at=0, *, fields=None): |         def concat(a, b): | ||||||
|  |             if a is None: | ||||||
|  |                 return b | ||||||
|  |             return "{}__{}".format(a, b) | ||||||
|  | 
 | ||||||
|  |         fields = {} | ||||||
|  |         for field_name in other.fields: | ||||||
|  |             field = other[field_name] | ||||||
|  |             if isinstance(field, Record): | ||||||
|  |                 fields[field_name] = Record.like(field, name=concat(new_name, field_name), | ||||||
|  |                                                  src_loc_at=1 + src_loc_at) | ||||||
|  |             else: | ||||||
|  |                 fields[field_name] = Signal.like(field, name=concat(new_name, field_name), | ||||||
|  |                                                  src_loc_at=1 + src_loc_at) | ||||||
|  | 
 | ||||||
|  |         return cls(other.layout, new_name, fields=fields, src_loc_at=1) | ||||||
|  | 
 | ||||||
|  |     def __init__(self, layout, name=None, *, fields=None, src_loc_at=0): | ||||||
|         if name is None: |         if name is None: | ||||||
|             name = tracer.get_var_name(depth=2 + src_loc_at, default=None) |             name = tracer.get_var_name(depth=2 + src_loc_at, default=None) | ||||||
| 
 | 
 | ||||||
|  | @ -111,10 +127,10 @@ class Record(Value): | ||||||
|             else: |             else: | ||||||
|                 if isinstance(field_shape, Layout): |                 if isinstance(field_shape, Layout): | ||||||
|                     self.fields[field_name] = Record(field_shape, name=concat(name, field_name), |                     self.fields[field_name] = Record(field_shape, name=concat(name, field_name), | ||||||
|                                                      src_loc_at=src_loc_at + 1) |                                                      src_loc_at=1 + src_loc_at) | ||||||
|                 else: |                 else: | ||||||
|                     self.fields[field_name] = Signal(field_shape, name=concat(name, field_name), |                     self.fields[field_name] = Signal(field_shape, name=concat(name, field_name), | ||||||
|                                                      src_loc_at=src_loc_at + 1) |                                                      src_loc_at=1 + src_loc_at) | ||||||
| 
 | 
 | ||||||
|     def __getattr__(self, name): |     def __getattr__(self, name): | ||||||
|         return self[name] |         return self[name] | ||||||
|  |  | ||||||
|  | @ -151,6 +151,20 @@ class RecordTestCase(FHDLTestCase): | ||||||
|         r4 = Record.like(r1, name_suffix="foo") |         r4 = Record.like(r1, name_suffix="foo") | ||||||
|         self.assertEqual(r4.name, "r1foo") |         self.assertEqual(r4.name, "r1foo") | ||||||
| 
 | 
 | ||||||
|  |     def test_like_modifications(self): | ||||||
|  |         r1 = Record([("a", 1), ("b", [("s", 1)])]) | ||||||
|  |         self.assertEqual(r1.a.name, "r1__a") | ||||||
|  |         self.assertEqual(r1.b.name, "r1__b") | ||||||
|  |         self.assertEqual(r1.b.s.name, "r1__b__s") | ||||||
|  |         r1.a.reset = 1 | ||||||
|  |         r1.b.s.reset = 1 | ||||||
|  |         r2 = Record.like(r1) | ||||||
|  |         self.assertEqual(r2.a.reset, 1) | ||||||
|  |         self.assertEqual(r2.b.s.reset, 1) | ||||||
|  |         self.assertEqual(r2.a.name, "r2__a") | ||||||
|  |         self.assertEqual(r2.b.name, "r2__b") | ||||||
|  |         self.assertEqual(r2.b.s.name, "r2__b__s") | ||||||
|  | 
 | ||||||
|     def test_slice_tuple(self): |     def test_slice_tuple(self): | ||||||
|         r1 = Record([("a", 1), ("b", 2), ("c", 3)]) |         r1 = Record([("a", 1), ("b", 2), ("c", 3)]) | ||||||
|         r2 = r1["a", "c"] |         r2 = r1["a", "c"] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 whitequark
						whitequark