Phase 7i: byte indexing p[i] / p[i] = v (retire peek8/poke8)
Raw byte access is now indexing, not C-style peek/poke: peek8(src, i) -> src[i] (reads a byte, widened to int) poke8(out, j, r) -> out[j] = r (narrows the int to a byte) E_INDEX on a non-slice pointer/string lowers to a `getelementptr i8` + load/zext (read) or trunc/store (write) — byte-identical to the old peek8/poke8, so the migration reproduces the compiler exactly. A "byte" element type (llty i8) drives the widen/narrow. The compiler's own byte work now reads naturally, e.g. `is_slice_ty` is `t[0] == 91 and t[1] == 93`. Subtlety fixed on the way: g_addr_ty (the out-param carrying the indexed element type) must be set AFTER evaluating the index expression, since a member/index in the index would otherwise clobber it — doing it early made a byte read load a full pointer from a byte address and crash the self-compile. Two reseeds: add byte-index support keeping peek8/poke8, then migrate 148 call sites and delete the intrinsics (+ the now-dead emit_gep_i8). Vocabulary drops peek8/poke8. Reseeded (22604 lines); C-free fixpoint holds; goldens identical; 18/18; vocab clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3aaf983cf5
commit
feb3a71e56
25 changed files with 3309 additions and 3388 deletions
|
|
@ -40,7 +40,7 @@ fn rt_init() -> void {
|
||||||
rt_map = mem_alloc(96 * 64)
|
rt_map = mem_alloc(96 * 64)
|
||||||
mem_set(rt_map, 32, 96 * 64)
|
mem_set(rt_map, 32, 96 * 64)
|
||||||
rt_statusbuf = mem_alloc(96)
|
rt_statusbuf = mem_alloc(96)
|
||||||
poke8(rt_statusbuf, 0, 0)
|
rt_statusbuf[0] = 0
|
||||||
rt_image_init()
|
rt_image_init()
|
||||||
rt_tt_init()
|
rt_tt_init()
|
||||||
rt_ui_init()
|
rt_ui_init()
|
||||||
|
|
@ -117,7 +117,7 @@ fn rt_glyph(x: int, y: int, ch: int, colour: int, sc: int) -> void {
|
||||||
let base = (c - 32) * 7
|
let base = (c - 32) * 7
|
||||||
let font = rt_font()
|
let font = rt_font()
|
||||||
for row in 0 .. 7 {
|
for row in 0 .. 7 {
|
||||||
let bits = peek8(font, base + row) - 48
|
let bits = font[base + row] - 48
|
||||||
var b = bits
|
var b = bits
|
||||||
for cc in 0 .. 5 {
|
for cc in 0 .. 5 {
|
||||||
let on = b / 16
|
let on = b / 16
|
||||||
|
|
@ -132,12 +132,12 @@ fn rt_glyph(x: int, y: int, ch: int, colour: int, sc: int) -> void {
|
||||||
fn rt_text(x: int, y: int, s: str, colour: int, sc: int) -> void {
|
fn rt_text(x: int, y: int, s: str, colour: int, sc: int) -> void {
|
||||||
var i = 0
|
var i = 0
|
||||||
var cx = x
|
var cx = x
|
||||||
var ch = peek8(s, 0)
|
var ch = s[0]
|
||||||
while ch != 0 {
|
while ch != 0 {
|
||||||
rt_glyph(cx, y, ch, colour, sc)
|
rt_glyph(cx, y, ch, colour, sc)
|
||||||
cx = cx + 6 * sc
|
cx = cx + 6 * sc
|
||||||
i = i + 1
|
i = i + 1
|
||||||
ch = peek8(s, i)
|
ch = s[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,19 +240,19 @@ fn rt_running() -> bool {
|
||||||
fn rt_put_str(buf: ptr, at: int, s: str) -> int {
|
fn rt_put_str(buf: ptr, at: int, s: str) -> int {
|
||||||
var i = 0
|
var i = 0
|
||||||
var n = at
|
var n = at
|
||||||
var ch = peek8(s, 0)
|
var ch = s[0]
|
||||||
while ch != 0 {
|
while ch != 0 {
|
||||||
poke8(buf, n, ch)
|
buf[n] = ch
|
||||||
n = n + 1
|
n = n + 1
|
||||||
i = i + 1
|
i = i + 1
|
||||||
ch = peek8(s, i)
|
ch = s[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rt_put_int(buf: ptr, at: int, v: int) -> int {
|
fn rt_put_int(buf: ptr, at: int, v: int) -> int {
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
poke8(buf, at, 48)
|
buf[at] = 48
|
||||||
return at + 1
|
return at + 1
|
||||||
}
|
}
|
||||||
var digits = 0
|
var digits = 0
|
||||||
|
|
@ -268,7 +268,7 @@ fn rt_put_int(buf: ptr, at: int, v: int) -> int {
|
||||||
for k in 1 .. p {
|
for k in 1 .. p {
|
||||||
div = div * 10
|
div = div * 10
|
||||||
}
|
}
|
||||||
poke8(buf, n, 48 + (v / div) % 10)
|
buf[n] = 48 + (v / div) % 10
|
||||||
n = n + 1
|
n = n + 1
|
||||||
p = p - 1
|
p = p - 1
|
||||||
}
|
}
|
||||||
|
|
@ -291,9 +291,9 @@ fn rt_dump_ppm(path: str) -> void {
|
||||||
let buf = mem_alloc(px * 3)
|
let buf = mem_alloc(px * 3)
|
||||||
for i in 0 .. px {
|
for i in 0 .. px {
|
||||||
let c = peek32(rt_fb, i)
|
let c = peek32(rt_fb, i)
|
||||||
poke8(buf, i * 3, (c / 65536) % 256)
|
buf[i * 3] = (c / 65536) % 256
|
||||||
poke8(buf, i * 3 + 1, (c / 256) % 256)
|
buf[i * 3 + 1] = (c / 256) % 256
|
||||||
poke8(buf, i * 3 + 2, c % 256)
|
buf[i * 3 + 2] = c % 256
|
||||||
}
|
}
|
||||||
file_write(f, buf, px * 3)
|
file_write(f, buf, px * 3)
|
||||||
file_close(f)
|
file_close(f)
|
||||||
|
|
@ -324,12 +324,12 @@ fn rt_map_row(y: int, s: str) -> void {
|
||||||
if y < 0 { return }
|
if y < 0 { return }
|
||||||
if y >= 64 { return }
|
if y >= 64 { return }
|
||||||
var x = 0
|
var x = 0
|
||||||
var ch = peek8(s, 0)
|
var ch = s[0]
|
||||||
while ch != 0 {
|
while ch != 0 {
|
||||||
if x >= 96 { return }
|
if x >= 96 { return }
|
||||||
poke8(rt_map, y * 96 + x, ch)
|
rt_map[y * 96 + x] = ch
|
||||||
x = x + 1
|
x = x + 1
|
||||||
ch = peek8(s, x)
|
ch = s[x]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,7 +338,7 @@ fn rt_tile(x: int, y: int) -> int {
|
||||||
if y < 0 { return 35 }
|
if y < 0 { return 35 }
|
||||||
if x >= rt_mapw { return 35 }
|
if x >= rt_mapw { return 35 }
|
||||||
if y >= rt_maph { return 35 }
|
if y >= rt_maph { return 35 }
|
||||||
return peek8(rt_map, y * 96 + x)
|
return rt_map[y * 96 + x]
|
||||||
}
|
}
|
||||||
|
|
||||||
# ---- status line ----------------------------------------------------------
|
# ---- status line ----------------------------------------------------------
|
||||||
|
|
@ -348,16 +348,16 @@ var rt_statusbuf: ptr = null
|
||||||
|
|
||||||
fn rt_status(s: str) -> void {
|
fn rt_status(s: str) -> void {
|
||||||
var i = 0
|
var i = 0
|
||||||
var ch = peek8(s, 0)
|
var ch = s[0]
|
||||||
while ch != 0 {
|
while ch != 0 {
|
||||||
if i >= 95 { ch = 0 }
|
if i >= 95 { ch = 0 }
|
||||||
if ch != 0 {
|
if ch != 0 {
|
||||||
poke8(rt_statusbuf, i, ch)
|
rt_statusbuf[i] = ch
|
||||||
i = i + 1
|
i = i + 1
|
||||||
ch = peek8(s, i)
|
ch = s[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poke8(rt_statusbuf, i, 0)
|
rt_statusbuf[i] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rt_status_text() -> ptr {
|
fn rt_status_text() -> ptr {
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ fn rt_image_init() -> void {
|
||||||
|
|
||||||
# ---- decoding -------------------------------------------------------------
|
# ---- decoding -------------------------------------------------------------
|
||||||
fn png_be32(b: ptr, at: int) -> int {
|
fn png_be32(b: ptr, at: int) -> int {
|
||||||
return (peek8(b, at) << 24) | (peek8(b, at + 1) << 16) | (peek8(b, at + 2) << 8) | peek8(b, at + 3)
|
return (b[at] << 24) | (b[at + 1] << 16) | (b[at + 2] << 8) | b[at + 3]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn png_tag(b: ptr, at: int, a: int, c: int, d: int, e: int) -> bool {
|
fn png_tag(b: ptr, at: int, a: int, c: int, d: int, e: int) -> bool {
|
||||||
if peek8(b, at) != a { return false }
|
if b[at] != a { return false }
|
||||||
if peek8(b, at + 1) != c { return false }
|
if b[at + 1] != c { return false }
|
||||||
if peek8(b, at + 2) != d { return false }
|
if b[at + 2] != d { return false }
|
||||||
if peek8(b, at + 3) != e { return false }
|
if b[at + 3] != e { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,8 +70,8 @@ fn rt_decode_png(path: str) -> bool {
|
||||||
if (d == null) { return false }
|
if (d == null) { return false }
|
||||||
let size = rt_file_len
|
let size = rt_file_len
|
||||||
if size < 8 { mem_free(d); return false }
|
if size < 8 { mem_free(d); return false }
|
||||||
if peek8(d, 0) != 137 { mem_free(d); return false }
|
if d[0] != 137 { mem_free(d); return false }
|
||||||
if peek8(d, 1) != 80 { mem_free(d); return false }
|
if d[1] != 80 { mem_free(d); return false }
|
||||||
|
|
||||||
var w = 0
|
var w = 0
|
||||||
var h = 0
|
var h = 0
|
||||||
|
|
@ -97,19 +97,19 @@ fn rt_decode_png(path: str) -> bool {
|
||||||
if png_tag(d, typ, 73, 72, 68, 82) { # IHDR
|
if png_tag(d, typ, 73, 72, 68, 82) { # IHDR
|
||||||
w = png_be32(d, body)
|
w = png_be32(d, body)
|
||||||
h = png_be32(d, body + 4)
|
h = png_be32(d, body + 4)
|
||||||
bd = peek8(d, body + 8)
|
bd = d[body + 8]
|
||||||
ct = peek8(d, body + 9)
|
ct = d[body + 9]
|
||||||
}
|
}
|
||||||
if png_tag(d, typ, 80, 76, 84, 69) { # PLTE
|
if png_tag(d, typ, 80, 76, 84, 69) { # PLTE
|
||||||
let m = min(ln, 768)
|
let m = min(ln, 768)
|
||||||
for k in 0 .. m { poke8(plte, k, peek8(d, body + k)) }
|
for k in 0 .. m { plte[k] = d[body + k] }
|
||||||
}
|
}
|
||||||
if png_tag(d, typ, 116, 82, 78, 83) { # tRNS
|
if png_tag(d, typ, 116, 82, 78, 83) { # tRNS
|
||||||
ntrns = min(ln, 256)
|
ntrns = min(ln, 256)
|
||||||
for k in 0 .. ntrns { poke8(trns, k, peek8(d, body + k)) }
|
for k in 0 .. ntrns { trns[k] = d[body + k] }
|
||||||
}
|
}
|
||||||
if png_tag(d, typ, 73, 68, 65, 84) { # IDAT
|
if png_tag(d, typ, 73, 68, 65, 84) { # IDAT
|
||||||
for k in 0 .. ln { poke8(idat, idlen + k, peek8(d, body + k)) }
|
for k in 0 .. ln { idat[idlen + k] = d[body + k] }
|
||||||
idlen = idlen + ln
|
idlen = idlen + ln
|
||||||
}
|
}
|
||||||
if png_tag(d, typ, 73, 69, 78, 68) { done = 1 } # IEND
|
if png_tag(d, typ, 73, 69, 78, 68) { done = 1 } # IEND
|
||||||
|
|
@ -139,17 +139,17 @@ fn rt_decode_png(path: str) -> bool {
|
||||||
# reverse the per-scanline filters, in place
|
# reverse the per-scanline filters, in place
|
||||||
for y in 0 .. h {
|
for y in 0 .. h {
|
||||||
let line = y * (stride + 1)
|
let line = y * (stride + 1)
|
||||||
let ft = peek8(raw, line)
|
let ft = raw[line]
|
||||||
let cur = line + 1
|
let cur = line + 1
|
||||||
let prev = cur - (stride + 1)
|
let prev = cur - (stride + 1)
|
||||||
for x in 0 .. stride {
|
for x in 0 .. stride {
|
||||||
var a = 0
|
var a = 0
|
||||||
var b = 0
|
var b = 0
|
||||||
var c = 0
|
var c = 0
|
||||||
if x >= fbpp { a = peek8(raw, cur + x - fbpp) }
|
if x >= fbpp { a = raw[cur + x - fbpp] }
|
||||||
if y > 0 { b = peek8(raw, prev + x) }
|
if y > 0 { b = raw[prev + x] }
|
||||||
if x >= fbpp { if y > 0 { c = peek8(raw, prev + x - fbpp) } }
|
if x >= fbpp { if y > 0 { c = raw[prev + x - fbpp] } }
|
||||||
var v = peek8(raw, cur + x)
|
var v = raw[cur + x]
|
||||||
if ft == 1 { v = v + a }
|
if ft == 1 { v = v + a }
|
||||||
if ft == 2 { v = v + b }
|
if ft == 2 { v = v + b }
|
||||||
if ft == 3 { v = v + (a + b) / 2 }
|
if ft == 3 { v = v + (a + b) / 2 }
|
||||||
|
|
@ -163,7 +163,7 @@ fn rt_decode_png(path: str) -> bool {
|
||||||
if pa <= pb { if pa <= pc { pick = a } }
|
if pa <= pb { if pa <= pc { pick = a } }
|
||||||
v = v + pick
|
v = v + pick
|
||||||
}
|
}
|
||||||
poke8(raw, cur + x, (v & 255))
|
raw[cur + x] = (v & 255)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,33 +178,33 @@ fn rt_decode_png(path: str) -> bool {
|
||||||
var B = 0
|
var B = 0
|
||||||
var A = 255
|
var A = 255
|
||||||
if ct == 6 {
|
if ct == 6 {
|
||||||
R = peek8(raw, row + x * 4)
|
R = raw[row + x * 4]
|
||||||
G = peek8(raw, row + x * 4 + 1)
|
G = raw[row + x * 4 + 1]
|
||||||
B = peek8(raw, row + x * 4 + 2)
|
B = raw[row + x * 4 + 2]
|
||||||
A = peek8(raw, row + x * 4 + 3)
|
A = raw[row + x * 4 + 3]
|
||||||
}
|
}
|
||||||
if ct == 2 {
|
if ct == 2 {
|
||||||
R = peek8(raw, row + x * 3)
|
R = raw[row + x * 3]
|
||||||
G = peek8(raw, row + x * 3 + 1)
|
G = raw[row + x * 3 + 1]
|
||||||
B = peek8(raw, row + x * 3 + 2)
|
B = raw[row + x * 3 + 2]
|
||||||
}
|
}
|
||||||
if ct == 4 {
|
if ct == 4 {
|
||||||
R = peek8(raw, row + x * 2)
|
R = raw[row + x * 2]
|
||||||
G = R
|
G = R
|
||||||
B = R
|
B = R
|
||||||
A = peek8(raw, row + x * 2 + 1)
|
A = raw[row + x * 2 + 1]
|
||||||
}
|
}
|
||||||
if ct == 3 {
|
if ct == 3 {
|
||||||
let bp = x * bd
|
let bp = x * bd
|
||||||
let idx = ((peek8(raw, row + bp / 8) >> (8 - bd - bp % 8)) & maxv)
|
let idx = ((raw[row + bp / 8] >> (8 - bd - bp % 8)) & maxv)
|
||||||
R = peek8(plte, idx * 3)
|
R = plte[idx * 3]
|
||||||
G = peek8(plte, idx * 3 + 1)
|
G = plte[idx * 3 + 1]
|
||||||
B = peek8(plte, idx * 3 + 2)
|
B = plte[idx * 3 + 2]
|
||||||
if idx < ntrns { A = peek8(trns, idx) }
|
if idx < ntrns { A = trns[idx] }
|
||||||
}
|
}
|
||||||
if ct == 0 {
|
if ct == 0 {
|
||||||
let bp = x * bd
|
let bp = x * bd
|
||||||
let s = ((peek8(raw, row + bp / 8) >> (8 - bd - bp % 8)) & maxv)
|
let s = ((raw[row + bp / 8] >> (8 - bd - bp % 8)) & maxv)
|
||||||
var g = s
|
var g = s
|
||||||
if bd != 8 { g = s * 255 / maxv }
|
if bd != 8 { g = s * 255 / maxv }
|
||||||
R = g
|
R = g
|
||||||
|
|
@ -389,15 +389,15 @@ fn rt_sprites_load(path: str) -> void {
|
||||||
var len = 0
|
var len = 0
|
||||||
var j = start
|
var j = start
|
||||||
while j < size {
|
while j < size {
|
||||||
let ch = peek8(d, j)
|
let ch = 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)
|
let c0 = d[start]
|
||||||
if c0 == 112 { # 'p' — "pal <char> <rrggbb>"
|
if c0 == 112 { # 'p' — "pal <char> <rrggbb>"
|
||||||
let ch = peek8(d, start + 4)
|
let ch = d[start + 4]
|
||||||
var v = 0
|
var v = 0
|
||||||
for k in 0 .. 6 {
|
for k in 0 .. 6 {
|
||||||
let hv = rt_hexval(peek8(d, start + 6 + k))
|
let hv = rt_hexval(d[start + 6 + k])
|
||||||
if hv >= 0 { v = v * 16 + hv }
|
if hv >= 0 { v = v * 16 + hv }
|
||||||
}
|
}
|
||||||
if ch < 128 { poke32(pal, ch, ((255 << 24) | v)) }
|
if ch < 128 { poke32(pal, ch, ((255 << 24) | v)) }
|
||||||
|
|
@ -419,7 +419,7 @@ fn rt_sprites_load(path: str) -> void {
|
||||||
for x in 0 .. SPR_SZ {
|
for x in 0 .. SPR_SZ {
|
||||||
if x < len {
|
if x < len {
|
||||||
poke32(spr_px, cur * SPR_SZ * SPR_SZ + row * SPR_SZ + x,
|
poke32(spr_px, cur * SPR_SZ * SPR_SZ + row * SPR_SZ + x,
|
||||||
peek32(pal, (peek8(d, start + x) & 127)))
|
peek32(pal, (d[start + x] & 127)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row = row + 1
|
row = row + 1
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ fn z_bits(need: int) -> int {
|
||||||
z_err = 1
|
z_err = 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
val = (val | (peek8(z_src, z_pos) << z_bitcnt))
|
val = (val | (z_src[z_pos] << z_bitcnt))
|
||||||
z_pos = z_pos + 1
|
z_pos = z_pos + 1
|
||||||
z_bitcnt = z_bitcnt + 8
|
z_bitcnt = z_bitcnt + 8
|
||||||
}
|
}
|
||||||
|
|
@ -129,13 +129,13 @@ fn z_stored(out: ptr, at: int, cap: int) -> int {
|
||||||
z_bitbuf = 0
|
z_bitbuf = 0
|
||||||
z_bitcnt = 0 # stored blocks are byte-aligned
|
z_bitcnt = 0 # stored blocks are byte-aligned
|
||||||
if z_pos + 4 > z_len { return -1 }
|
if z_pos + 4 > z_len { return -1 }
|
||||||
let n = peek8(z_src, z_pos) + (peek8(z_src, z_pos + 1) << 8)
|
let n = z_src[z_pos] + (z_src[z_pos + 1] << 8)
|
||||||
z_pos = z_pos + 4 # LEN then its one's complement
|
z_pos = z_pos + 4 # LEN then its one's complement
|
||||||
var w = at
|
var w = at
|
||||||
for i in 0 .. n {
|
for i in 0 .. n {
|
||||||
if z_pos >= z_len { return -1 }
|
if z_pos >= z_len { return -1 }
|
||||||
if w >= cap { return -1 }
|
if w >= cap { return -1 }
|
||||||
poke8(out, w, peek8(z_src, z_pos))
|
out[w] = z_src[z_pos]
|
||||||
w = w + 1
|
w = w + 1
|
||||||
z_pos = z_pos + 1
|
z_pos = z_pos + 1
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +150,7 @@ fn z_codes(out: ptr, at: int, cap: int, lit: ptr, dist: ptr) -> int {
|
||||||
if sym < 0 { return -1 }
|
if sym < 0 { return -1 }
|
||||||
if sym < 256 {
|
if sym < 256 {
|
||||||
if w >= cap { return -1 }
|
if w >= cap { return -1 }
|
||||||
poke8(out, w, sym)
|
out[w] = sym
|
||||||
w = w + 1
|
w = w + 1
|
||||||
}
|
}
|
||||||
if sym > 256 {
|
if sym > 256 {
|
||||||
|
|
@ -163,7 +163,7 @@ fn z_codes(out: ptr, at: int, cap: int, lit: ptr, dist: ptr) -> int {
|
||||||
if distance > w { return -1 }
|
if distance > w { return -1 }
|
||||||
for k in 0 .. length {
|
for k in 0 .. length {
|
||||||
if w >= cap { return -1 }
|
if w >= cap { return -1 }
|
||||||
poke8(out, w, peek8(out, w - distance))
|
out[w] = out[w - distance]
|
||||||
w = w + 1
|
w = w + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +197,7 @@ fn z_dynamic_tables(lit: ptr, dist: ptr) -> int {
|
||||||
# 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 — biased by '0' so it is one literal
|
# 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 — biased by '0' so it is one literal
|
||||||
let order = "@AB08796:5;4<3=2>1?"
|
let order = "@AB08796:5;4<3=2>1?"
|
||||||
for i in 0 .. ncode {
|
for i in 0 .. ncode {
|
||||||
poke32(lengths, peek8(order, i) - 48, z_bits(3))
|
poke32(lengths, order[i] - 48, z_bits(3))
|
||||||
}
|
}
|
||||||
let clen = z_table_new(19)
|
let clen = z_table_new(19)
|
||||||
z_table_build(clen, lengths, 19)
|
z_table_build(clen, lengths, 19)
|
||||||
|
|
@ -270,7 +270,7 @@ fn z_inflate(src: ptr, len: int, out: ptr, cap: int) -> int {
|
||||||
# zlib wrapper (RFC 1950): two header bytes, then DEFLATE, then Adler-32.
|
# zlib wrapper (RFC 1950): two header bytes, then DEFLATE, then Adler-32.
|
||||||
fn z_uncompress(src: ptr, len: int, out: ptr, cap: int) -> int {
|
fn z_uncompress(src: ptr, len: int, out: ptr, cap: int) -> int {
|
||||||
if len < 2 { return -1 }
|
if len < 2 { return -1 }
|
||||||
let cmf = peek8(src, 0)
|
let cmf = src[0]
|
||||||
if (cmf & 15) != 8 { return -1 }
|
if (cmf & 15) != 8 { return -1 }
|
||||||
return z_inflate(ptr_add(src, 2), len - 2, out, cap)
|
return z_inflate(ptr_add(src, 2), len - 2, out, cap)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ fn rt_tt_init() -> void {
|
||||||
|
|
||||||
# ---- big-endian readers ---------------------------------------------------
|
# ---- big-endian readers ---------------------------------------------------
|
||||||
fn tt_u16(d: ptr, at: int) -> int {
|
fn tt_u16(d: ptr, at: int) -> int {
|
||||||
return ((peek8(d, at) << 8) | peek8(d, at + 1))
|
return ((d[at] << 8) | d[at + 1])
|
||||||
}
|
}
|
||||||
fn tt_i16(d: ptr, at: int) -> int {
|
fn tt_i16(d: ptr, at: int) -> int {
|
||||||
let v = tt_u16(d, at)
|
let v = tt_u16(d, at)
|
||||||
|
|
@ -114,10 +114,10 @@ fn tt_i16(d: ptr, at: int) -> int {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
fn tt_u32(d: ptr, at: int) -> int {
|
fn tt_u32(d: ptr, at: int) -> int {
|
||||||
return (peek8(d, at) << 24) | (peek8(d, at + 1) << 16) | (peek8(d, at + 2) << 8) | peek8(d, at + 3)
|
return (d[at] << 24) | (d[at + 1] << 16) | (d[at + 2] << 8) | d[at + 3]
|
||||||
}
|
}
|
||||||
fn tt_i8(d: ptr, at: int) -> int {
|
fn tt_i8(d: ptr, at: int) -> int {
|
||||||
let v = peek8(d, at)
|
let v = d[at]
|
||||||
if v >= 128 { return v - 256 }
|
if v >= 128 { return v - 256 }
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
@ -126,10 +126,10 @@ fn tt_find_table(d: ptr, base: int, a: int, b: int, c: int, e: int) -> int {
|
||||||
let n = tt_u16(d, base + 4)
|
let n = tt_u16(d, base + 4)
|
||||||
for i in 0 .. n {
|
for i in 0 .. n {
|
||||||
let rec = base + 12 + i * 16
|
let rec = base + 12 + i * 16
|
||||||
if peek8(d, rec) == a {
|
if d[rec] == a {
|
||||||
if peek8(d, rec + 1) == b {
|
if d[rec + 1] == b {
|
||||||
if peek8(d, rec + 2) == c {
|
if d[rec + 2] == c {
|
||||||
if peek8(d, rec + 3) == e { return tt_u32(d, rec + 8) }
|
if d[rec + 3] == e { return tt_u32(d, rec + 8) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +174,7 @@ fn rt_font_load(path: str) -> int {
|
||||||
var base = 0
|
var base = 0
|
||||||
# a .ttc collection points at its first font
|
# a .ttc collection points at its first font
|
||||||
if size >= 16 {
|
if size >= 16 {
|
||||||
if peek8(d, 0) == 116 { if peek8(d, 1) == 116 { if peek8(d, 2) == 99 { if peek8(d, 3) == 102 {
|
if d[0] == 116 { if d[1] == 116 { if d[2] == 99 { if d[3] == 102 {
|
||||||
base = tt_u32(d, 12)
|
base = tt_u32(d, 12)
|
||||||
} } } }
|
} } } }
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +256,7 @@ fn tt_glyph_index(id: int, cp: int) -> int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if fmt == 0 {
|
if fmt == 0 {
|
||||||
if cp < 256 { return peek8(d, s + 6 + cp) }
|
if cp < 256 { return d[s + 6 + cp] }
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -313,15 +313,15 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
||||||
let flags = mem_alloc(npts + 8)
|
let flags = mem_alloc(npts + 8)
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < npts {
|
while i < npts {
|
||||||
let fl = peek8(d, p)
|
let fl = d[p]
|
||||||
p = p + 1
|
p = p + 1
|
||||||
poke8(flags, i, fl)
|
flags[i] = fl
|
||||||
i = i + 1
|
i = i + 1
|
||||||
if (fl & 8) != 0 { # REPEAT
|
if (fl & 8) != 0 { # REPEAT
|
||||||
var r = peek8(d, p)
|
var r = d[p]
|
||||||
p = p + 1
|
p = p + 1
|
||||||
while r > 0 {
|
while r > 0 {
|
||||||
if i < npts { poke8(flags, i, fl); i = i + 1 }
|
if i < npts { flags[i] = fl; i = i + 1 }
|
||||||
r = r - 1
|
r = r - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -331,9 +331,9 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
||||||
let ys = mem_alloc((npts + 1) * 4)
|
let ys = mem_alloc((npts + 1) * 4)
|
||||||
var xv = 0
|
var xv = 0
|
||||||
for k in 0 .. npts {
|
for k in 0 .. npts {
|
||||||
let fl = peek8(flags, k)
|
let fl = flags[k]
|
||||||
if (fl & 2) != 0 {
|
if (fl & 2) != 0 {
|
||||||
let dxv = peek8(d, p)
|
let dxv = d[p]
|
||||||
p = p + 1
|
p = p + 1
|
||||||
if (fl & 16) != 0 { xv = xv + dxv } else { xv = xv - dxv }
|
if (fl & 16) != 0 { xv = xv + dxv } else { xv = xv - dxv }
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -343,9 +343,9 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
||||||
}
|
}
|
||||||
var yv = 0
|
var yv = 0
|
||||||
for k in 0 .. npts {
|
for k in 0 .. npts {
|
||||||
let fl = peek8(flags, k)
|
let fl = flags[k]
|
||||||
if (fl & 4) != 0 {
|
if (fl & 4) != 0 {
|
||||||
let dyv = peek8(d, p)
|
let dyv = d[p]
|
||||||
p = p + 1
|
p = p + 1
|
||||||
if (fl & 32) != 0 { yv = yv + dyv } else { yv = yv - dyv }
|
if (fl & 32) != 0 { yv = yv + dyv } else { yv = yv - dyv }
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -360,7 +360,7 @@ fn tt_load_outline(id: int, gid: int, a: fixed, b: fixed, c: fixed, e: fixed, dx
|
||||||
for k in start .. last + 1 {
|
for k in start .. last + 1 {
|
||||||
let X = fx(peek32(xs, k))
|
let X = fx(peek32(xs, k))
|
||||||
let Y = fx(peek32(ys, k))
|
let Y = fx(peek32(ys, k))
|
||||||
ol_pt(a * X + c * Y + dx, b * X + e * Y + dy, (peek8(flags, k) & 1))
|
ol_pt(a * X + c * Y + dx, b * X + e * Y + dy, (flags[k] & 1))
|
||||||
}
|
}
|
||||||
if ol_ne < 256 {
|
if ol_ne < 256 {
|
||||||
poke32(ol_ends, ol_ne, ol_n)
|
poke32(ol_ends, ol_ne, ol_n)
|
||||||
|
|
|
||||||
|
|
@ -215,9 +215,9 @@ fn tt_raster(id: int, gid: int, px: int) -> ptr {
|
||||||
if cvr > 0.0 {
|
if cvr > 0.0 {
|
||||||
let oxp = sx / TT_SS
|
let oxp = sx / TT_SS
|
||||||
if oxp >= 0 { if oxp < W { if oy >= 0 { if oy < H {
|
if oxp >= 0 { if oxp < W { if oy >= 0 { if oy < H {
|
||||||
var v = peek8(cover, oy * W + oxp) + flr(cvr * unit)
|
var v = cover[oy * W + oxp] + flr(cvr * unit)
|
||||||
if v > 255 { v = 255 }
|
if v > 255 { v = 255 }
|
||||||
poke8(cover, oy * W + oxp, v)
|
cover[oy * W + oxp] = v
|
||||||
} } } }
|
} } } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +270,7 @@ fn tt_glyph_get(font: int, cp: int, px: int) -> int {
|
||||||
var u8_next: int = 0 # byte index just past the codepoint last decoded
|
var u8_next: int = 0 # byte index just past the codepoint last decoded
|
||||||
|
|
||||||
fn tt_utf8(s: str, at: int) -> int {
|
fn tt_utf8(s: str, at: int) -> int {
|
||||||
let c = peek8(s, at)
|
let c = s[at]
|
||||||
var extra = 0 - 1
|
var extra = 0 - 1
|
||||||
if c < 128 { extra = 0 }
|
if c < 128 { extra = 0 }
|
||||||
if (c >> 5) == 6 { extra = 1 }
|
if (c >> 5) == 6 { extra = 1 }
|
||||||
|
|
@ -286,7 +286,7 @@ fn tt_utf8(s: str, at: int) -> int {
|
||||||
}
|
}
|
||||||
var cp = (c & (63 >> extra))
|
var cp = (c & (63 >> extra))
|
||||||
for i in 0 .. extra {
|
for i in 0 .. extra {
|
||||||
let b = peek8(s, at + 1 + i)
|
let b = s[at + 1 + i]
|
||||||
if (b & 192) != 128 {
|
if (b & 192) != 128 {
|
||||||
u8_next = at + 1 + i
|
u8_next = at + 1 + i
|
||||||
return 65533
|
return 65533
|
||||||
|
|
@ -308,7 +308,7 @@ fn tt_blit(bmp: ptr, w: int, h: int, dx: int, dy: int, colour: int) -> void {
|
||||||
if py >= 0 {
|
if py >= 0 {
|
||||||
if py < rt_fbh {
|
if py < rt_fbh {
|
||||||
for x in 0 .. w {
|
for x in 0 .. w {
|
||||||
let a = peek8(bmp, y * w + x)
|
let a = bmp[y * w + x]
|
||||||
if a != 0 {
|
if a != 0 {
|
||||||
let pxx = dx + x
|
let pxx = dx + x
|
||||||
if pxx >= 0 {
|
if pxx >= 0 {
|
||||||
|
|
@ -337,7 +337,7 @@ fn rt_text_ttf(font: int, x: int, y: int, s: str, colour: int, px: int) -> void
|
||||||
let lineh = flr(fx(peek32(tt_asc, font) - peek32(tt_desc, font) + peek32(tt_gap, font)) * scale + 0.5)
|
let lineh = flr(fx(peek32(tt_asc, font) - peek32(tt_desc, font) + peek32(tt_gap, font)) * scale + 0.5)
|
||||||
var penx = x
|
var penx = x
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(s, i) != 0 {
|
while s[i] != 0 {
|
||||||
let cp = tt_utf8(s, i)
|
let cp = tt_utf8(s, i)
|
||||||
i = u8_next
|
i = u8_next
|
||||||
if cp == 10 {
|
if cp == 10 {
|
||||||
|
|
@ -358,7 +358,7 @@ fn rt_text_w(font: int, s: str, px: int) -> int {
|
||||||
var w = 0
|
var w = 0
|
||||||
var best = 0
|
var best = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(s, i) != 0 {
|
while s[i] != 0 {
|
||||||
let cp = tt_utf8(s, i)
|
let cp = tt_utf8(s, i)
|
||||||
i = u8_next
|
i = u8_next
|
||||||
if cp == 10 {
|
if cp == 10 {
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ fn ui_tw(font: int, s: ptr, size: int) -> int {
|
||||||
if font < tt_n { return rt_text_w(font, s, size) }
|
if font < tt_n { return rt_text_w(font, s, size) }
|
||||||
}
|
}
|
||||||
var n = 0
|
var n = 0
|
||||||
while peek8(s, n) != 0 { n = n + 1 }
|
while s[n] != 0 { n = n + 1 }
|
||||||
return n * 6 * max(size / 8, 1)
|
return n * 6 * max(size / 8, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,16 +219,16 @@ fn rt_ui_set_text(id: int, s: str) -> void {
|
||||||
if id >= ui_n { return }
|
if id >= ui_n { return }
|
||||||
let base = id * 96
|
let base = id * 96
|
||||||
var i = 0
|
var i = 0
|
||||||
var ch = peek8(s, 0)
|
var ch = s[0]
|
||||||
while ch != 0 {
|
while ch != 0 {
|
||||||
if i >= 95 { ch = 0 }
|
if i >= 95 { ch = 0 }
|
||||||
if ch != 0 {
|
if ch != 0 {
|
||||||
poke8(ui_dyn, base + i, ch)
|
ui_dyn[base + i] = ch
|
||||||
i = i + 1
|
i = i + 1
|
||||||
ch = peek8(s, i)
|
ch = s[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poke8(ui_dyn, base + i, 0)
|
ui_dyn[base + i] = 0
|
||||||
poke32(ui_hasdyn, id, 1)
|
poke32(ui_hasdyn, id, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,12 +239,12 @@ fn rt_ui_set_int(id: int, n: int) -> void {
|
||||||
var at = 0
|
var at = 0
|
||||||
var v = n
|
var v = n
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
poke8(ui_dyn, base, 45)
|
ui_dyn[base] = 45
|
||||||
at = 1
|
at = 1
|
||||||
v = 0 - v
|
v = 0 - v
|
||||||
}
|
}
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
poke8(ui_dyn, base + at, 48)
|
ui_dyn[base + at] = 48
|
||||||
at = at + 1
|
at = at + 1
|
||||||
} else {
|
} else {
|
||||||
var digits = 0
|
var digits = 0
|
||||||
|
|
@ -257,12 +257,12 @@ fn rt_ui_set_int(id: int, n: int) -> void {
|
||||||
while p > 0 {
|
while p > 0 {
|
||||||
var div = 1
|
var div = 1
|
||||||
for k in 1 .. p { div = div * 10 }
|
for k in 1 .. p { div = div * 10 }
|
||||||
poke8(ui_dyn, base + at, 48 + (v / div) % 10)
|
ui_dyn[base + at] = 48 + (v / div) % 10
|
||||||
at = at + 1
|
at = at + 1
|
||||||
p = p - 1
|
p = p - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poke8(ui_dyn, base + at, 0)
|
ui_dyn[base + at] = 0
|
||||||
poke32(ui_hasdyn, id, 1)
|
poke32(ui_hasdyn, id, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ fn buf_ensure(b: Buf, extra: int) -> void {
|
||||||
}
|
}
|
||||||
fn buf_putc(b: Buf, c: int) -> void {
|
fn buf_putc(b: Buf, c: int) -> void {
|
||||||
buf_ensure(b, 1)
|
buf_ensure(b, 1)
|
||||||
poke8(b.data, b.len, c)
|
b.data[b.len] = c
|
||||||
b.len = b.len + 1
|
b.len = b.len + 1
|
||||||
}
|
}
|
||||||
fn buf_puts(b: Buf, s: ptr) -> void {
|
fn buf_puts(b: Buf, s: ptr) -> void {
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(s, i) != 0 { buf_putc(b, peek8(s, i)); i = i + 1 }
|
while s[i] != 0 { buf_putc(b, s[i]); i = i + 1 }
|
||||||
}
|
}
|
||||||
fn buf_puti(b: Buf, n: int) -> void { buf_puts(b, itoa(n)) }
|
fn buf_puti(b: Buf, n: int) -> void { buf_puts(b, itoa(n)) }
|
||||||
fn buf_str(b: Buf) -> ptr { poke8(b.data, b.len, 0); return b.data }
|
fn buf_str(b: Buf) -> ptr { b.data[b.len] = 0; return b.data }
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,12 @@ fn emit_member_addr(e: Node) -> ptr {
|
||||||
# address of `base[index]` (slices only in this subset)
|
# address of `base[index]` (slices only in this subset)
|
||||||
fn emit_index_addr(e: Node) -> ptr {
|
fn emit_index_addr(e: Node) -> ptr {
|
||||||
let base = emit_expr(e.a)
|
let base = emit_expr(e.a)
|
||||||
if not is_slice_ty(base.ty) { perr("indexing a non-slice") }
|
if not is_slice_ty(base.ty) { # a raw ptr/str: address of byte i.
|
||||||
|
let bi = emit_expr(e.b) # (evaluate index first — it may set g_addr_ty)
|
||||||
|
let r = emit_bind(`getelementptr inbounds i8, ptr {base.code}, i32 {bi.code}`)
|
||||||
|
g_addr_ty = "byte" # set last so the caller sees it
|
||||||
|
return r
|
||||||
|
}
|
||||||
let el = slice_elem(base.ty)
|
let el = slice_elem(base.ty)
|
||||||
g_addr_ty = el
|
g_addr_ty = el
|
||||||
# load the data pointer from the slice header (field 0)
|
# load the data pointer from the slice header (field 0)
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,12 @@ fn lbl(pfx: ptr) -> ptr { let r = (pfx + itoa(ll_lbl)); ll_lbl = ll_lbl + 1; r
|
||||||
# slice) is a pointer; void is void.
|
# slice) is a pointer; void is void.
|
||||||
fn llty(t: ptr) -> ptr {
|
fn llty(t: ptr) -> ptr {
|
||||||
if (t == "int") or (t == "bool") or (t == "fixed") { return "i32" }
|
if (t == "int") or (t == "bool") or (t == "fixed") { return "i32" }
|
||||||
|
if (t == "byte") { return "i8" } # a single byte (p[i] on a raw ptr)
|
||||||
if (t == "void") { return "void" }
|
if (t == "void") { return "void" }
|
||||||
return "ptr"
|
return "ptr"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_slice_ty(t: ptr) -> bool { return peek8(t, 0) == 91 and peek8(t, 1) == 93 } # "[]"
|
fn is_slice_ty(t: ptr) -> bool { return t[0] == 91 and t[1] == 93 } # "[]"
|
||||||
fn slice_elem(t: ptr) -> ptr { return t[2..len(t)] }
|
fn slice_elem(t: ptr) -> ptr { return t[2..len(t)] }
|
||||||
|
|
||||||
fn find_arch(name: ptr) -> Node {
|
fn find_arch(name: ptr) -> Node {
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,14 @@ fn emit_expr(e: Node) -> Val {
|
||||||
}
|
}
|
||||||
let a = emit_member_addr(e); return emit_load_at(a, g_addr_ty)
|
let a = emit_member_addr(e); return emit_load_at(a, g_addr_ty)
|
||||||
}
|
}
|
||||||
if e.kind == E_INDEX { let a = emit_index_addr(e); return emit_load_at(a, g_addr_ty) }
|
if e.kind == E_INDEX {
|
||||||
|
let a = emit_index_addr(e)
|
||||||
|
if (g_addr_ty == "byte") { # a byte read, widened to int
|
||||||
|
let b = emit_bind(`load i8, ptr {a}`)
|
||||||
|
return val(emit_bind(`zext i8 {b} to i32`), "int")
|
||||||
|
}
|
||||||
|
return emit_load_at(a, g_addr_ty)
|
||||||
|
}
|
||||||
if e.kind == E_CALL { return emit_call(e) }
|
if e.kind == E_CALL { return emit_call(e) }
|
||||||
if e.kind == E_BIN { return emit_bin(e) }
|
if e.kind == E_BIN { return emit_bin(e) }
|
||||||
if e.kind == E_UN {
|
if e.kind == E_UN {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ fn emit_str_const(s: ptr) -> ptr {
|
||||||
emith(itoa(n + 1)); emith(" x i8] c\"")
|
emith(itoa(n + 1)); emith(" x i8] c\"")
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < n {
|
while i < n {
|
||||||
let c = peek8(s, i)
|
let c = s[i]
|
||||||
if c == 34 or c == 92 or c < 32 or c > 126 {
|
if c == 34 or c == 92 or c < 32 or c > 126 {
|
||||||
buf_putc(head, 92) # backslash
|
buf_putc(head, 92) # backslash
|
||||||
buf_putc(head, hexdig(c / 16))
|
buf_putc(head, hexdig(c / 16))
|
||||||
|
|
@ -24,14 +24,6 @@ fn emit_str_const(s: ptr) -> ptr {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
# a fresh SSA register bound to a `getelementptr`, returned as its name
|
|
||||||
fn emit_gep_i8(base: ptr, idx: ptr) -> ptr {
|
|
||||||
let r = nreg()
|
|
||||||
emit(" "); emit(r); emit(" = getelementptr inbounds i8, ptr ")
|
|
||||||
emit(base); emit(", i32 "); emit(idx); emit("\n")
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
# the constant initializer for a global var: a literal, or 0/null
|
# the constant initializer for a global var: a literal, or 0/null
|
||||||
fn global_init(d: Node) -> ptr {
|
fn global_init(d: Node) -> ptr {
|
||||||
if (d.a == null) { if (llty(d.ty) == "ptr") { return "null" }; return "0" }
|
if (d.a == null) { if (llty(d.ty) == "ptr") { return "null" }; return "0" }
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ var g_intrin_ok: bool = false
|
||||||
# without evaluating arguments (which could clobber shared state).
|
# without evaluating arguments (which could clobber shared state).
|
||||||
fn is_intrinsic(name: ptr) -> bool {
|
fn is_intrinsic(name: ptr) -> bool {
|
||||||
if (name == "mem_alloc") or (name == "mem_realloc") { return true }
|
if (name == "mem_alloc") or (name == "mem_realloc") { return true }
|
||||||
if (name == "peek8") or (name == "poke8") { return true }
|
|
||||||
if (name == "file_open") or (name == "file_read") or (name == "file_write") { return true }
|
if (name == "file_open") or (name == "file_read") or (name == "file_write") { return true }
|
||||||
if (name == "file_seek") or (name == "file_tell") or (name == "file_close") { return true }
|
if (name == "file_seek") or (name == "file_tell") or (name == "file_close") { return true }
|
||||||
if (name == "os_argc") or (name == "os_arg") or (name == "os_exit") or (name == "file_stderr") { return true }
|
if (name == "os_argc") or (name == "os_arg") or (name == "os_exit") or (name == "file_stderr") { return true }
|
||||||
|
|
@ -35,19 +34,6 @@ fn emit_intrinsic(name: ptr, e: Node) -> Val {
|
||||||
let w = emit_bind(`zext i32 {n} to i64`)
|
let w = emit_bind(`zext i32 {n} to i64`)
|
||||||
return val(emit_bind(`call ptr @realloc(ptr {p}, i64 {w})`), "ptr")
|
return val(emit_bind(`call ptr @realloc(ptr {p}, i64 {w})`), "ptr")
|
||||||
}
|
}
|
||||||
if (name == "peek8") {
|
|
||||||
let p = arg_code(e, 0); let i = arg_code(e, 1)
|
|
||||||
let a = emit_gep_i8(p, i)
|
|
||||||
let b = emit_bind(`load i8, ptr {a}`)
|
|
||||||
return val(emit_bind(`zext i8 {b} to i32`), "int")
|
|
||||||
}
|
|
||||||
if (name == "poke8") {
|
|
||||||
let p = arg_code(e, 0); let i = arg_code(e, 1); let v = arg_code(e, 2)
|
|
||||||
let a = emit_gep_i8(p, i)
|
|
||||||
let t = emit_bind(`trunc i32 {v} to i8`)
|
|
||||||
emit(" store i8 "); emit(t); emit(", ptr "); emit(a); emit("\n")
|
|
||||||
return val("0", "void")
|
|
||||||
}
|
|
||||||
if (name == "file_open") {
|
if (name == "file_open") {
|
||||||
let p = arg_code(e, 0); let m = arg_code(e, 1)
|
let p = arg_code(e, 0); let m = arg_code(e, 1)
|
||||||
return val(emit_bind(`call ptr @fopen(ptr {p}, ptr {m})`), "ptr")
|
return val(emit_bind(`call ptr @fopen(ptr {p}, ptr {m})`), "ptr")
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ fn emit_assign(st: Node) -> void {
|
||||||
if (st.s == ("/=")) { opc = "sdiv" }
|
if (st.s == ("/=")) { opc = "sdiv" }
|
||||||
v = emit_bind(`{opc} i32 {cur}, {v}`)
|
v = emit_bind(`{opc} i32 {cur}, {v}`)
|
||||||
}
|
}
|
||||||
|
if (lt == "i8") { v = emit_bind(`trunc i32 {v} to i8`) } # narrow to a byte for p[i] = v
|
||||||
store_at(lt, v, addr)
|
store_at(lt, v, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ fn ui_index_of(nm: ptr) -> int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
fn is_ui_ident(nm: ptr) -> bool {
|
fn is_ui_ident(nm: ptr) -> bool {
|
||||||
return len(nm) > 3 and peek8(nm, 0) == 85 and peek8(nm, 1) == 73 and peek8(nm, 2) == 95 # "UI_"
|
return len(nm) > 3 and nm[0] == 85 and nm[1] == 73 and nm[2] == 95 # "UI_"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ll_ui_set(idx: int, key: int, val: ptr) -> void {
|
fn ll_ui_set(idx: int, key: int, val: ptr) -> void {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ fn read_file(path: str) -> ptr {
|
||||||
file_seek(f, 0, 0)
|
file_seek(f, 0, 0)
|
||||||
let buf = mem_alloc(n + 1)
|
let buf = mem_alloc(n + 1)
|
||||||
file_read(f, buf, n)
|
file_read(f, buf, n)
|
||||||
poke8(buf, n, 0)
|
buf[n] = 0
|
||||||
file_close(f)
|
file_close(f)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,6 @@ fn read_file(path: str) -> ptr {
|
||||||
# length of a NUL-terminated buffer
|
# length of a NUL-terminated buffer
|
||||||
fn cstr_len(s: ptr) -> int {
|
fn cstr_len(s: ptr) -> int {
|
||||||
var n = 0
|
var n = 0
|
||||||
while peek8(s, n) != 0 { n = n + 1 }
|
while s[n] != 0 { n = n + 1 }
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ fn tok_push(kind: int, text: ptr, ival: int, line: int) -> void {
|
||||||
|
|
||||||
# does src match the 2-char operator op at position i?
|
# does src match the 2-char operator op at position i?
|
||||||
fn two_at(src: ptr, i: int, a: int, b: int) -> bool {
|
fn two_at(src: ptr, i: int, a: int, b: int) -> bool {
|
||||||
return peek8(src, i) == a and peek8(src, i + 1) == b
|
return src[i] == a and src[i + 1] == b
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_op1(c: int) -> bool {
|
fn is_op1(c: int) -> bool {
|
||||||
|
|
@ -43,11 +43,11 @@ fn lex(src: ptr) -> void {
|
||||||
var line = 1
|
var line = 1
|
||||||
let n = len(src)
|
let n = len(src)
|
||||||
while i < n {
|
while i < n {
|
||||||
let c = peek8(src, i)
|
let c = src[i]
|
||||||
if c == 10 { tok_push(TK_NL, null, 0, line); line = line + 1; i = i + 1; continue }
|
if c == 10 { tok_push(TK_NL, null, 0, line); line = line + 1; i = i + 1; continue }
|
||||||
if c == 32 or c == 9 or c == 13 { i = i + 1; continue }
|
if c == 32 or c == 9 or c == 13 { i = i + 1; continue }
|
||||||
if c == 35 { # '#' comment to end of line
|
if c == 35 { # '#' comment to end of line
|
||||||
while i < n and peek8(src, i) != 10 { i = i + 1 }
|
while i < n and src[i] != 10 { i = i + 1 }
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c == 34 { # "string"
|
if c == 34 { # "string"
|
||||||
|
|
@ -55,18 +55,18 @@ fn lex(src: ptr) -> void {
|
||||||
let start = i
|
let start = i
|
||||||
let out = mem_alloc(n)
|
let out = mem_alloc(n)
|
||||||
var j = 0
|
var j = 0
|
||||||
while i < n and peek8(src, i) != 34 {
|
while i < n and src[i] != 34 {
|
||||||
if peek8(src, i) == 92 { # backslash escape
|
if src[i] == 92 { # backslash escape
|
||||||
let e = peek8(src, i + 1)
|
let e = src[i + 1]
|
||||||
var r = e
|
var r = e
|
||||||
if e == 110 { r = 10 }
|
if e == 110 { r = 10 }
|
||||||
if e == 116 { r = 9 }
|
if e == 116 { r = 9 }
|
||||||
if e == 48 { r = 0 }
|
if e == 48 { r = 0 }
|
||||||
poke8(out, j, r); j = j + 1; i = i + 2
|
out[j] = r; j = j + 1; i = i + 2
|
||||||
} else { poke8(out, j, peek8(src, i)); j = j + 1; i = i + 1 }
|
} else { out[j] = src[i]; j = j + 1; i = i + 1 }
|
||||||
}
|
}
|
||||||
i = i + 1
|
i = i + 1
|
||||||
poke8(out, j, 0)
|
out[j] = 0
|
||||||
tok_push(TK_STR, out, 0, line)
|
tok_push(TK_STR, out, 0, line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -74,32 +74,32 @@ fn lex(src: ptr) -> void {
|
||||||
i = i + 1
|
i = i + 1
|
||||||
let out = mem_alloc(n)
|
let out = mem_alloc(n)
|
||||||
var j = 0
|
var j = 0
|
||||||
while i < n and peek8(src, i) != 96 { poke8(out, j, peek8(src, i)); j = j + 1; i = i + 1 }
|
while i < n and src[i] != 96 { out[j] = src[i]; j = j + 1; i = i + 1 }
|
||||||
i = i + 1
|
i = i + 1
|
||||||
poke8(out, j, 0)
|
out[j] = 0
|
||||||
tok_push(TK_INTERP, out, 0, line)
|
tok_push(TK_INTERP, out, 0, line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c == 39 { # 'c' char literal -> int
|
if c == 39 { # 'c' char literal -> int
|
||||||
i = i + 1
|
i = i + 1
|
||||||
var v = 0
|
var v = 0
|
||||||
if peek8(src, i) == 92 {
|
if src[i] == 92 {
|
||||||
let e = peek8(src, i + 1)
|
let e = src[i + 1]
|
||||||
if e == 110 { v = 10 }
|
if e == 110 { v = 10 }
|
||||||
if e == 116 { v = 9 }
|
if e == 116 { v = 9 }
|
||||||
if e == 48 { v = 0 }
|
if e == 48 { v = 0 }
|
||||||
i = i + 2
|
i = i + 2
|
||||||
} else { v = peek8(src, i); i = i + 1 }
|
} else { v = src[i]; i = i + 1 }
|
||||||
if peek8(src, i) == 39 { i = i + 1 }
|
if src[i] == 39 { i = i + 1 }
|
||||||
tok_push(TK_INT, null, v, line)
|
tok_push(TK_INT, null, v, line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if char_is_digit(c) {
|
if char_is_digit(c) {
|
||||||
if c == 48 and peek8(src, i + 1) == 120 { # 0x hex
|
if c == 48 and src[i + 1] == 120 { # 0x hex
|
||||||
var v = 0
|
var v = 0
|
||||||
i = i + 2
|
i = i + 2
|
||||||
while i < n {
|
while i < n {
|
||||||
let h = peek8(src, i)
|
let h = src[i]
|
||||||
var d = 0
|
var d = 0
|
||||||
if char_is_digit(h) { d = h - 48 }
|
if char_is_digit(h) { d = h - 48 }
|
||||||
else { if h >= 97 and h <= 102 { d = h - 87 }
|
else { if h >= 97 and h <= 102 { d = h - 87 }
|
||||||
|
|
@ -111,12 +111,12 @@ fn lex(src: ptr) -> void {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var 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 }
|
while i < n and char_is_digit(src[i]) { v = v * 10 + (src[i] - 48); i = i + 1 }
|
||||||
# a fractional part makes it a Q16.16 fixed literal
|
# 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)) {
|
if i < n and src[i] == 46 and char_is_digit(src[i + 1]) {
|
||||||
i = i + 1
|
i = i + 1
|
||||||
var fnum = 0; var 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 }
|
while i < n and char_is_digit(src[i]) { fnum = fnum * 10 + (src[i] - 48); fden = fden * 10; i = i + 1 }
|
||||||
let bits = (v << 16) + (fnum << 16) / fden
|
let bits = (v << 16) + (fnum << 16) / fden
|
||||||
tok_push(TK_FLOAT, null, bits, line)
|
tok_push(TK_FLOAT, null, bits, line)
|
||||||
continue
|
continue
|
||||||
|
|
@ -126,7 +126,7 @@ fn lex(src: ptr) -> void {
|
||||||
}
|
}
|
||||||
if char_is_alpha(c) {
|
if char_is_alpha(c) {
|
||||||
let start = i
|
let start = i
|
||||||
while i < n and char_is_alnum(peek8(src, i)) { i = i + 1 }
|
while i < n and char_is_alnum(src[i]) { i = i + 1 }
|
||||||
tok_push(TK_ID, src[start..i], 0, line)
|
tok_push(TK_ID, src[start..i], 0, line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -18,7 +18,7 @@
|
||||||
fn base_name(path: ptr) -> ptr {
|
fn base_name(path: ptr) -> ptr {
|
||||||
var last = 0 - 1
|
var last = 0 - 1
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(path, i) != 0 { if peek8(path, i) == 47 { last = i }; i = i + 1 }
|
while path[i] != 0 { if path[i] == 47 { last = i }; i = i + 1 }
|
||||||
return path[last + 1..i]
|
return path[last + 1..i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ fn getenv_or(name: ptr, dflt: ptr) -> ptr {
|
||||||
fn ensure_slash(d: ptr) -> ptr {
|
fn ensure_slash(d: ptr) -> ptr {
|
||||||
let n = len(d)
|
let n = len(d)
|
||||||
if n == 0 { return d }
|
if n == 0 { return d }
|
||||||
if peek8(d, n - 1) == 47 { return d }
|
if d[n - 1] == 47 { return d }
|
||||||
return (d + ("/"))
|
return (d + ("/"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ entry {
|
||||||
else {
|
else {
|
||||||
# an unknown flag is ignored (with a note) rather than mistaken for the
|
# an unknown flag is ignored (with a note) rather than mistaken for the
|
||||||
# input file — '-' is ASCII 45
|
# input file — '-' is ASCII 45
|
||||||
if peek8(a, 0) == 45 {
|
if a[0] == 45 {
|
||||||
let m = `ludicc: ignoring unknown flag {a}\n`
|
let m = `ludicc: ignoring unknown flag {a}\n`
|
||||||
file_write(file_stderr(), m, len(m))
|
file_write(file_stderr(), m, len(m))
|
||||||
} else { path = a }
|
} else { path = a }
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ fn ptype() -> ptr {
|
||||||
eat_op("]")
|
eat_op("]")
|
||||||
let el = ptype()
|
let el = ptype()
|
||||||
let out = mem_alloc(len(el) + 3)
|
let out = mem_alloc(len(el) + 3)
|
||||||
poke8(out, 0, 91); poke8(out, 1, 93) # "[]"
|
out[0] = 91; out[1] = 93 # "[]"
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(el, i) != 0 { poke8(out, 2 + i, peek8(el, i)); i = i + 1 }
|
while el[i] != 0 { out[2 + i] = el[i]; i = i + 1 }
|
||||||
poke8(out, 2 + i, 0)
|
out[2 + i] = 0
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
return eat_id()
|
return eat_id()
|
||||||
|
|
@ -79,15 +79,15 @@ fn parse_interp(raw: ptr) -> Node {
|
||||||
var lj = 0
|
var lj = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < n {
|
while i < n {
|
||||||
let c = peek8(raw, i)
|
let c = raw[i]
|
||||||
if c == 123 { # '{'
|
if c == 123 { # '{'
|
||||||
if peek8(raw, i + 1) == 123 { poke8(lit, lj, 123); lj = lj + 1; i = i + 2; continue } # {{ -> {
|
if raw[i + 1] == 123 { lit[lj] = 123; lj = lj + 1; i = i + 2; continue } # {{ -> {
|
||||||
if lj > 0 { acc = interp_add(acc, interp_lit(lit, lj)); lj = 0 }
|
if lj > 0 { acc = interp_add(acc, interp_lit(lit, lj)); lj = 0 }
|
||||||
i = i + 1
|
i = i + 1
|
||||||
let hs = i
|
let hs = i
|
||||||
var depth = 1
|
var depth = 1
|
||||||
while i < n and depth > 0 {
|
while i < n and depth > 0 {
|
||||||
let d = peek8(raw, i)
|
let d = raw[i]
|
||||||
if d == 123 { depth = depth + 1 }
|
if d == 123 { depth = depth + 1 }
|
||||||
else { if d == 125 { depth = depth - 1; if depth == 0 { break } } }
|
else { if d == 125 { depth = depth - 1; if depth == 0 { break } } }
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
@ -95,14 +95,14 @@ fn parse_interp(raw: ptr) -> Node {
|
||||||
acc = interp_add(acc, interp_str(parse_hole(raw[hs..i])))
|
acc = interp_add(acc, interp_str(parse_hole(raw[hs..i])))
|
||||||
i = i + 1 # skip the closing '}'
|
i = i + 1 # skip the closing '}'
|
||||||
} else {
|
} else {
|
||||||
if c == 125 and peek8(raw, i + 1) == 125 { poke8(lit, lj, 125); lj = lj + 1; i = i + 2; continue } # }} -> }
|
if c == 125 and raw[i + 1] == 125 { lit[lj] = 125; lj = lj + 1; i = i + 2; continue } # }} -> }
|
||||||
if c == 92 { # backslash escape in literal text
|
if c == 92 { # backslash escape in literal text
|
||||||
let e = peek8(raw, i + 1); var r = e
|
let e = raw[i + 1]; var r = e
|
||||||
if e == 110 { r = 10 }
|
if e == 110 { r = 10 }
|
||||||
if e == 116 { r = 9 }
|
if e == 116 { r = 9 }
|
||||||
poke8(lit, lj, r); lj = lj + 1; i = i + 2; continue
|
lit[lj] = r; lj = lj + 1; i = i + 2; continue
|
||||||
}
|
}
|
||||||
poke8(lit, lj, c); lj = lj + 1; i = i + 1
|
lit[lj] = c; lj = lj + 1; i = i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if lj > 0 or (acc == null) { acc = interp_add(acc, interp_lit(lit, lj)) }
|
if lj > 0 or (acc == null) { acc = interp_add(acc, interp_lit(lit, lj)) }
|
||||||
|
|
@ -311,12 +311,12 @@ fn parse_main() -> Node { pi = pi + 1; let n = node(N_MAIN); n.a = block(); retu
|
||||||
fn dir_of(path: ptr) -> ptr {
|
fn dir_of(path: ptr) -> ptr {
|
||||||
var last = 0 - 1
|
var last = 0 - 1
|
||||||
var i = 0
|
var i = 0
|
||||||
while peek8(path, i) != 0 { if peek8(path, i) == 47 { last = i }; i = i + 1 }
|
while path[i] != 0 { if path[i] == 47 { last = i }; i = i + 1 }
|
||||||
if last < 0 { return "" }
|
if last < 0 { return "" }
|
||||||
return path[0..0 + (last + 1)]
|
return path[0..0 + (last + 1)]
|
||||||
}
|
}
|
||||||
fn path_join(dir: ptr, rel: ptr) -> ptr {
|
fn path_join(dir: ptr, rel: ptr) -> ptr {
|
||||||
if peek8(rel, 0) == 47 { return rel } # absolute
|
if rel[0] == 47 { return rel } # absolute
|
||||||
return (dir + rel)
|
return (dir + rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,20 @@ fn char_is_alnum(c: int) -> bool { return char_is_alpha(c) or char_is_digit(c) }
|
||||||
|
|
||||||
# integer -> fresh decimal string
|
# integer -> fresh decimal string
|
||||||
fn itoa(v: int) -> ptr {
|
fn itoa(v: int) -> ptr {
|
||||||
if v == 0 { let z = mem_alloc(2); poke8(z, 0, 48); poke8(z, 1, 0); return z }
|
if v == 0 { let z = mem_alloc(2); z[0] = 48; z[1] = 0; return z }
|
||||||
var neg = false
|
var neg = false
|
||||||
var x = v
|
var x = v
|
||||||
if x < 0 { neg = true; x = 0 - x }
|
if x < 0 { neg = true; x = 0 - x }
|
||||||
let tmp = mem_alloc(16)
|
let tmp = mem_alloc(16)
|
||||||
var n = 0
|
var n = 0
|
||||||
while x > 0 { poke8(tmp, n, 48 + x % 10); x = x / 10; n = n + 1 }
|
while x > 0 { tmp[n] = 48 + x % 10; x = x / 10; n = n + 1 }
|
||||||
var total = n
|
var total = n
|
||||||
if neg { total = total + 1 }
|
if neg { total = total + 1 }
|
||||||
let out = mem_alloc(total + 1)
|
let out = mem_alloc(total + 1)
|
||||||
var k = 0
|
var k = 0
|
||||||
if neg { poke8(out, 0, 45); k = 1 }
|
if neg { out[0] = 45; k = 1 }
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < n { poke8(out, k + i, peek8(tmp, n - 1 - i)); i = i + 1 }
|
while i < n { out[k + i] = tmp[n - 1 - i]; i = i + 1 }
|
||||||
poke8(out, total, 0)
|
out[total] = 0
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ object LudicVocabulary {
|
||||||
"ui_focused", "ui_visible", "key", "reg", "set_reg", "self", "save", "load",
|
"ui_focused", "ui_visible", "key", "reg", "set_reg", "self", "save", "load",
|
||||||
"status", "print", "str", "quit",
|
"status", "print", "str", "quit",
|
||||||
// compiler intrinsics: the floor the Ludic-written runtime stands on
|
// compiler intrinsics: the floor the Ludic-written runtime stands on
|
||||||
"mem_alloc", "mem_realloc", "mem_free", "mem_copy", "mem_set", "peek8", "poke8", "peek32",
|
"mem_alloc", "mem_realloc", "mem_free", "mem_copy", "mem_set", "peek32",
|
||||||
"os_argc", "os_arg", "file_stderr", "file_stdout",
|
"os_argc", "os_arg", "file_stderr", "file_stdout",
|
||||||
"poke32", "peekp", "pokep", "peekf", "pokef", "ptr_add",
|
"poke32", "peekp", "pokep", "peekf", "pokef", "ptr_add",
|
||||||
"as_fixed", "as_int", "file_open", "file_read", "file_write",
|
"as_fixed", "as_int", "file_open", "file_read", "file_write",
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@
|
||||||
{
|
{
|
||||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||||
"name": "support.function.intrinsic.ludic",
|
"name": "support.function.intrinsic.ludic",
|
||||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek32|poke32|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@
|
||||||
{
|
{
|
||||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||||
"name": "support.function.intrinsic.ludic",
|
"name": "support.function.intrinsic.ludic",
|
||||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek32|poke32|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,6 @@ static const LBuiltin LUDIC_INTRINSICS[] = {
|
||||||
{"mem_free","mem_free(p: ptr)","Release an allocation."},
|
{"mem_free","mem_free(p: ptr)","Release an allocation."},
|
||||||
{"mem_copy","mem_copy(dst: ptr, src: ptr, n: int)","memcpy."},
|
{"mem_copy","mem_copy(dst: ptr, src: ptr, n: int)","memcpy."},
|
||||||
{"mem_set","mem_set(p: ptr, byte: int, n: int)","memset."},
|
{"mem_set","mem_set(p: ptr, byte: int, n: int)","memset."},
|
||||||
{"peek8","peek8(p: ptr, off: int) -> int","Read one byte."},
|
|
||||||
{"poke8","poke8(p: ptr, off: int, v: int)","Write one byte."},
|
|
||||||
{"peek32","peek32(p: ptr, off: int) -> int","Read a 32-bit word."},
|
{"peek32","peek32(p: ptr, off: int) -> int","Read a 32-bit word."},
|
||||||
{"poke32","poke32(p: ptr, off: int, v: int)","Write a 32-bit word."},
|
{"poke32","poke32(p: ptr, off: int, v: int)","Write a 32-bit word."},
|
||||||
{"peekp","peekp(p: ptr, off: int) -> ptr","Read a pointer-sized word."},
|
{"peekp","peekp(p: ptr, off: int) -> ptr","Read a pointer-sized word."},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue