_ = (args, kwargs)
def __binary_operator(self, op, other):
- span = self.__class__.span
+ span = dict.fromkeys(self.__class__.span).keys()
lhs = _selectconcat(*(self.storage[bit] for bit in span))
- if isinstance(other, Field):
- bits = len(other.__class__)
- value = int(other)
- rhs = _SelectableInt(value=value, bits=bits)
+ if isinstance(other, Reference):
+ span = dict.fromkeys(other.__class__.span).keys()
+ rhs = _selectconcat(*(other.storage[bit] for bit in span))
elif isinstance(other, int):
bits = len(self.__class__)
if other.bit_length() > bits:
return super().__new__(metacls, clsname, bases, ns)
- def __getitem__(cls, size):
- clsname = f"{cls.__name__}[{size}]"
- items = ((Field,) * size)
- return ArrayMeta(clsname, (Array,), {}, items=items)
-
def __repr__(cls):
if not cls.__members__:
return cls.__name__
def __len__(cls):
return len(cls.__members__)
- @property
- def span(cls):
- return cls.__members__
+ def __getitem__(cls, selector):
+ if isinstance(selector, int):
+ selector = (selector,)
+
+ items = []
+ for idx in selector:
+ if not isinstance(idx, int):
+ raise ValueError(selector)
+ item = cls.__members__[idx]
+ items.append(item)
+
+ return cls.__class__(cls.__name__, (Field,), {}, items=items)
def remap(cls, scheme):
if isinstance(scheme, type) and issubclass(scheme, Mapping):
return cls.__class__(cls.__name__, (cls,), {}, items=items)
+ @property
+ def span(cls):
+ return cls.__members__
+
+ def traverse(cls, path):
+ yield (path, cls.__members__)
+
class Field(Reference, metaclass=FieldMeta):
def __len__(self):
length += len(field)
return length
+ def __getitem__(cls, size):
+ clsname = f"{cls.__name__}[{size}]"
+ items = ((Field,) * size)
+ return ArrayMeta(clsname, (Array,), {}, items=items)
+
def remap(cls, scheme):
scheme_md = []
scheme_sd = []
for field in cls.__members__:
yield from field.span
+ def traverse(cls, path=""):
+ for (idx, field) in cls:
+ yield from field.traverse(path=f"{path}[{idx}]")
+
class Array(Reference, metaclass=ArrayMeta):
def __init__(self, storage):
length = max(length, len(field))
return length
+ def __getitem__(cls, selector):
+ best_min = 0
+ best_max = 0
+ for field in cls.__members__.values():
+ length = len(field)
+ best_min = min(best_min, length)
+ best_max = max(best_max, length)
+
+ items = tuple(range(best_min, best_max))
+ field = FieldMeta(cls.__name__, (Field,), {}, items=items)
+
+ return field[selector]
+
def remap(cls, scheme):
ns = {}
annotations = {}
for field in cls.__members__.values():
yield from field.span
+ def traverse(cls, path=""):
+ for (name, field) in cls:
+ if name == "_":
+ yield from field.traverse(path=path)
+ elif path == "":
+ yield from field.traverse(path=name)
+ else:
+ yield from field.traverse(path=f"{path}.{name}")
+
class Mapping(Reference, metaclass=MappingMeta):
def __init__(self, storage, **kwargs):