fix(gen, gen-c): lower ExprCast in Zig and C emitters#1337
Merged
Conversation
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).
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-07-04 13:59:19 UTC
Summary
Seal Status
|
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
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-07-04 14:01:54 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-07-04 14:04:14 UTC
Summary
Seal Status
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1333.
Companion to #1320 (Rust arm, merged as c4dc8ee). With this PR,
NodeKind::ExprCasthas a lowering arm in all four backends (gen-verilog already had it).Fix
gen(Zig) —gen_exprdefault was_ => {}(silent drop → miscompile). Now emits@as(<target>, @intCast(<operand>)).@assets the explicit target type;@intCastdoes 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-c—gen_c_exprdefault emitted/* unsupported: ExprCast */. Now emits((<target_c_type>)(<operand>))via the existingSelf::type_to_chelper (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 genon tri-netspecs/wire.t27:be_byte→@as(u8, @intCast((w >> 24) & 255)),u32_be→ allas u32now@as(u32, @intCast(...)). Previously silent drop.t27c gen-conwire.t27:be_byte→((uint8_t)(((w >> 24) & 255))). Previously/* unsupported: ExprCast */.comprehensive_suite.t27: 0unsupported: ExprCastin bothgenandgen-coutput.Downstream unblock
tri-net's drift-guard (PR #35, merged) currently covers
gen/rust/wire.rsonly. With Zig + C now correct, tri-net can extend drift-guard togen/zig/wire.zig+gen/c/wire.c(multi-target spec-drift enforcement) — the gen-rust/zig/c triple all reproducible fromspecs/wire.t27.Anchor: phi^2 + phi^-2 = 3.