return selectconcat(*[self.si[x] for x in key])
elif isinstance(key, (tuple, list, range)):
return FieldSelectableInt(si=self, br=key)
+ else:
+ raise ValueError(key)
def __setitem__(self, key, value):
if isinstance(key, SelectableInt):
self.si[k] = value[i]
def __negate__(self):
- return self._op1(negate)
+ return self._op1(neg)
def __invert__(self):
return self._op1(inv)
return True
return False
+ def __int__(self):
+ return self.asint(msb0=True)
+
def asint(self, msb0=False):
res = 0
brlen = len(self.br)
value = (self.value >> start) & mask
log("getitem", stop, start, self.bits, hex(self.value), value)
return SelectableInt(value, bits)
+ else:
+ bits = []
+ key = tuple(key)
+ for bit in key:
+ if not isinstance(bit, (int, SelectableInt)):
+ raise ValueError(key)
+ bits.append(self[bit])
+ return selectconcat(*bits)
def __setitem__(self, key, value):
if isinstance(key, SelectableInt):
mask = ((1 << bits) - 1) << start
value = value << start
self.value = (self.value & ~mask) | (value & mask)
+ else:
+ raise ValueError(key)
def __ge__(self, other):
if isinstance(other, FieldSelectableInt):
return struct.unpack('<d', data)[0]
-class SelectableIntMappingMeta(type):
- class Field(tuple):
- def __call__(self, si):
- return FieldSelectableInt(si=si, br=self)
-
- class FieldMapping(dict):
- def __init__(self, items):
- if isinstance(items, dict):
- items = items.items()
-
- length = 0
- mapping = {}
- Field = SelectableIntMappingMeta.Field
- for (key, value) in items:
- field = Field(value)
- mapping[key] = field
- length = max(length, len(field))
-
- self.__length = length
-
- return super().__init__(mapping)
-
- def __iter__(self):
- yield from self.items()
-
- def __len__(self):
- return self.__length
-
- def __call__(self, si):
- return {key:value(si=si) for (key, value) in self}
-
- def __new__(metacls, name, bases, attrs):
- mapping = {}
- valid = False
- for base in reversed(bases):
- if issubclass(base.__class__, metacls):
- mapping.update(base)
- if not valid and issubclass(base, SelectableInt):
- valid = True
- if not valid:
- raise ValueError(bases)
-
- for (key, value) in tuple(attrs.items()):
- if key.startswith("_"):
- continue
- if isinstance(value, dict):
- value = metacls.FieldMapping(value)
- elif isinstance(value, (list, tuple, range)):
- value = metacls.Field(value)
- else:
- continue
- mapping[key] = value
- attrs[key] = value
-
- length = 0
- for (key, value) in mapping.items():
- length = max(length, len(value))
-
- cls = super().__new__(metacls, name, bases, attrs)
- cls.__length = length
- cls.__mapping = mapping
-
- return cls
-
- def __len__(cls):
- return cls.__length
-
- def __contains__(cls, key):
- return cls.__mapping.__contains__(key)
-
- def __getitem__(cls, key):
- return cls.__mapping.__getitem__(key)
-
- def __iter__(cls):
- yield from cls.__mapping.items()
- if type(cls) is not SelectableIntMappingMeta:
- yield from super().__iter__()
-
-
-class SelectableIntMapping(SelectableInt, metaclass=SelectableIntMappingMeta):
- def __init__(self, value=0, bits=None):
- if isinstance(value, SelectableInt):
- value = value.value
- if bits is None:
- bits = len(self.__class__)
- if bits != len(self.__class__):
- raise ValueError(bits)
-
- return super().__init__(value=value, bits=bits)
-
- def __iter__(self):
- for (name, _) in self.__class__:
- yield (name, getattr(self, name))
-
- def __getattribute__(self, attr):
- if (attr != "__class__") and (attr in self.__class__):
- return self.__class__[attr](si=self)
- return super().__getattribute__(attr)
-
-
def onebit(bit):
return SelectableInt(1 if bit else 0, 1)