Skip to content

fix: three codegen/parser/ffi bugs (#587, #589, #591)#593

Merged
cs01 merged 3 commits intomainfrom
fix/codegen-bugs-587-589-591
Apr 20, 2026
Merged

fix: three codegen/parser/ffi bugs (#587, #589, #591)#593
cs01 merged 3 commits intomainfrom
fix/codegen-bugs-587-589-591

Conversation

@cs01
Copy link
Copy Markdown
Owner

@cs01 cs01 commented Apr 20, 2026

Summary

Three independent fixes, one commit each:

  • codegen: arrow-literal in class ctor body emits IR with missing @ sigil on lambda reference #587 (459665de02aecec1 pre-rebase) — fix(codegen): arrow literal assigned to a class field inside the ctor body was emitting store i8* __lambda_N, i8** %X (missing @ sigil). Clang rejected. Fix normalizes raw __lambda_N operands to @__lambda_N at the single class-field store site in storeFieldValueDirect. 1 file, +3 LOC (src/codegen/infrastructure/assignment-generator.ts).
  • parser: rejects arr[i](args) — ElementAccessExpression as callee #589 (887c76fc9fcf31a8 pre-rebase) — fix(parser): CallExpression visitor now accepts ElementAccessExpression as a callee alongside CallExpression/ParenthesizedExpression. Unblocks parsing arr[i](args) dispatch-table shapes (codegen still needs function-pointer array indirect-call support to run end-to-end; that's tracked separately — the parser no longer rejects the shape). 1 file, +1/-1 LOC (src/parser-ts/handlers/expressions.ts).
  • ffi: NULL char* does not reliably round-trip to empty string in TS #591 (d50c519925693fe1 pre-rebase) — fix(ffi): declare function returning a char* now round-trips NULL as the empty string. Added a select i1 (icmp eq ptr null), empty_str, result coercion at the FFI call return for declare-function i8* returns, so if (someBridge() === "") works without per-bridge _is_* probes. 1 file, +12 LOC (src/codegen/expressions/calls.ts).

Before / After

#587

class Foo {
  cb: (x: number) => number;
  constructor() { this.cb = (x) => x * 2; }
}
  • Before: store i8* __lambda_0, i8** %5 → clang error: expected value token
  • After: store i8* @__lambda_0, i8** %5 → compiles and calls correctly.

#589

const fns = [doubler, plusOne];
const a = fns[0](10);
  • Before: parser throws Unsupported call expression: ElementAccessExpression.
  • After: parser lowers to a method_call with method: "" just like existing paren/IIFE-callee shapes; downstream semantic layer now returns the real "IIFE not supported" error, making the function-array codegen gap visible and addressable as a separate follow-up.

#591

declare function getenv(name: string): string;
const v = getenv("__DOES_NOT_EXIST__");
if (v === "") { /* ok — was unreachable before */ }
  • Before: NULL char* fell into the null-vs-string branch of the === strcmp lowering and produced false (bothNull was false because "" is a real string).
  • After: NULL is coerced to the interned empty string at the FFI return, so v === "" is true.

Test files added

Verify

Full npm run verify passed on this branch before opening the PR:

  • Stage 0: native compiler built, smoke test passed
  • Stage 1 self-host: built + smoke test passed
  • Stage 2 self-host: built + smoke test passed (bit-exact oracle)
  • All fixture tests passed

Test plan

  • CI green on npm run verify
  • CI green on npm test (fixture suite picks up the three new tests)
  • Self-host stages 1 + 2 still produce bit-exact binaries

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results (Linux x86-64)

Benchmark C ChadScript Go Node Place
Cold Start 0.8ms 0.7ms 1.1ms 26.8ms 🥇
Fibonacci 0.725s 0.723s 1.430s 2.858s 🥇
Hash Map Lookup 0.099s 0.063s 0.092s 0.126s 🥇
Binary Trees 1.489s 1.477s 3.000s 1.287s 🥈
JSON Parse/Stringify 0.032s 0.044s 0.178s 0.134s 🥈
Matrix Multiply 0.432s 0.458s 0.463s 0.493s 🥈
Monte Carlo Pi 0.424s 0.430s 0.454s 1.473s 🥈
N-Body Simulation 1.430s 1.855s 1.947s 2.273s 🥈
Regex Match 0.014s 0.004s 0.021s 0.004s 🥈
SQLite 0.046s 0.329s 0.485s 0.422s 🥈
File I/O 0.070s 0.074s 0.072s 0.229s 🥉
Quicksort 0.177s 0.230s 0.203s 0.267s 🥉
Sieve of Eratosthenes 0.029s 0.041s 0.038s 0.056s 🥉
String Manipulation 0.008s 0.018s 0.017s 0.036s 🥉

CLI Tool Benchmarks

Benchmark ChadScript grep node xxd Place
Hex Dump 0.474s 1.012s 0.070s 🥈
Recursive Grep 0.012s 0.007s 0.101s 🥈

@cs01 cs01 merged commit 6da851d into main Apr 20, 2026
13 checks passed
@cs01 cs01 deleted the fix/codegen-bugs-587-589-591 branch April 20, 2026 17:13
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