Phase 2: enforce statement separators (Rule B)
The parser now requires a newline or ';' between statements (block() in selfhost/parse.ludic); two statements may no longer sit adjacent with only spaces. Also fixed if-without-else swallowing its trailing separator. Migration: tools/ludic-tools/migrate_separators.c inserts ';' at statement boundaries corpus-wide (examples, runtime, 25 self-host fragments, ~1100 boundaries). Verified semantically identical — the migrated compiler compiles itself to IR byte-identical to the pre-migration seed, and every golden game renders identically. Reseeded to the strict compiler; C-free fixpoint holds; test.sh 14/14. Docs: Rule B documented in LANGUAGE.md; BOOTSTRAP.md R1 + stale fences updated; check-docs green across all docs. Fixed a multi-line string literal in emit_expr.ludic (byte-identical \n escape) that the C toolchain lexer mis-lexes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
985f9ad8f2
commit
eac8f8f335
35 changed files with 3861 additions and 3588 deletions
|
|
@ -49,7 +49,7 @@ fn rt_read_file(path: str) -> ptr {
|
|||
file_seek(f, 0, 2)
|
||||
let n = file_tell(f)
|
||||
file_seek(f, 0, 0)
|
||||
if n <= 0 { file_close(f) return ptr_null() }
|
||||
if n <= 0 { file_close(f); return ptr_null() }
|
||||
let buf = mem_alloc(n + 8)
|
||||
file_read(f, buf, n)
|
||||
file_close(f)
|
||||
|
|
@ -70,9 +70,9 @@ fn rt_decode_png(path: str) -> bool {
|
|||
let d = rt_read_file(path)
|
||||
if ptr_is_null(d) { return false }
|
||||
let size = rt_file_len
|
||||
if size < 8 { mem_free(d) return false }
|
||||
if peek8(d, 0) != 137 { mem_free(d) return false }
|
||||
if peek8(d, 1) != 80 { mem_free(d) return false }
|
||||
if size < 8 { mem_free(d); return false }
|
||||
if peek8(d, 0) != 137 { mem_free(d); return false }
|
||||
if peek8(d, 1) != 80 { mem_free(d); return false }
|
||||
|
||||
let w = 0
|
||||
let h = 0
|
||||
|
|
@ -119,8 +119,8 @@ fn rt_decode_png(path: str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
if w <= 0 { mem_free(d) return false }
|
||||
if h <= 0 { mem_free(d) return false }
|
||||
if w <= 0 { mem_free(d); return false }
|
||||
if h <= 0 { mem_free(d); return false }
|
||||
|
||||
let channels = 1
|
||||
if ct == 2 { channels = 3 }
|
||||
|
|
@ -133,7 +133,7 @@ fn rt_decode_png(path: str) -> bool {
|
|||
let rawlen = h * (stride + 1)
|
||||
let raw = mem_alloc(rawlen + 8)
|
||||
if z_uncompress(idat, idlen, raw, rawlen) < 0 {
|
||||
mem_free(d) mem_free(raw) mem_free(idat)
|
||||
mem_free(d); mem_free(raw); mem_free(idat)
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +378,7 @@ fn rt_hexval(c: int) -> int {
|
|||
|
||||
fn rt_load_sprites(path: str) -> void {
|
||||
let d = rt_read_file(path)
|
||||
if ptr_is_null(d) { spr_n = 0 return }
|
||||
if ptr_is_null(d) { spr_n = 0; return }
|
||||
let size = rt_file_len
|
||||
let pal = mem_alloc(128 * 4)
|
||||
mem_set(pal, 0, 128 * 4)
|
||||
|
|
@ -391,7 +391,7 @@ fn rt_load_sprites(path: str) -> void {
|
|||
let j = start
|
||||
while j < size {
|
||||
let ch = peek8(d, j)
|
||||
if ch == 10 { j = size } else { len = len + 1 j = j + 1 }
|
||||
if ch == 10 { j = size } else { len = len + 1; j = j + 1 }
|
||||
}
|
||||
let c0 = peek8(d, start)
|
||||
if c0 == 112 { # 'p' — "pal <char> <rrggbb>"
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
|||
let r = peek8(d, p)
|
||||
p = p + 1
|
||||
while r > 0 {
|
||||
if i < npts { poke8(flags, i, fl) i = i + 1 }
|
||||
if i < npts { poke8(flags, i, fl); i = i + 1 }
|
||||
r = r - 1
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
|||
p = p + 1
|
||||
if band(fl, 16) != 0 { xv = xv + dxv } else { xv = xv - dxv }
|
||||
} else {
|
||||
if band(fl, 16) == 0 { xv = xv + tt_i16(d, p) p = p + 2 }
|
||||
if band(fl, 16) == 0 { xv = xv + tt_i16(d, p); p = p + 2 }
|
||||
}
|
||||
poke32(xs, k, xv)
|
||||
}
|
||||
|
|
@ -350,7 +350,7 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
|||
p = p + 1
|
||||
if band(fl, 32) != 0 { yv = yv + dyv } else { yv = yv - dyv }
|
||||
} else {
|
||||
if band(fl, 32) == 0 { yv = yv + tt_i16(d, p) p = p + 2 }
|
||||
if band(fl, 32) == 0 { yv = yv + tt_i16(d, p); p = p + 2 }
|
||||
}
|
||||
poke32(ys, k, yv)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue