refactor(runtime,packages,examples): named constants, package enums, idiom sweep
- runtime: HEADLESS_FRAME_PATH, STICK_DEADZONE / STICK_LEFT_X/Y, key and byte codes as char literals throughout (`k == 'w'`, `fill(rt_map, ' ', …)`) - ludic.gameplay/stats: drop the duplicate `stat_field` (it answered "atk" for every build stat); Stats.base uses stats_field_name - ludic.shooter: compare aim modes and fire patterns with AimMode.* and WeaponPattern.* instead of raw ints; STICK_RIGHT_X/Y - ludic.npcai: DecisionMade / brain_set_state use AiState.* - examples/games/menu.ludic uses Font.load / Ui.* with FONT_PATH and BACKDROP named; strings.ludic header says what it prints - whole tree: `x = x + 1` → `x += 1` (single-term right-hand sides only), `0 - x` → `-x`, ASCII codes → char literals; every .ludic and every ```ludic fence reformatted with the fixed formatter (whitespace only) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e3e1bc7784
commit
bf36bc8a8f
103 changed files with 1256 additions and 1252 deletions
|
|
@ -25,7 +25,7 @@
|
|||
# ============================================================================
|
||||
|
||||
# ---- small helpers ----------------------------------------------------------
|
||||
function rx_slen(s: pointer) -> int { var n = 0; while s[n] != 0 { n = n + 1 }; return n }
|
||||
function rx_slen(s: pointer) -> int { var n = 0; while s[n] != 0 { n += 1 }; return n }
|
||||
|
||||
# ---- growable int vector ----------------------------------------------------
|
||||
property IVec { d: words, n: int, cap: int }
|
||||
|
|
@ -37,17 +37,17 @@ function iv_new() -> IVec {
|
|||
function iv_grow(v: IVec, need: int) -> void {
|
||||
if v.n + need <= v.cap { return }
|
||||
var nc = v.cap * 2
|
||||
while nc < v.n + need { nc = nc * 2 }
|
||||
while nc < v.n + need { nc *= 2 }
|
||||
let nd = words(nc)
|
||||
var i = 0
|
||||
while i < v.n { nd[i] = v.d[i]; i = i + 1 }
|
||||
while i < v.n { nd[i] = v.d[i]; i += 1 }
|
||||
v.d = nd; v.cap = nc
|
||||
}
|
||||
function iv_push(v: IVec, x: int) -> int {
|
||||
iv_grow(v, 1)
|
||||
let idx = v.n
|
||||
v.d[v.n] = x
|
||||
v.n = v.n + 1
|
||||
v.n += 1
|
||||
return idx
|
||||
}
|
||||
|
||||
|
|
@ -80,13 +80,13 @@ const N_EMPTY: int = 13
|
|||
|
||||
property RNode {
|
||||
op: int = 0, ch: int = 0, cls: int = 0, lo: int = 0, hi: int = 0,
|
||||
greedy: int = 1, gidx: int = 0 - 1, kids: []RNode
|
||||
greedy: int = 1, gidx: int = -1, kids: []RNode
|
||||
}
|
||||
function rx_node(op: int) -> RNode {
|
||||
let n = new RNode
|
||||
n.op = op
|
||||
n.greedy = 1
|
||||
n.gidx = 0 - 1
|
||||
n.gidx = -1
|
||||
n.kids = new []RNode
|
||||
return n
|
||||
}
|
||||
|
|
@ -101,16 +101,16 @@ var rx_err: int = 0
|
|||
var rx_ngroup: int = 0
|
||||
var rx_prog: Prog = null
|
||||
|
||||
function rx_peek() -> int { if rx_pos < rx_len { return rx_pat[rx_pos] & 255 }; return 0 - 1 }
|
||||
function rx_peek2() -> int { if rx_pos + 1 < rx_len { return rx_pat[rx_pos + 1] & 255 }; return 0 - 1 }
|
||||
function rx_adv() -> int { let c = rx_peek(); rx_pos = rx_pos + 1; return c }
|
||||
function rx_peek() -> int { if rx_pos < rx_len { return rx_pat[rx_pos] & 255 }; return -1 }
|
||||
function rx_peek2() -> int { if rx_pos + 1 < rx_len { return rx_pat[rx_pos + 1] & 255 }; return -1 }
|
||||
function rx_adv() -> int { let c = rx_peek(); rx_pos += 1; return c }
|
||||
|
||||
# ---- character classes ------------------------------------------------------
|
||||
# a class is 8 i32 words (256 bits) in prog.cls; class k occupies cls[8k .. 8k+8)
|
||||
function rx_class_new() -> int {
|
||||
let idx = rx_prog.cls.n / 8
|
||||
var i = 0
|
||||
while i < 8 { iv_push(rx_prog.cls, 0); i = i + 1 }
|
||||
while i < 8 { iv_push(rx_prog.cls, 0); i += 1 }
|
||||
return idx
|
||||
}
|
||||
function rx_class_set(idx: int, c: int) -> void {
|
||||
|
|
@ -119,11 +119,11 @@ function rx_class_set(idx: int, c: int) -> void {
|
|||
}
|
||||
function rx_class_set_range(idx: int, a: int, b: int) -> void {
|
||||
var c = a
|
||||
while c <= b { rx_class_set(idx, c); c = c + 1 }
|
||||
while c <= b { rx_class_set(idx, c); c += 1 }
|
||||
}
|
||||
function rx_class_negate(idx: int) -> void {
|
||||
var i = 0
|
||||
while i < 8 { let w = idx * 8 + i; rx_prog.cls.d[w] = ~rx_prog.cls.d[w]; i = i + 1 }
|
||||
while i < 8 { let w = idx * 8 + i; rx_prog.cls.d[w] = ~rx_prog.cls.d[w]; i += 1 }
|
||||
}
|
||||
function rx_class_unset(idx: int, c: int) -> void {
|
||||
let w = idx * 8 + (c >> 5)
|
||||
|
|
@ -131,11 +131,11 @@ function rx_class_unset(idx: int, c: int) -> void {
|
|||
}
|
||||
function rx_class_unset_range(idx: int, a: int, b: int) -> void {
|
||||
var c = a
|
||||
while c <= b { rx_class_unset(idx, c); c = c + 1 }
|
||||
while c <= b { rx_class_unset(idx, c); c += 1 }
|
||||
}
|
||||
function rx_class_set_all(idx: int) -> void {
|
||||
var i = 0
|
||||
while i < 8 { rx_prog.cls.d[idx * 8 + i] = 0 - 1; i = i + 1 }
|
||||
while i < 8 { rx_prog.cls.d[idx * 8 + i] = -1; i += 1 }
|
||||
}
|
||||
function rx_class_set_word(idx: int) -> void {
|
||||
rx_class_set_range(idx, 48, 57)
|
||||
|
|
@ -151,12 +151,12 @@ function rx_class_has(prog: Prog, idx: int, c: int) -> bool {
|
|||
let w = prog.cls.d[idx * 8 + (c >> 5)]
|
||||
return (w & (1 << (c & 31))) != 0
|
||||
}
|
||||
function rx_is_digit(c: int) -> bool { return c >= 48 and c <= 57 }
|
||||
function rx_is_digit(c: int) -> bool { return c >= '0' and c <= '9' }
|
||||
function rx_is_word(c: int) -> bool {
|
||||
return (c >= 48 and c <= 57) or (c >= 65 and c <= 90) or (c >= 97 and c <= 122) or c == 95
|
||||
return (c >= '0' and c <= '9') or (c >= 'A' and c <= 'Z') or (c >= 'a' and c <= 'z') or c == '_'
|
||||
}
|
||||
function rx_is_ws(c: int) -> bool {
|
||||
return c == 32 or c == 9 or c == 10 or c == 13 or c == 12 or c == 11
|
||||
return c == ' ' or c == '\t' or c == '\n' or c == '\r' or c == 12 or c == 11
|
||||
}
|
||||
# OR the set named by \d \D \w \W \s \S into class idx. The negated forms OR in
|
||||
# the complement set bit-by-bit (never via set-all+unset, which would clobber a
|
||||
|
|
@ -170,7 +170,7 @@ function rx_class_add_pre(idx: int, kind: int) -> void {
|
|||
if kind == 68 { if not rx_is_digit(c) { rx_class_set(idx, c) } } # \D
|
||||
else if kind == 87 { if not rx_is_word(c) { rx_class_set(idx, c) } } # \W
|
||||
else if kind == 83 { if not rx_is_ws(c) { rx_class_set(idx, c) } } # \S
|
||||
c = c + 1
|
||||
c += 1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ function rx_parse_class() -> RNode {
|
|||
var lo = rx_adv()
|
||||
if lo == 92 { # escape inside class
|
||||
let e = rx_adv()
|
||||
if e == 100 or e == 68 or e == 119 or e == 87 or e == 115 or e == 83 {
|
||||
if e == 'd' or e == 'D' or e == 'w' or e == 'W' or e == 's' or e == 'S' {
|
||||
rx_class_add_pre(idx, e)
|
||||
continue
|
||||
}
|
||||
|
|
@ -210,12 +210,12 @@ function rx_parse_class() -> RNode {
|
|||
}
|
||||
# map an escaped char inside a class to its byte
|
||||
function rx_class_escape_char(e: int) -> int {
|
||||
if e == 110 { return 10 }
|
||||
if e == 116 { return 9 }
|
||||
if e == 114 { return 13 }
|
||||
if e == 102 { return 12 }
|
||||
if e == 118 { return 11 }
|
||||
if e == 48 { return 0 }
|
||||
if e == 'n' { return 10 }
|
||||
if e == 't' { return 9 }
|
||||
if e == 'r' { return 13 }
|
||||
if e == 'f' { return 12 }
|
||||
if e == 'v' { return 11 }
|
||||
if e == '0' { return 0 }
|
||||
return e
|
||||
}
|
||||
|
||||
|
|
@ -223,21 +223,21 @@ function rx_class_escape_char(e: int) -> int {
|
|||
function rx_parse_escape() -> RNode {
|
||||
rx_adv() # consume '\'
|
||||
let e = rx_adv()
|
||||
if e == 100 or e == 68 or e == 119 or e == 87 or e == 115 or e == 83 {
|
||||
if e == 'd' or e == 'D' or e == 'w' or e == 'W' or e == 's' or e == 'S' {
|
||||
let idx = rx_class_new()
|
||||
rx_class_add_pre(idx, e)
|
||||
let node = rx_node(N_CLASS)
|
||||
node.cls = idx
|
||||
return node
|
||||
}
|
||||
if e >= 49 and e <= 57 { rx_err = 1; return rx_node(N_EMPTY) } # backrefs unsupported
|
||||
if e >= '1' and e <= '9' { rx_err = 1; return rx_node(N_EMPTY) } # backrefs unsupported
|
||||
var ch = e
|
||||
if e == 110 { ch = 10 }
|
||||
else if e == 116 { ch = 9 }
|
||||
else if e == 114 { ch = 13 }
|
||||
else if e == 102 { ch = 12 }
|
||||
else if e == 118 { ch = 11 }
|
||||
else if e == 48 { ch = 0 }
|
||||
if e == 'n' { ch = 10 }
|
||||
else if e == 't' { ch = 9 }
|
||||
else if e == 'r' { ch = 13 }
|
||||
else if e == 'f' { ch = 12 }
|
||||
else if e == 'v' { ch = 11 }
|
||||
else if e == '0' { ch = 0 }
|
||||
else if e < 0 { rx_err = 1; return rx_node(N_EMPTY) }
|
||||
let node = rx_node(N_LIT)
|
||||
node.ch = ch
|
||||
|
|
@ -261,7 +261,7 @@ function rx_parse_concat() -> RNode {
|
|||
let cat = rx_node(N_CONCAT)
|
||||
while true {
|
||||
let c = rx_peek()
|
||||
if c < 0 or c == 124 or c == 41 { break }
|
||||
if c < 0 or c == '|' or c == ')' { break }
|
||||
push(cat.kids, rx_parse_repeat())
|
||||
if rx_err == 1 { break }
|
||||
}
|
||||
|
|
@ -278,17 +278,17 @@ function rx_parse_repeat() -> RNode {
|
|||
let atom = rx_parse_atom()
|
||||
if rx_err == 1 { return atom }
|
||||
let c = rx_peek()
|
||||
if c == 42 or c == 43 or c == 63 {
|
||||
if c == '*' or c == '+' or c == '?' {
|
||||
rx_adv()
|
||||
var op = N_STAR
|
||||
if c == 43 { op = N_PLUS }
|
||||
if c == 63 { op = N_QUEST }
|
||||
if c == '+' { op = N_PLUS }
|
||||
if c == '?' { op = N_QUEST }
|
||||
let r = rx_node(op)
|
||||
r.greedy = rx_lazy()
|
||||
push(r.kids, atom)
|
||||
return r
|
||||
}
|
||||
if c == 123 { return rx_parse_brace(atom) }
|
||||
if c == '{' { return rx_parse_brace(atom) }
|
||||
return atom
|
||||
}
|
||||
# {n} {n,} {n,m}
|
||||
|
|
@ -300,7 +300,7 @@ function rx_parse_brace(atom: RNode) -> RNode {
|
|||
while rx_peek() >= 48 and rx_peek() <= 57 { lo = lo * 10 + (rx_adv() - 48); haslo = true }
|
||||
var hi = lo
|
||||
var hasComma = false
|
||||
if rx_peek() == 44 { hasComma = true; rx_adv(); hi = 0 - 1
|
||||
if rx_peek() == 44 { hasComma = true; rx_adv(); hi = -1
|
||||
var hashi = false
|
||||
while rx_peek() >= 48 and rx_peek() <= 57 { if not hashi { hi = 0 }; hi = hi * 10 + (rx_adv() - 48); hashi = true }
|
||||
}
|
||||
|
|
@ -319,18 +319,18 @@ function rx_parse_brace(atom: RNode) -> RNode {
|
|||
}
|
||||
function rx_parse_atom() -> RNode {
|
||||
let c = rx_peek()
|
||||
if c == 40 { # '('
|
||||
if c == '(' { # '('
|
||||
rx_adv()
|
||||
var gidx = 0 - 1
|
||||
var gidx = -1
|
||||
if rx_peek() == 63 { # (? ...
|
||||
rx_adv()
|
||||
let d = rx_peek()
|
||||
if d == 58 { rx_adv() } # (?: non-capturing
|
||||
else if d == 80 { rx_adv(); rx_skip_name() } # (?P<name> (captured, name ignored for now)
|
||||
else if d == 60 { rx_skip_name() } # (?<name>
|
||||
if d == ':' { rx_adv() } # (?: non-capturing
|
||||
else if d == 'P' { rx_adv(); rx_skip_name() } # (?P<name> (captured, name ignored for now)
|
||||
else if d == '<' { rx_skip_name() } # (?<name>
|
||||
else { rx_err = 1; return rx_node(N_EMPTY) }
|
||||
} else {
|
||||
rx_ngroup = rx_ngroup + 1
|
||||
rx_ngroup += 1
|
||||
gidx = rx_ngroup
|
||||
}
|
||||
let inner = rx_parse_alt()
|
||||
|
|
@ -341,12 +341,12 @@ function rx_parse_atom() -> RNode {
|
|||
push(g.kids, inner)
|
||||
return g
|
||||
}
|
||||
if c == 91 { return rx_parse_class() }
|
||||
if c == 46 { rx_adv(); return rx_node(N_ANY) }
|
||||
if c == 94 { rx_adv(); return rx_node(N_BOL) }
|
||||
if c == 36 { rx_adv(); return rx_node(N_EOL) }
|
||||
if c == 92 { return rx_parse_escape() }
|
||||
if c == 42 or c == 43 or c == 63 or c == 41 { rx_err = 1; return rx_node(N_EMPTY) }
|
||||
if c == '[' { return rx_parse_class() }
|
||||
if c == '.' { rx_adv(); return rx_node(N_ANY) }
|
||||
if c == '^' { rx_adv(); return rx_node(N_BOL) }
|
||||
if c == '$' { rx_adv(); return rx_node(N_EOL) }
|
||||
if c == '\\' { return rx_parse_escape() }
|
||||
if c == '*' or c == '+' or c == '?' or c == ')' { rx_err = 1; return rx_node(N_EMPTY) }
|
||||
if c < 0 { rx_err = 1; return rx_node(N_EMPTY) }
|
||||
rx_adv()
|
||||
let n = rx_node(N_LIT)
|
||||
|
|
@ -359,7 +359,7 @@ function rx_skip_name() -> void {
|
|||
if rx_peek() == 60 { rx_adv() } # consume '<'
|
||||
while rx_peek() != 62 and rx_peek() >= 0 { rx_adv() }
|
||||
if rx_peek() == 62 { rx_adv() } # consume '>'
|
||||
rx_ngroup = rx_ngroup + 1
|
||||
rx_ngroup += 1
|
||||
# note: the caller set gidx = -1; fix it up to a real capture index
|
||||
rx_named_gidx = rx_ngroup
|
||||
}
|
||||
|
|
@ -387,7 +387,7 @@ function rx_compile(node: RNode) -> void {
|
|||
if op == N_EOL { pg_emit(OP_EOL, 0, 0); return }
|
||||
if op == N_CONCAT {
|
||||
var i = 0
|
||||
while i < len(node.kids) { rx_compile(node.kids[i]); i = i + 1 }
|
||||
while i < len(node.kids) { rx_compile(node.kids[i]); i += 1 }
|
||||
return
|
||||
}
|
||||
if op == N_GROUP {
|
||||
|
|
@ -414,11 +414,11 @@ function rx_compile(node: RNode) -> void {
|
|||
} else {
|
||||
rx_compile(node.kids[i])
|
||||
}
|
||||
i = i + 1
|
||||
i += 1
|
||||
}
|
||||
let end = pg_pc()
|
||||
i = 0
|
||||
while i < jmps.n { pg_set_a(jmps.d[i], end); i = i + 1 }
|
||||
while i < jmps.n { pg_set_a(jmps.d[i], end); i += 1 }
|
||||
return
|
||||
}
|
||||
if op == N_STAR {
|
||||
|
|
@ -453,7 +453,7 @@ function rx_compile(node: RNode) -> void {
|
|||
if op == N_REP {
|
||||
let kid = node.kids[0]
|
||||
var i = 0
|
||||
while i < node.lo { rx_compile(kid); i = i + 1 }
|
||||
while i < node.lo { rx_compile(kid); i += 1 }
|
||||
if node.hi < 0 {
|
||||
let st = rx_node(N_STAR)
|
||||
st.greedy = node.greedy
|
||||
|
|
@ -466,7 +466,7 @@ function rx_compile(node: RNode) -> void {
|
|||
q.greedy = node.greedy
|
||||
push(q.kids, kid)
|
||||
rx_compile(q)
|
||||
i = i + 1
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -503,4 +503,3 @@ function regex_compile(pattern: pointer) -> Prog {
|
|||
pg_emit(OP_MATCH, 0, 0)
|
||||
return p
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue