Skip to content

gen-c, gen: a module-level var is mutable (Refs #2161) - #2730

Merged
gHashTag merged 2 commits into
masterfrom
w699-mutvar
Aug 27, 2026
Merged

gen-c, gen: a module-level var is mutable (Refs #2161)#2730
gHashTag merged 2 commits into
masterfrom
w699-mutvar

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

The parser records mutability in extra_mutable, and both backends already branch on it for function locals — Zig var/const, Rust let mut/let. The module-level paths never read it.

gen-c        #define counter 0     →  `counter = counter + 1` becomes
                                      `0 = (0 + 1)`, which is not C at all
gen (Zig)    const counter: u32    →  Zig refuses the assignment
gen-verilog  reg [31:0] counter       correct all along

gen-c now emits static <type> <name> = <init>; for a mutable module-level declaration and keeps #define / static const for real constants. Zig writes var.

Measured over the 42 specs whose C output this changes

before after
C compile errors (cc -fsyntax-only -std=c11) 537 277
specs whose generated C is clean 0 19

specs/fpga/bpsk.t27 — the BPSK modem merged in #1250 — goes 7 errors to 0.

A probe spec compiles and runs: two calls to a function that increments a module-level counter print 1 2.

Immutable constants are untouched: const K: u32 = 7 still emits #define K 7.

gen-rust is deliberately not fixed here

Rust has no safe module-level mutable, and the three candidate lowerings each change the generated interface:

  • static mut — needs unsafe at every access site
  • AtomicU32 — turns every read and write into load/store
  • thread_local! — changes the semantics

Which one t27 means is a datapath decision, not an oversight, so it belongs to whoever owns it. Measured before deciding: all 43 of these specs already produce Rust that does not compile, for reasons beyond this one, so nothing regresses by leaving it. Filed separately.

No regressions

Parse count unchanged at 620/746; t27c tests unchanged at 1629 passed / 6 failed; RATCHET: CLEAN; width baseline 2 known, 0 new.

Refs #2161

The parser records mutability in `extra_mutable`, and both backends
already branch on it for function LOCALS -- Zig `var` vs `const`, Rust
`let mut` vs `let`. The module-level paths never read it, so a `var` at
module scope was emitted as a constant:

    gen-c    #define counter 0     -> `counter = counter + 1` becomes
                                      `0 = (0 + 1)`, which is not C
    gen      const counter: u32    -> Zig refuses the assignment
    gen-verilog  reg [31:0] counter    correct all along

gen-c now emits `static <type> <name> = <init>;` for a mutable
module-level declaration and keeps `#define` / `static const` for real
constants. Zig writes `var` instead of `const`.

Measured over the 42 specs whose C output this changes:

    C compile errors (cc -fsyntax-only -std=c11)   537 -> 277
    specs whose generated C is clean                 0 -> 19

specs/fpga/bpsk.t27 -- the BPSK modem merged in #1250 -- goes 7 errors to
0. A probe spec compiles and RUNS: two calls to a function that
increments a module-level counter print `1 2`.

Immutable constants are untouched: `const K: u32 = 7` still emits
`#define K 7`.

gen-rust is NOT fixed here, and the reason is a language question rather
than an oversight. Rust has no safe module-level mutable: `static mut`
needs `unsafe` at every access, `AtomicU32` changes the access API to
load/store, and `thread_local!` changes the semantics. All three alter
the generated interface, so which one t27 means belongs to whoever owns
the datapath. Measured first: all 43 of these specs already produce Rust
that does not compile, for reasons beyond this one, so nothing regresses
by leaving it.

Parse count unchanged at 620/746; t27c tests unchanged at 1629 passed /
6 failed.

FROZEN_HASH resealed in the same commit (M5).
@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

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

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-27 17:32:09 UTC

Summary

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

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=b4ed38b1d79a != manifest seal=87e5cbd3ad94.
    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 c9356d8 into master Aug 27, 2026
33 of 34 checks passed
@gHashTag
gHashTag deleted the w699-mutvar branch August 27, 2026 17:44
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