Phase 7b: null literal + x == null (retire ptr_null/ptr_is_null)
`null` is now a real pointer literal and null-tests are comparisons, instead of `ptr_null()` and `ptr_is_null(x)`: ptr_null() -> null ptr_is_null(x) -> (x == null) not ptr_is_null(x) -> (x != null) Mechanics: a new E_NULL primary (`null`, like true/false) lowers to the `null` pointer; emit_bin's comparison path now picks `ptr` vs `i32` from operand type (via llty), so `==`/`!=` work on any pointer/record/slice. The two intrinsics are deleted. Two reseeds: (A) add the literal + ptr comparison keeping the intrinsics; (B) migrate all 182 call sites (compiler + runtime, via a balanced-paren script that skips string-literal args and rewrites `not ptr_is_null` to `!= null`) and delete the intrinsics. Node/Val/Buf/Tok field defaults now read `ptr = null`. Vocabulary drops the two from LUDIC_INTRINSICS; `null` joins true/false as a language constant (grammar + ludic_syntax.h). LANGUAGE.md notes the literal. Reseeded (21664 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
ddb1af3008
commit
70ab79a4e9
34 changed files with 5064 additions and 5124 deletions
|
|
@ -20,10 +20,10 @@
|
|||
# ============================================================================
|
||||
|
||||
# ---- state ----------------------------------------------------------------
|
||||
var rt_fb: ptr = ptr_null() # framebuffer, one i32 (0x00RRGGBB) per pixel
|
||||
var rt_fb: ptr = null # framebuffer, one i32 (0x00RRGGBB) per pixel
|
||||
var rt_fbw: int = 320
|
||||
var rt_fbh: int = 240
|
||||
var rt_regs: ptr = ptr_null() # the 64 general-purpose game registers
|
||||
var rt_regs: ptr = null # the 64 general-purpose game registers
|
||||
var rt_rng: int = 305419896 # xorshift32 state
|
||||
var rt_alive: int = 1 # platform still running?
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ fn rt_put_int(buf: ptr, at: int, v: int) -> int {
|
|||
|
||||
fn rt_dump_ppm(path: str) -> void {
|
||||
let f = file_open(path, "wb")
|
||||
if ptr_is_null(f) { return }
|
||||
if (f == null) { return }
|
||||
|
||||
let hdr = mem_alloc(64)
|
||||
var n = rt_put_str(hdr, 0, "P6\n")
|
||||
|
|
@ -310,7 +310,7 @@ import "ui.ludic"
|
|||
# A character grid the game paints with map_row() and reads with tile(). Stored
|
||||
# as one byte per cell in a flat buffer; out-of-bounds reads answer '#' so a
|
||||
# caller can treat the edge of the world as wall without special-casing it.
|
||||
var rt_map: ptr = ptr_null()
|
||||
var rt_map: ptr = null
|
||||
var rt_mapw: int = 0
|
||||
var rt_maph: int = 0
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ fn rt_tile(x: int, y: int) -> int {
|
|||
# ---- status line ----------------------------------------------------------
|
||||
# One persistent string of feedback/dialogue, copied into runtime-owned memory
|
||||
# so it survives whatever the caller does with the original.
|
||||
var rt_statusbuf: ptr = ptr_null()
|
||||
var rt_statusbuf: ptr = null
|
||||
|
||||
fn rt_status(s: str) -> void {
|
||||
var i = 0
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ const IMG_MAX: int = 32
|
|||
const SPR_MAX: int = 160
|
||||
const SPR_SZ: int = 16
|
||||
|
||||
var img_px: ptr = ptr_null() # IMG_MAX pointers to RGBA buffers
|
||||
var img_w: ptr = ptr_null()
|
||||
var img_h: ptr = ptr_null()
|
||||
var img_px: ptr = null # IMG_MAX pointers to RGBA buffers
|
||||
var img_w: ptr = null
|
||||
var img_h: ptr = null
|
||||
var img_n: int = 0
|
||||
|
||||
var spr_px: ptr = ptr_null() # SPR_MAX * 16 * 16 RGBA pixels, one block
|
||||
var spr_px: ptr = null # SPR_MAX * 16 * 16 RGBA pixels, one block
|
||||
var spr_n: int = 0
|
||||
|
||||
fn rt_image_init() -> void {
|
||||
|
|
@ -44,11 +44,11 @@ fn png_tag(b: ptr, at: int, a: int, c: int, d: int, e: int) -> bool {
|
|||
|
||||
fn rt_read_file(path: str) -> ptr {
|
||||
let f = file_open(path, "rb")
|
||||
if ptr_is_null(f) { return ptr_null() }
|
||||
if (f == null) { return null }
|
||||
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 null }
|
||||
let buf = mem_alloc(n + 8)
|
||||
file_read(f, buf, n)
|
||||
file_close(f)
|
||||
|
|
@ -60,14 +60,14 @@ var rt_file_len: int = 0
|
|||
# decoded image is left in these; -1 width means failure
|
||||
var png_w: int = 0
|
||||
var png_h: int = 0
|
||||
var png_px: ptr = ptr_null()
|
||||
var png_px: ptr = null
|
||||
|
||||
fn rt_decode_png(path: str) -> bool {
|
||||
png_w = 0
|
||||
png_h = 0
|
||||
png_px = ptr_null()
|
||||
png_px = null
|
||||
let d = rt_read_file(path)
|
||||
if ptr_is_null(d) { return false }
|
||||
if (d == null) { 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 }
|
||||
|
|
@ -334,7 +334,7 @@ fn rt_png_load(path: str) -> int {
|
|||
}
|
||||
}
|
||||
mem_free(png_px)
|
||||
png_px = ptr_null()
|
||||
png_px = null
|
||||
return id
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ fn rt_hexval(c: int) -> int {
|
|||
|
||||
fn rt_sprites_load(path: str) -> void {
|
||||
let d = rt_read_file(path)
|
||||
if ptr_is_null(d) { spr_n = 0; return }
|
||||
if (d == null) { spr_n = 0; return }
|
||||
let size = rt_file_len
|
||||
let pal = mem_alloc(128 * 4)
|
||||
mem_set(pal, 0, 128 * 4)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
# ============================================================================
|
||||
|
||||
# ---- bit reader (DEFLATE packs bits least-significant-first) ---------------
|
||||
var z_src: ptr = ptr_null()
|
||||
var z_src: ptr = null
|
||||
var z_len: int = 0
|
||||
var z_pos: int = 0
|
||||
var z_bitbuf: int = 0
|
||||
|
|
|
|||
|
|
@ -18,50 +18,50 @@ const TT_EDGES: int = 16384 # line segments in one glyph
|
|||
const TT_GC: int = 512 # glyph cache entries
|
||||
|
||||
# ---- per-font tables (parallel arrays; index = font id) -------------------
|
||||
var tt_data: ptr = ptr_null()
|
||||
var tt_size: ptr = ptr_null()
|
||||
var tt_upem: ptr = ptr_null()
|
||||
var tt_nglyf: ptr = ptr_null()
|
||||
var tt_locfm: ptr = ptr_null()
|
||||
var tt_nhm: ptr = ptr_null()
|
||||
var tt_asc: ptr = ptr_null()
|
||||
var tt_desc: ptr = ptr_null()
|
||||
var tt_gap: ptr = ptr_null()
|
||||
var tt_glyf: ptr = ptr_null()
|
||||
var tt_loca: ptr = ptr_null()
|
||||
var tt_hmtx: ptr = ptr_null()
|
||||
var tt_cmap: ptr = ptr_null()
|
||||
var tt_cfmt: ptr = ptr_null()
|
||||
var tt_data: ptr = null
|
||||
var tt_size: ptr = null
|
||||
var tt_upem: ptr = null
|
||||
var tt_nglyf: ptr = null
|
||||
var tt_locfm: ptr = null
|
||||
var tt_nhm: ptr = null
|
||||
var tt_asc: ptr = null
|
||||
var tt_desc: ptr = null
|
||||
var tt_gap: ptr = null
|
||||
var tt_glyf: ptr = null
|
||||
var tt_loca: ptr = null
|
||||
var tt_hmtx: ptr = null
|
||||
var tt_cmap: ptr = null
|
||||
var tt_cfmt: ptr = null
|
||||
var tt_n: int = 0
|
||||
|
||||
# ---- outline + edge scratch (reused for every glyph) ----------------------
|
||||
var ol_x: ptr = ptr_null()
|
||||
var ol_y: ptr = ptr_null()
|
||||
var ol_on: ptr = ptr_null()
|
||||
var ol_ends: ptr = ptr_null()
|
||||
var ol_x: ptr = null
|
||||
var ol_y: ptr = null
|
||||
var ol_on: ptr = null
|
||||
var ol_ends: ptr = null
|
||||
var ol_n: int = 0
|
||||
var ol_ne: int = 0
|
||||
|
||||
var ed_x0: ptr = ptr_null()
|
||||
var ed_y0: ptr = ptr_null()
|
||||
var ed_x1: ptr = ptr_null()
|
||||
var ed_y1: ptr = ptr_null()
|
||||
var ed_x0: ptr = null
|
||||
var ed_y0: ptr = null
|
||||
var ed_x1: ptr = null
|
||||
var ed_y1: ptr = null
|
||||
var ed_n: int = 0
|
||||
|
||||
var sc_x: ptr = ptr_null() # scanline crossings
|
||||
var sc_d: ptr = ptr_null()
|
||||
var sc_x: ptr = null # scanline crossings
|
||||
var sc_d: ptr = null
|
||||
|
||||
# ---- glyph cache ----------------------------------------------------------
|
||||
var gc_used: ptr = ptr_null()
|
||||
var gc_font: ptr = ptr_null()
|
||||
var gc_cp: ptr = ptr_null()
|
||||
var gc_px: ptr = ptr_null()
|
||||
var gc_w: ptr = ptr_null()
|
||||
var gc_h: ptr = ptr_null()
|
||||
var gc_ox: ptr = ptr_null()
|
||||
var gc_oy: ptr = ptr_null()
|
||||
var gc_adv: ptr = ptr_null()
|
||||
var gc_bmp: ptr = ptr_null()
|
||||
var gc_used: ptr = null
|
||||
var gc_font: ptr = null
|
||||
var gc_cp: ptr = null
|
||||
var gc_px: ptr = null
|
||||
var gc_w: ptr = null
|
||||
var gc_h: ptr = null
|
||||
var gc_ox: ptr = null
|
||||
var gc_oy: ptr = null
|
||||
var gc_adv: ptr = null
|
||||
var gc_bmp: ptr = null
|
||||
|
||||
fn rt_tt_init() -> void {
|
||||
tt_data = mem_alloc(TT_MAX * 8)
|
||||
|
|
@ -169,7 +169,7 @@ fn tt_pick_cmap(id: int, d: ptr, co: int) -> void {
|
|||
fn rt_font_load(path: str) -> int {
|
||||
if tt_n >= TT_MAX { return 0 - 1 }
|
||||
let d = rt_read_file(path)
|
||||
if ptr_is_null(d) { return 0 - 1 }
|
||||
if (d == null) { return 0 - 1 }
|
||||
let size = rt_file_len
|
||||
var base = 0
|
||||
# a .ttc collection points at its first font
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fn tt_raster(id: int, gid: int, px: int) -> ptr {
|
|||
ol_ne = 0
|
||||
ed_n = 0
|
||||
tt_load_outline(id, gid, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0)
|
||||
if ol_n == 0 { return ptr_null() }
|
||||
if ol_n == 0 { return null }
|
||||
|
||||
var minx = 999999.0
|
||||
var miny = 999999.0
|
||||
|
|
@ -83,10 +83,10 @@ fn tt_raster(id: int, gid: int, px: int) -> ptr {
|
|||
if maxy == fx(flr(maxy)) { y1 = flr(maxy) }
|
||||
let W = x1 - x0
|
||||
let H = y1 - y0
|
||||
if W <= 0 { return ptr_null() }
|
||||
if H <= 0 { return ptr_null() }
|
||||
if W > 1024 { return ptr_null() }
|
||||
if H > 1024 { return ptr_null() }
|
||||
if W <= 0 { return null }
|
||||
if H <= 0 { return null }
|
||||
if W > 1024 { return null }
|
||||
if H > 1024 { return null }
|
||||
gr_w = W
|
||||
gr_h = H
|
||||
gr_ox = x0
|
||||
|
|
@ -250,7 +250,7 @@ fn tt_glyph_get(font: int, cp: int, px: int) -> int {
|
|||
let s = h
|
||||
if peek32(gc_used, s) == 1 {
|
||||
let old = peekp(gc_bmp, s)
|
||||
if ptr_is_null(old) == false { mem_free(old) }
|
||||
if (old == null) == false { mem_free(old) }
|
||||
}
|
||||
let bmp = tt_raster(font, tt_glyph_index(font, cp), px)
|
||||
pokep(gc_bmp, s, bmp)
|
||||
|
|
@ -299,7 +299,7 @@ fn tt_utf8(s: str, at: int) -> int {
|
|||
|
||||
# ---- drawing --------------------------------------------------------------
|
||||
fn tt_blit(bmp: ptr, w: int, h: int, dx: int, dy: int, colour: int) -> void {
|
||||
if ptr_is_null(bmp) { return }
|
||||
if (bmp == null) { return }
|
||||
let cr = ((colour >> 16) & 255)
|
||||
let cg = ((colour >> 8) & 255)
|
||||
let cb = (colour & 255)
|
||||
|
|
|
|||
|
|
@ -45,35 +45,35 @@ const K_VISIBLE: int = 18
|
|||
const K_IMG: int = 19
|
||||
const K_SKIN: int = 20
|
||||
|
||||
var ui_type: ptr = ptr_null()
|
||||
var ui_parent: ptr = ptr_null()
|
||||
var ui_w: ptr = ptr_null()
|
||||
var ui_h: ptr = ptr_null()
|
||||
var ui_x: ptr = ptr_null()
|
||||
var ui_y: ptr = ptr_null()
|
||||
var ui_haspos: ptr = ptr_null()
|
||||
var ui_pad: ptr = ptr_null()
|
||||
var ui_gap: ptr = ptr_null()
|
||||
var ui_bg: ptr = ptr_null()
|
||||
var ui_fg: ptr = ptr_null()
|
||||
var ui_border: ptr = ptr_null()
|
||||
var ui_align: ptr = ptr_null()
|
||||
var ui_grow: ptr = ptr_null()
|
||||
var ui_font: ptr = ptr_null()
|
||||
var ui_size: ptr = ptr_null()
|
||||
var ui_skin: ptr = ptr_null()
|
||||
var ui_inset: ptr = ptr_null()
|
||||
var ui_img: ptr = ptr_null()
|
||||
var ui_focusable: ptr = ptr_null()
|
||||
var ui_rx: ptr = ptr_null()
|
||||
var ui_ry: ptr = ptr_null()
|
||||
var ui_rw: ptr = ptr_null()
|
||||
var ui_rh: ptr = ptr_null()
|
||||
var ui_visible: ptr = ptr_null()
|
||||
var ui_fired: ptr = ptr_null()
|
||||
var ui_hasdyn: ptr = ptr_null()
|
||||
var ui_dyn: ptr = ptr_null() # UI_MAX * 96 bytes
|
||||
var ui_text: ptr = ptr_null() # UI_MAX static string pointers
|
||||
var ui_type: ptr = null
|
||||
var ui_parent: ptr = null
|
||||
var ui_w: ptr = null
|
||||
var ui_h: ptr = null
|
||||
var ui_x: ptr = null
|
||||
var ui_y: ptr = null
|
||||
var ui_haspos: ptr = null
|
||||
var ui_pad: ptr = null
|
||||
var ui_gap: ptr = null
|
||||
var ui_bg: ptr = null
|
||||
var ui_fg: ptr = null
|
||||
var ui_border: ptr = null
|
||||
var ui_align: ptr = null
|
||||
var ui_grow: ptr = null
|
||||
var ui_font: ptr = null
|
||||
var ui_size: ptr = null
|
||||
var ui_skin: ptr = null
|
||||
var ui_inset: ptr = null
|
||||
var ui_img: ptr = null
|
||||
var ui_focusable: ptr = null
|
||||
var ui_rx: ptr = null
|
||||
var ui_ry: ptr = null
|
||||
var ui_rw: ptr = null
|
||||
var ui_rh: ptr = null
|
||||
var ui_visible: ptr = null
|
||||
var ui_fired: ptr = null
|
||||
var ui_hasdyn: ptr = null
|
||||
var ui_dyn: ptr = null # UI_MAX * 96 bytes
|
||||
var ui_text: ptr = null # UI_MAX static string pointers
|
||||
|
||||
var ui_n: int = 0
|
||||
var ui_active: int = -1
|
||||
|
|
@ -138,7 +138,7 @@ fn rt_ui_reset(n: int) -> void {
|
|||
poke32(ui_visible, i, 1)
|
||||
poke32(ui_fired, i, 0)
|
||||
poke32(ui_hasdyn, i, 0)
|
||||
pokep(ui_text, i, ptr_null())
|
||||
pokep(ui_text, i, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +178,7 @@ fn rt_ui_static_text(i: int, s: str) -> void {
|
|||
fn ui_str(i: int) -> ptr {
|
||||
if peek32(ui_hasdyn, i) == 1 { return ptr_add(ui_dyn, i * 96) }
|
||||
let t = peekp(ui_text, i)
|
||||
if ptr_is_null(t) { return ptr_add(ui_dyn, i * 96) }
|
||||
if (t == null) { return ptr_add(ui_dyn, i * 96) }
|
||||
return t
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,10 +146,10 @@ fn ui_draw_node(i: int) -> void {
|
|||
}
|
||||
|
||||
# ---- focus and activation -------------------------------------------------
|
||||
var ui_fl: ptr = ptr_null()
|
||||
var ui_fl: ptr = null
|
||||
|
||||
fn ui_focusables() -> int {
|
||||
if ptr_is_null(ui_fl) { ui_fl = mem_alloc(UI_MAX * 4) }
|
||||
if (ui_fl == null) { ui_fl = mem_alloc(UI_MAX * 4) }
|
||||
var n = 0
|
||||
for i in 0 .. ui_n {
|
||||
if peek32(ui_focusable, i) == 1 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue