Skip to content

fix(gen, gen-c): lower ExprCast in Zig and C emitters#1337

Merged
gHashTag merged 4 commits into
masterfrom
fix/exprcast-zig-c-emitters
Jul 4, 2026
Merged

fix(gen, gen-c): lower ExprCast in Zig and C emitters#1337
gHashTag merged 4 commits into
masterfrom
fix/exprcast-zig-c-emitters

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Closes #1333.

Companion to #1320 (Rust arm, merged as c4dc8ee). With this PR, NodeKind::ExprCast has a lowering arm in all four backends (gen-verilog already had it).

Fix

  • gen (Zig)gen_expr default was _ => {} (silent drop → miscompile). Now emits @as(<target>, @intCast(<operand>)). @as sets the explicit target type; @intCast does the safe integer conversion. Works in any expression position and for both narrowing (u32→u8) and widening (u8→u32) — stronger than the @as-only minimal pass suggested in gen-zig and gen-c: ExprCast falls through default arm (silent drop / '/* unsupported */') #1333, which cannot narrow.
  • gen-cgen_c_expr default emitted /* unsupported: ExprCast */. Now emits ((<target_c_type>)(<operand>)) via the existing Self::type_to_c helper (u8→uint8_t, u32→uint32_t).

Both arms mirror #1320's Rust arm: node.children[0] = operand, node.extra_type.split('[').next() = scalar target type.

Verified

  • t27c self-tests: 20 passed, 0 failed.
  • t27c gen on tri-net specs/wire.t27: be_byte@as(u8, @intCast((w >> 24) & 255)), u32_be → all as u32 now @as(u32, @intCast(...)). Previously silent drop.
  • t27c gen-c on wire.t27: be_byte((uint8_t)(((w >> 24) & 255))). Previously /* unsupported: ExprCast */.
  • comprehensive_suite.t27: 0 unsupported: ExprCast in both gen and gen-c output.

Downstream unblock

tri-net's drift-guard (PR #35, merged) currently covers gen/rust/wire.rs only. With Zig + C now correct, tri-net can extend drift-guard to gen/zig/wire.zig + gen/c/wire.c (multi-target spec-drift enforcement) — the gen-rust/zig/c triple all reproducible from specs/wire.t27.

Anchor: phi^2 + phi^-2 = 3.

Companion to #1320 (which added the Rust arm). NodeKind::ExprCast now
has a lowering arm in all three text emitters; only gen-verilog previously
had one.

- gen (Zig), gen_expr default was '_ => {}' (silent drop): now emits
  '@as(<target>, @intcast(<operand>))'. @as establishes the explicit target
  type, @intcast does the safe integer conversion. Works in any expression
  position and for both narrowing (u32->u8) and widening (u8->u32) — better
  than the @as-only minimal pass suggested in #1333, which cannot narrow.
- gen-c, gen_c_expr default emitted '/* unsupported: ExprCast */': now emits
  '((<target_c_type>)(<operand>))' using the existing Self::type_to_c helper
  (u8->uint8_t, u32->uint32_t).

Closes #1333.

Verified:
- t27c self-tests: 20 passed, 0 failed.
- 't27c gen' on tri-net specs/wire.t27: be_byte -> '@as(u8, @intcast((w >> 24) & 255))',
  u32_be -> all 'as u32' casts now '@as(u32, @intcast(...))'. Previously silent drop.
- 't27c gen-c' on wire.t27: be_byte -> '((uint8_t)(((w >> 24) & 255)))'.
  Previously '/* unsupported: ExprCast */'.
- Minimal repro 'fn hi_byte(w: u32) -> u8 { return ((w >> 24) & 255) as u8; }'
  -> gen: 'return @as(u8, @intcast((w >> 24) & 255));',
     gen-c: 'return ((uint8_t)(((w >> 24) & 255)));'.
- comprehensive_suite.t27: 0 'unsupported: ExprCast' in both gen and gen-c output.

With #1320 (Rust) + this (Zig, C), ExprCast is fully lowered across all four
backends (gen-verilog already had it). Unblocks multi-target T27-first flips
in downstream consumers (tri-net gen/zig + gen/c drift-guard).
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-07-04 13:39:18 UTC

Summary

Status Count
Total Open PRs 20
PRs with Failing Checks 11
PRs with All Checks Green 9
READY 7
FAILING 11
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=621b9883e268 != manifest seal=49e55df6d444.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-07-04 13:59:19 UTC

Summary

Status Count
Total Open PRs 20
PRs with Failing Checks 12
PRs with All Checks Green 8
READY 7
FAILING 12
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=621b9883e268 != manifest seal=49e55df6d444.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

Wave Loop 411 close-out requires docs/NOW.md to reflect every landing PR.
Adds a section for this PR documenting:
- WHERE: gen/gen-c ExprCast arms in bootstrap/src/compiler.rs
- Zig form: @as(<T>, @intcast(<operand>)) -- narrows and widens
- C form: ((<uintN_t>)(<operand>)) via Self::type_to_c
- Coverage: all 4 backends now lower ExprCast (Rust from #1320, Verilog
  already, Zig+C in this PR)
- Downstream unblock: tri-net multi-target drift-guard (Rust+Zig+C from
  specs/wire.t27) can now proceed
- Regression: t27c self-tests 20/0; comprehensive_suite.t27 shows 0
  'unsupported: ExprCast' in Zig+C output

Anchor: phi^2 + phi^-2 = 3
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-07-04 14:01:54 UTC

Summary

Status Count
Total Open PRs 20
PRs with Failing Checks 12
PRs with All Checks Green 8
READY 7
FAILING 12
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=621b9883e268 != manifest seal=49e55df6d444.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-07-04 14:04:14 UTC

Summary

Status Count
Total Open PRs 19
PRs with Failing Checks 11
PRs with All Checks Green 8
READY 7
FAILING 11
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=621b9883e268 != manifest seal=49e55df6d444.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 3c912d9 into master Jul 4, 2026
23 checks passed
@gHashTag
gHashTag deleted the fix/exprcast-zig-c-emitters branch July 4, 2026 14:06
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.

gen-zig and gen-c: ExprCast falls through default arm (silent drop / '/* unsupported */')

1 participant