Skip to content

fix(codegen): annotator only caches truly-static expression types; unblocks typeOf consumer migrations#580

Merged
cs01 merged 1 commit intomainfrom
fix/annotator-skip-context-dependent
Apr 20, 2026
Merged

fix(codegen): annotator only caches truly-static expression types; unblocks typeOf consumer migrations#580
cs01 merged 1 commit intomainfrom
fix/annotator-skip-context-dependent

Conversation

@cs01
Copy link
Copy Markdown
Owner

@cs01 cs01 commented Apr 20, 2026

Root-cause fix. The AST type annotator (src/semantic/type-annotator.ts) was populating the typeOf cache for every expression pre-codegen. But arrays/binary/conditional/new/object/map/set/type_assertion expressions recurse into the symbol table (isString, getType) whose answers only exist mid-codegen. Cached pre-codegen → stale wrong answer; downstream consumers reading base/arrayDepth from that cached rich object got misclassified types → native IR type mismatches.

Diagnostic trail: the previous attempt to migrate variable-allocator (PR #578 rollback) failed with '%N' defined with type 'double' but expected 'ptr' on stage 1 self-compile. Side-effect test showed calling typeOf+discarding worked; using its return broke — proved the returned value was wrong, not a side effect. Instrumentation side-by-side (typeOf vs flat) found 397 divergences: 342 array (number[] vs string[]), 29 conditional, 26 binary. All caused by annotator caching with empty symbol table.

Fix: shrink annotator's cache-set to truly-static types (number/string/template_literal/boolean/null/regex). Everything else resolves live via typeOf's fallback to resolveExpressionTypeRich.

Also in this PR: variable-allocator.ts uses typeOf() at the decl-type site — was rolled back in #578 due to this bug; now safe with the annotator fix. Pattern for future consumer migrations is now sound.

Test plan:

  • Stage 0 native compile of src/chad-native.ts — clean
  • Full npm run verify (stage 0/1/2 + tests) — Verification PASSED
  • CI green

🤖 Generated with Claude Code

…blocks typeof consumer migrations (array/binary/conditional recurse through symbol table set mid-codegen)
@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results (Linux x86-64)

Benchmark C ChadScript Go Node Place
Cold Start 1.1ms 0.9ms 1.3ms 28.0ms 🥇
Fibonacci 0.814s 0.765s 1.559s 3.160s 🥇
Hash Map Lookup 0.090s 0.063s 0.091s 0.112s 🥇
Binary Trees 1.456s 1.294s 2.755s 1.181s 🥈
File I/O 0.119s 0.093s 0.086s 0.207s 🥈
JSON Parse/Stringify 0.035s 0.052s 0.175s 0.136s 🥈
N-Body Simulation 1.666s 2.119s 2.202s 2.390s 🥈
Regex Match 0.016s 0.005s 0.021s 0.004s 🥈
SQLite 0.051s 0.365s 0.490s 0.419s 🥈
Monte Carlo Pi 0.389s 0.410s 0.405s 2.248s 🥉
Quicksort 0.215s 0.247s 0.213s 0.262s 🥉
Sieve of Eratosthenes 0.015s 0.026s 0.020s 0.040s 🥉
String Manipulation 0.008s 0.019s 0.016s 0.036s 🥉
Matrix Multiply 0.445s 0.740s 0.564s 0.381s #4

CLI Tool Benchmarks

Benchmark ChadScript grep node xxd Place
Hex Dump 0.558s 1.059s 0.131s 🥈
Recursive Grep 0.020s 0.010s 0.103s 🥈

@cs01 cs01 merged commit 677bea1 into main Apr 20, 2026
19 of 21 checks passed
@cs01 cs01 deleted the fix/annotator-skip-context-dependent branch April 20, 2026 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant