feat(opcodes): register full AGE opcode ABI

This commit is contained in:
gamer147
2026-07-28 22:21:40 -04:00
parent 8f84f0b083
commit 77c7b85612
8 changed files with 6682 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Generator + linter for the living opcode reference (vm-map/opcodes.toml).
--bootstrap seed skeletons for every used opcode (append-only; preserves hand edits)
--bootstrap-age seed compatibility stubs for every opcode in the broader AGE catalog
--build emit age_opcodes_himegari.py + build/opcodes.json + docs/opcode-reference.md + build/opcode-coverage.md
--lint run the linter, print errors/warnings, exit nonzero on errors
See docs/superpowers/specs/2026-07-06-opcode-reference-design.md."""
@@ -77,14 +78,22 @@ def scan_corpus():
def _is_named(label: str) -> bool:
return not (label.startswith("u00") or label == "dev_ukn" or label.startswith("?"))
def skeleton_toml(op: int, label: str, argc: int, argtypes_for_op: dict) -> str:
def skeleton_toml(op: int, label: str, argc: int, argtypes_for_op: dict,
*, observed_in_himegari: bool = True) -> str:
conf = "med" if _is_named(label) else "low"
lines = ["[[opcode]]", f"op = 0x{op:x}", f'label = "{label}"', f"argc = {argc}",
'abi_source = "kelebek+decode-validated"', "", "[opcode.semantics]",
f'name = "{label}"', 'category = "unknown"', 'summary = ""',
abi_source = "kelebek+decode-validated" if observed_in_himegari else "kelebek"
summary = ("" if observed_in_himegari else
"Broader AGE-catalog compatibility stub; the port currently traces and skips it.")
evidence = ("" if observed_in_himegari else
"Not observed in Himegari's script corpus; ABI label/argc come from Kelebek's AGE table.")
lines = ["[[opcode]]", f"op = 0x{op:x}", f'label = "{label}"', f"argc = {argc}"]
if not observed_in_himegari:
lines.append("observed_in_himegari = false")
lines += [f'abi_source = "{abi_source}"', "", "[opcode.semantics]",
f'name = "{label}"', 'category = "unknown"', f'summary = "{summary}"',
"noop_headless = false", 'source = "kelebek"', f'confidence = "{conf}"',
"depends_on = []", 'evidence = ""']
for i in range(argc):
"depends_on = []", f'evidence = "{evidence}"']
for i in range(argc if observed_in_himegari else 0):
tnames = [TYPE_NAMES.get(t, "t%#x" % t) for t in sorted(argtypes_for_op.get(i, ()))]
obs = ", ".join('"%s"' % n for n in tnames)
lines += ["", "[[opcode.semantics.args]]", f"i = {i + 1}", 'role = ""',
@@ -107,6 +116,22 @@ def bootstrap(toml_path: Path) -> None:
f.write("\n".join(blocks))
print(f"bootstrap: {len(used)} used opcodes; appended {len(blocks)} new skeletons -> {toml_path}")
def bootstrap_age(toml_path: Path) -> None:
"""Append compatibility stubs for catalog opcodes absent from the canonical map."""
present = set(M.load(toml_path).opcodes) if toml_path.exists() else set()
blocks = [
skeleton_toml(op, label, argc, {}, observed_in_himegari=False)
for op, (label, argc) in sorted(OPCODES.items())
if op not in present
]
if not toml_path.exists():
toml_path.parent.mkdir(parents=True, exist_ok=True)
toml_path.write_text(META_TOML + "\n", encoding="utf-8")
with toml_path.open("a", encoding="utf-8") as f:
f.write("\n".join(blocks))
print(f"bootstrap-age: {len(OPCODES)} catalog opcodes; "
f"appended {len(blocks)} compatibility stubs -> {toml_path}")
GEN_HEADER = "# DO NOT EDIT -- generated from vm-map/opcodes.toml by tools/opcodes_build.py --build\n"
def emit_inferred_py(model: M.Model) -> str:
@@ -128,6 +153,7 @@ def emit_json(model: M.Model) -> str:
"dependents": {"0x%x" % k: ["0x%x" % d for d in v] for k, v in rev.items() if v}}
for op, oc in sorted(model.opcodes.items()):
e = {"op": "0x%x" % op, "label": oc.label, "argc": oc.argc,
"observed_in_himegari": oc.observed_in_himegari,
"code_target_args": oc.code_target_args, "abi_source": oc.abi_source}
s = oc.semantics
if s:
@@ -140,9 +166,12 @@ def emit_json(model: M.Model) -> str:
def emit_reference_md(model: M.Model) -> str:
rev = M.dependents(model)
observed = sum(oc.observed_in_himegari for oc in model.opcodes.values())
catalog_only = len(model.opcodes) - observed
L = ["<!-- DO NOT EDIT -- generated from vm-map/opcodes.toml by tools/opcodes_build.py --build -->",
"# Opcode Reference (generated)", "",
f"{len(model.opcodes)} opcodes used by Himegari. Source of truth: `vm-map/opcodes.toml`.", ""]
f"{len(model.opcodes)} AGE catalog opcodes: {observed} observed in Himegari and "
f"{catalog_only} compatibility stubs. Source of truth: `vm-map/opcodes.toml`.", ""]
by_cat = collections.defaultdict(list)
for op, oc in model.opcodes.items():
cat = oc.semantics.category if oc.semantics else "unknown"
@@ -182,8 +211,12 @@ def emit_coverage_md(model: M.Model) -> str:
by_cat[s.category] += 1
if s.name != oc.label:
named += 1
observed = sum(oc.observed_in_himegari for oc in model.opcodes.values())
L = ["<!-- DO NOT EDIT -- generated from vm-map/opcodes.toml -->", "# Opcode Coverage (generated)", "",
f"- opcodes: {len(model.opcodes)}", f"- given a distinct mnemonic: {named}", "",
f"- AGE catalog opcodes: {len(model.opcodes)}",
f"- observed in Himegari: {observed}",
f"- compatibility stubs: {len(model.opcodes) - observed}",
f"- given a distinct mnemonic: {named}", "",
"## by source", ""]
L += [f"- {k}: {v}" for k, v in sorted(by_src.items())]
L += ["", "## by confidence", ""] + [f"- {k}: {by_conf[k]}" for k in ("high", "med", "low")]
@@ -193,6 +226,7 @@ def emit_coverage_md(model: M.Model) -> str:
def main(argv=None):
ap = argparse.ArgumentParser()
ap.add_argument("--bootstrap", action="store_true")
ap.add_argument("--bootstrap-age", action="store_true")
ap.add_argument("--build", action="store_true")
ap.add_argument("--lint", action="store_true")
ap.add_argument("--toml", default=str(TOML_DEFAULT))
@@ -201,6 +235,9 @@ def main(argv=None):
if args.bootstrap:
bootstrap(tp)
return 0
if args.bootstrap_age:
bootstrap_age(tp)
return 0
if args.build:
model = M.load(tp)
errors, warnings = M.lint(model)
@@ -226,7 +263,7 @@ def main(argv=None):
print("error:", m)
print(f"lint: {len(errors)} errors, {len(warnings)} warnings")
return 1 if errors else 0
ap.error("no action (expected --bootstrap/--build/--lint)")
ap.error("no action (expected --bootstrap/--bootstrap-age/--build/--lint)")
if __name__ == "__main__":
sys.exit(main())

View File

@@ -29,6 +29,7 @@ class Opcode:
op: int
label: str
argc: int
observed_in_himegari: bool = True
code_target_args: list[int] = field(default_factory=list)
abi_source: str = "kelebek+decode-validated"
abi_note: str = ""
@@ -61,6 +62,7 @@ def load(path) -> Model:
)
ops[int(e["op"])] = Opcode(
op=int(e["op"]), label=e.get("label", ""), argc=int(e["argc"]),
observed_in_himegari=bool(e.get("observed_in_himegari", True)),
code_target_args=[int(x) for x in e.get("code_target_args", [])],
abi_source=e.get("abi_source", "kelebek+decode-validated"),
abi_note=e.get("abi_note", ""), semantics=sem,
@@ -73,6 +75,12 @@ def lint(model: Model) -> tuple[list[str], list[str]]:
errors: list[str] = []
warnings: list[str] = []
ops = model.opcodes
expected_observed = model.meta.get("opcodes_used_by_himegari")
actual_observed = sum(oc.observed_in_himegari for oc in ops.values())
if expected_observed is not None and int(expected_observed) != actual_observed:
errors.append(
"meta.opcodes_used_by_himegari="
f"{expected_observed} but {actual_observed} entries are marked observed")
for op, oc in sorted(ops.items()):
s = oc.semantics
if not s:

View File

@@ -118,6 +118,7 @@ def test_lint():
def test_bootstrap():
import opcodes_build as B
from age_opcodes import OPCODES
from pathlib import Path
fd, p = tempfile.mkstemp(suffix=".toml"); os.close(fd); os.remove(p)
tp = Path(p)
@@ -130,6 +131,16 @@ def test_bootstrap():
check(len(M.load(tp).opcodes) == n1, "second bootstrap adds no duplicates")
e, w = M.lint(m)
check(e == [], f"bootstrapped file lints clean (errors: {e[:3]})")
B.bootstrap_age(tp)
full = M.load(tp)
check(len(full.opcodes) == len(OPCODES), "bootstrap-age seeds the complete AGE catalog")
check(sum(o.observed_in_himegari for o in full.opcodes.values()) == len(m.opcodes),
"bootstrap-age marks only added catalog entries unobserved")
check(all(not o.semantics.noop_headless for o in full.opcodes.values()
if not o.observed_in_himegari),
"compatibility stubs are not misclassified as semantically safe no-ops")
e, w = M.lint(full)
check(e == [], f"full catalog lints clean (errors: {e[:3]})")
def test_emit_inferred():
import opcodes_build as B