Phase 6f: let = immutable, var = mutable (binding-only)
Bindings now signal mutability the way Rust/Swift do, instead of `let` meaning
"local" and `var` meaning "module-level":
- `let x = e` -> immutable binding; a later `x = …` is a compile error
(`cannot assign to immutable 'x' … use var`).
- `var x = e` -> mutable binding, at local OR module scope (position decides
scope; the keyword decides mutability).
- `const` -> unchanged (compile-time).
Immutability is of the *binding*, not the object: `let n = new Node; n.kind = 1`
is fine (mutation through the reference); only rebinding `n` is rejected. The
check lives in emit_assign — a direct `name =` whose target is a `let` local
(loc_mut == 0) errors; field/index targets and `var`/param/loop bindings are
unaffected.
Delivered as three reseeds so the self-hosting compiler never had to compile
source its own rules would reject:
A) add `var` as a local statement + per-local mutability tracking (loc_mut),
no enforcement;
B) migrate every reassigned `let` -> `var` across the compiler, runtime and
examples (337 declarations), driven by a per-function, string/comment-aware
scan (binding targets only, never `x.f =` / `x[i] =`);
C) turn on the check. bootstrap-cfree (compiler vs its own source) and every
golden build (which splices the runtime) then proved zero reassigned `let`
was missed anywhere.
Also folded in: removed leftover debug instrumentation in block() (a `cur=` /
print_int(777…) trace on the separator-error path) and fixed parse.ludic's stale
header comment (no more `struct`). Reseeded (21711 lines); C-free fixpoint holds;
goldens identical; 17/17; vocab + doc-fences clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
573813609c
commit
e1d7797e29
38 changed files with 2909 additions and 2778 deletions
36
LANGUAGE.md
36
LANGUAGE.md
|
|
@ -466,11 +466,37 @@ another `.ludic` file (see `examples/lib/`).
|
|||
|
||||
## Statements
|
||||
|
||||
`let x = expr` · `x = expr` (`+= -= *= /=`) · `if cond { }` / `if/else`
|
||||
(the `else` is optional) · `while cond { }` · `for i in a .. b { }` (numeric range) ·
|
||||
`for (…) in query […] { }` · `break` · `continue` · `return` · `spawn` ·
|
||||
`despawn` · `enable` / `disable` (a property `on e`, a model, or a handler) ·
|
||||
`match` · `machine`.
|
||||
`let x = expr` / `var x = expr` · `x = expr` (`+= -= *= /=`) · `if cond { }` /
|
||||
`if/else` (the `else` is optional) · `while cond { }` · `for i in a .. b { }`
|
||||
(numeric range) · `for (…) in query […] { }` · `break` · `continue` · `return` ·
|
||||
`spawn` · `despawn` · `enable` / `disable` (a property `on e`, a model, or a
|
||||
handler) · `match` · `machine`.
|
||||
|
||||
### Bindings: `let`, `var`, `const`
|
||||
|
||||
A binding's keyword states whether it can be reassigned, the way Rust and Swift
|
||||
use them — not its scope (position decides that: inside a body it is a local,
|
||||
at the top level it is module state).
|
||||
|
||||
- **`let x = e`** — an *immutable* binding. `x = …` afterward is a compile error
|
||||
(`cannot assign to immutable 'x'`). Reach for `let` by default.
|
||||
- **`var x = e`** — a *mutable* binding: `x`, `x += 1`, … reassign it. Use it for
|
||||
loop accumulators and anything that genuinely changes.
|
||||
- **`const NAME = e`** — a compile-time constant (folded, no storage).
|
||||
|
||||
Immutability is of the **binding**, not the object. A `let` that holds a record
|
||||
or slice still lets you mutate *through* it — the reference itself just cannot be
|
||||
repointed:
|
||||
|
||||
```ludic
|
||||
# doc-check: skip — illustrative bindings
|
||||
let n = new Node # immutable binding…
|
||||
n.kind = 1 # …but mutation through it is fine
|
||||
n = new Node # ERROR: cannot assign to immutable 'n'
|
||||
|
||||
var total = 0
|
||||
for i in 0 .. 10 { total += i } # a var is the right tool for an accumulator
|
||||
```
|
||||
|
||||
**Statements are separated by a newline or `;`** (both lex to the same separator
|
||||
token). Two statements may not sit adjacent with only spaces between them — the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue