Download src/python/tomagi/format.py from c0mbatduckzz/TOMK: direct link, hf CLI and curl.
- Browser
- Download file 2.35 kB
-
https://huggingface.co/c0mbatduckzz/TOMK/resolve/main/src/python/tomagi/format.py
- Command line
-
hf download hf://c0mbatduckzz/TOMK/src/python/tomagi/format.py
-
curl -L -o format.py https://huggingface.co/c0mbatduckzz/TOMK/resolve/main/src/python/tomagi/format.py
2.35 kB
| """Binary .tmg format for TOMAGI 1.0.""" | |
| from __future__ import annotations | |
| import struct | |
| from pathlib import Path | |
| from .core import Cell, Program, State | |
| MAGIC = b"TOMAGI1\0" | |
| VERSION_WORD = 0x00010000 | |
| HEADER_SIZE = 128 | |
| CELL_SIZE = 48 | |
| STATE_SIZE = 64 | |
| _HEADER = struct.Struct("<8s14I") # 64 bytes: magic + eight fields + six reserved | |
| _STATE = struct.Struct("<16I") | |
| _CELL = struct.Struct("<12I") | |
| def dumps(program: Program) -> bytes: | |
| header = _HEADER.pack( | |
| MAGIC, | |
| VERSION_WORD, | |
| program.flags & 0xFFFFFFFF, | |
| len(program.cells), | |
| program.entry, | |
| program.seed & 0xFFFFFFFF, | |
| program.default_ticks, | |
| CELL_SIZE, | |
| STATE_SIZE, | |
| 0, 0, 0, 0, 0, 0, | |
| ) | |
| assert len(header) == 64 | |
| state_blob = _STATE.pack(*program.initial_state.words()) | |
| cells_blob = b"".join(_CELL.pack(*cell.words()) for cell in program.cells) | |
| return header + state_blob + cells_blob | |
| def loads(data: bytes) -> Program: | |
| if len(data) < HEADER_SIZE: | |
| raise ValueError("file is shorter than the TOMAGI header") | |
| values = _HEADER.unpack_from(data, 0) | |
| magic = values[0] | |
| if magic != MAGIC: | |
| raise ValueError("not a TOMAGI 1.0 program") | |
| version, flags, count, entry, seed, ticks, cell_size, state_size = values[1:9] | |
| reserved = values[9:15] | |
| if any(reserved): | |
| raise ValueError("reserved TOMAGI header words must be zero") | |
| if version != VERSION_WORD: | |
| raise ValueError(f"unsupported TOMAGI version word 0x{version:08x}") | |
| if cell_size != CELL_SIZE or state_size != STATE_SIZE: | |
| raise ValueError("record size does not match TOMAGI 1.0") | |
| expected = HEADER_SIZE + count * CELL_SIZE | |
| if len(data) != expected: | |
| raise ValueError(f"file length {len(data)} does not match expected {expected}") | |
| state = State.from_words(_STATE.unpack_from(data, 64)) | |
| cells = [] | |
| offset = HEADER_SIZE | |
| for _ in range(count): | |
| cells.append(Cell.from_words(_CELL.unpack_from(data, offset))) | |
| offset += CELL_SIZE | |
| return Program(cells=cells, entry=entry, seed=seed, default_ticks=ticks, | |
| initial_state=state, flags=flags) | |
| def dump(program: Program, path: str | Path) -> None: | |
| Path(path).write_bytes(dumps(program)) | |
| def load(path: str | Path) -> Program: | |
| return loads(Path(path).read_bytes()) | |