feat(runtime): float_to_bits/bits_to_float as real codegen builtins (… #30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # codegen-bootstrap-sync.yml — regen-desync gate (PR #1287 §1 follow-up). | |
| # | |
| # FAILS if any `hexa_<sym>(` C-call shape referenced inside a STRING | |
| # LITERAL of `self/codegen.hexa` is NOT present in the committed | |
| # bootstrap transpiler `self/native/hexa_cc.c`. That divergence means | |
| # a contributor added a direct-call mapping to codegen.hexa but did | |
| # not run `hexa cc --regen` + commit the regenerated hexa_cc.c, so a | |
| # clean `hexa cc` (non-regen) on a fresh checkout emits the OLD | |
| # carrier-form (`hexa_call1(<sym>, ...)`) instead of the new direct | |
| # call. The runtime exposes ONLY the direct symbol -> downstream | |
| # clang link fails with `error: use of undeclared identifier '<sym>'`. | |
| # | |
| # The desync class that prompted this gate (#1187 farr32 mappings on | |
| # codegen.hexa, 0 `hexa_farr32_*` on hexa_cc.c) was caught and | |
| # regenerated in #1291. This gate prevents recurrence for the entire | |
| # direct-call surface (~384 distinct hexa_<sym>( shapes today). | |
| # | |
| # How to fix a failing gate: | |
| # 1. cd <repo> | |
| # 2. hexa cc --regen (regenerates self/native/hexa_cc.c) | |
| # 3. git add self/native/hexa_cc.c | |
| # 4. git commit -m "regen(self/native): hexa_cc.c — sync with codegen.hexa" | |
| # | |
| # Trigger: any change touching either codegen.hexa or hexa_cc.c. | |
| # No build needed — pure grep diff (~1 second runtime). | |
| name: codegen-bootstrap-sync | |
| on: | |
| push: | |
| paths: | |
| - 'self/codegen.hexa' | |
| - 'self/native/hexa_cc.c' | |
| pull_request: | |
| paths: | |
| - 'self/codegen.hexa' | |
| - 'self/native/hexa_cc.c' | |
| permissions: | |
| contents: read | |
| jobs: | |
| codegen-bootstrap-sync: | |
| name: codegen.hexa direct-calls -> hexa_cc.c (regen desync gate) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Gate -- every hexa_<sym>( in codegen.hexa string literals must exist in hexa_cc.c | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| python3 <<'PY' | |
| import re, sys | |
| cg_path = 'self/codegen.hexa' | |
| cc_path = 'self/native/hexa_cc.c' | |
| with open(cg_path, encoding='utf-8') as f: | |
| cg = f.read() | |
| with open(cc_path, encoding='utf-8') as f: | |
| cc = f.read() | |
| # Extract every `hexa_<symbol>(` shape that appears INSIDE a | |
| # string literal of codegen.hexa. The §1 desync class is | |
| # specifically string-emitted direct-call mappings (e.g. | |
| # `return "hexa_farr32_zeros(" + a0 + ")"`). Comments and | |
| # identifiers in the hexa source itself are excluded. | |
| str_lits = re.findall(r'"([^"\\]*(?:\\.[^"\\]*)*)"', cg) | |
| syms = set() | |
| for s in str_lits: | |
| for m in re.findall(r'hexa_[a-zA-Z_0-9]+(?=\()', s): | |
| syms.add(m) | |
| missing = sorted(s for s in syms if s not in cc) | |
| print(f"codegen.hexa string-literals reference {len(syms)} distinct hexa_<sym>( call shapes") | |
| print(f"hexa_cc.c size: {len(cc)} bytes") | |
| if missing: | |
| print(f"::error::regen desync: {len(missing)} hexa_<sym>( call shape(s) in codegen.hexa not present in hexa_cc.c") | |
| print(" Bootstrap transpiler is STALE — run `hexa cc --regen` and commit self/native/hexa_cc.c.") | |
| print(" Missing symbols:") | |
| for s in missing: | |
| print(f" - {s}") | |
| sys.exit(1) | |
| print("OK: every codegen.hexa direct-call symbol is present in hexa_cc.c (regen in sync)") | |
| PY |