build.{dsl,res}: allow removing attributes from subsignals.

This is useful when most attributes in a large composite resource
are the same, but a few signals are different, and also when building
abstractions around resources.

Fixes #128.
This commit is contained in:
whitequark 2019-07-08 10:41:45 +00:00
parent f0c1c2cfeb
commit 0b844da4cf
3 changed files with 17 additions and 6 deletions

View file

@ -92,15 +92,20 @@ def DiffPairsN(*args, **kwargs):
class Attrs(OrderedDict):
def __init__(self, **attrs):
for attr_key, attr_value in attrs.items():
if not isinstance(attr_value, str):
raise TypeError("Attribute value must be a string, not {!r}"
if not (attr_value is None or isinstance(attr_value, str)):
raise TypeError("Attribute value must be None or str, not {!r}"
.format(attr_value))
super().__init__(**attrs)
def __repr__(self):
return "(attrs {})".format(" ".join("{}={}".format(k, v)
for k, v in self.items()))
items = []
for key, value in self.items():
if value is None:
items.append("!" + key)
else:
items.append(key + "=" + value)
return "(attrs {})".format(" ".join(items))
class Clock:

View file

@ -106,9 +106,10 @@ class ResourceManager:
if isinstance(resource.ios[0], Subsignal):
fields = OrderedDict()
for sub in resource.ios:
sub_attrs = {k: v for k, v in {**attrs, **sub.attrs}.items() if v is not None}
fields[sub.name] = resolve(sub, dir[sub.name], xdr[sub.name],
name="{}__{}".format(name, sub.name),
attrs={**attrs, **sub.attrs})
attrs=sub_attrs)
return Record([
(f_name, f.layout) for (f_name, f) in fields.items()
], fields=fields, name=name)