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
|
|
@ -37,8 +37,8 @@ fn is_op1(c: int) -> bool {
|
|||
|
||||
fn lex(src: ptr) -> void {
|
||||
toks = new []Tok
|
||||
let i = 0
|
||||
let line = 1
|
||||
var i = 0
|
||||
var line = 1
|
||||
let n = slen(src)
|
||||
while i < n {
|
||||
let c = peek8(src, i)
|
||||
|
|
@ -52,11 +52,11 @@ fn lex(src: ptr) -> void {
|
|||
i = i + 1
|
||||
let start = i
|
||||
let out = mem_alloc(n)
|
||||
let j = 0
|
||||
var j = 0
|
||||
while i < n and peek8(src, i) != 34 {
|
||||
if peek8(src, i) == 92 { # backslash escape
|
||||
let e = peek8(src, i + 1)
|
||||
let r = e
|
||||
var r = e
|
||||
if e == 110 { r = 10 }
|
||||
if e == 116 { r = 9 }
|
||||
if e == 48 { r = 0 }
|
||||
|
|
@ -70,7 +70,7 @@ fn lex(src: ptr) -> void {
|
|||
}
|
||||
if c == 39 { # 'c' char literal -> int
|
||||
i = i + 1
|
||||
let v = 0
|
||||
var v = 0
|
||||
if peek8(src, i) == 92 {
|
||||
let e = peek8(src, i + 1)
|
||||
if e == 110 { v = 10 }
|
||||
|
|
@ -84,11 +84,11 @@ fn lex(src: ptr) -> void {
|
|||
}
|
||||
if char_is_digit(c) {
|
||||
if c == 48 and peek8(src, i + 1) == 120 { # 0x hex
|
||||
let v = 0
|
||||
var v = 0
|
||||
i = i + 2
|
||||
while i < n {
|
||||
let h = peek8(src, i)
|
||||
let d = 0
|
||||
var d = 0
|
||||
if char_is_digit(h) { d = h - 48 }
|
||||
else { if h >= 97 and h <= 102 { d = h - 87 }
|
||||
else { if h >= 65 and h <= 70 { d = h - 55 } else { break } } }
|
||||
|
|
@ -98,12 +98,12 @@ fn lex(src: ptr) -> void {
|
|||
tok_push(TK_INT, ptr_null(), v, line)
|
||||
continue
|
||||
}
|
||||
let v = 0
|
||||
var v = 0
|
||||
while i < n and char_is_digit(peek8(src, i)) { v = v * 10 + (peek8(src, i) - 48); i = i + 1 }
|
||||
# a fractional part makes it a Q16.16 fixed literal
|
||||
if i < n and peek8(src, i) == 46 and char_is_digit(peek8(src, i + 1)) {
|
||||
i = i + 1
|
||||
let fnum = 0; let fden = 1
|
||||
var fnum = 0; var fden = 1
|
||||
while i < n and char_is_digit(peek8(src, i)) { fnum = fnum * 10 + (peek8(src, i) - 48); fden = fden * 10; i = i + 1 }
|
||||
let bits = shl(v, 16) + shl(fnum, 16) / fden
|
||||
tok_push(TK_FLOAT, ptr_null(), bits, line)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue