from __future__ import annotations from typing import Union, Optional class Range: def __init__(self, start: int, end: int, name: str, description: str = "", values: Optional[dict[str, Union[str, dict]]] = None, dependsOn: Optional[tuple[int, int]] = None) -> None: self.start: int = start self.end: int = end self.name: str = name self.description: str = description self.values: Optional[dict[str, Union[str, dict]]] = values self.dependsOn: Optional[tuple[int, int]] = dependsOn self.lastValueY: int = -1 @property def bits(self) -> int: return self.end - self.start + 1 @staticmethod def load(start: int, end: int, data: dict) -> Range: values = None bits = end - start + 1 if "values" in data: values = {} for val, desc in data["values"].items(): val = str(val).zfill(bits) values[val] = desc dependsOn = data.get("depends-on", None) if dependsOn is not None: dependsOn = Range.parseSpan(str(dependsOn)) return Range(start, end, str(data["name"]), data.get("description", ""), values, dependsOn) @staticmethod def parseSpan(span: str) -> tuple[int, int]: startEnd = span.split("-") if len(startEnd) == 1: startEnd.append(startEnd[0]) start = int(startEnd[1]) end = int(startEnd[0]) return (start, end)