Phase 4b: enum types name magic-int value spaces
enum Name { A, B, C } declares named int constants; Enum.Variant is a
compile-time int (index by declaration order), usable in match patterns,
comparisons, setreg. New: parse_enum + dispatch, enum_ordinal resolver
(emit_core), Enum.Variant handling (emit_expr). Scoped to a naming layer over
int (no enum-typed variables), so register/save semantics are untouched.
combat.ludic battle menus dispatch on KnightAct/MageAct instead of 0..3;
chronorift golden byte-identical. Editor vocab (ludic_syntax.h, JetBrains,
TextMate, emacs) gained enum, dropped retired edge/export/pure decl keywords;
check-vocabulary + test-tools 28/0. when/if kept by choice; bitwise stays
functions. Reseeded, fixpoint holds, test.sh 14/14.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
fd0b890acc
commit
f87964c5f7
14 changed files with 3021 additions and 2672 deletions
|
|
@ -15,6 +15,7 @@ const N_SYS: int = 9
|
|||
const N_ARCH: int = 10
|
||||
const N_EXTERN: int = 11
|
||||
const N_UI: int = 12
|
||||
const N_ENUM: int = 27 # enum Name { A, B, ... } — named int constants
|
||||
# statements
|
||||
const S_LET: int = 10
|
||||
const S_ASSIGN: int = 11
|
||||
|
|
|
|||
|
|
@ -119,6 +119,21 @@ fn find_global(name: ptr) -> Node {
|
|||
}
|
||||
return ptr_null()
|
||||
}
|
||||
|
||||
# `Enum.Variant` -> the variant's ordinal (its index), or -1 if `ename` names no
|
||||
# enum with that variant. Enum names live in `prog` like any other declaration.
|
||||
fn enum_ordinal(ename: ptr, vname: ptr) -> int {
|
||||
let i = 0
|
||||
while i < len(prog) {
|
||||
let d = prog[i]
|
||||
if d.kind == N_ENUM and streq(d.s, ename) {
|
||||
let j = 0
|
||||
while j < len(d.kids) { if streq(d.kids[j].s, vname) { return j }; j = j + 1 }
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return 0 - 1
|
||||
}
|
||||
fn find_fn(name: ptr) -> Node {
|
||||
let i = 0
|
||||
while i < len(prog) { let d = prog[i]; if d.kind == N_FN and streq(d.s, name) { return d }; i = i + 1 }
|
||||
|
|
|
|||
|
|
@ -152,7 +152,13 @@ fn emit_expr(e: Node) -> Val {
|
|||
if is_ui_ident(e.s) { return val(itoa(ui_index_of(e.s)), "int") }
|
||||
perr(sconcat("unknown identifier ", e.s))
|
||||
}
|
||||
if e.kind == E_MEMBER { let a = emit_member_addr(e); return emit_load_at(a, g_addr_ty) }
|
||||
if e.kind == E_MEMBER {
|
||||
if e.a.kind == E_ID { # `Enum.Variant` -> its ordinal, a compile-time int
|
||||
let ord = enum_ordinal(e.a.s, e.s)
|
||||
if ord >= 0 { return val(itoa(ord), "int") }
|
||||
}
|
||||
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_CALL { return emit_call(e) }
|
||||
if e.kind == E_BIN { return emit_bin(e) }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -296,6 +296,7 @@ fn parse_one_decl() -> void {
|
|||
return
|
||||
}
|
||||
if is_id("struct") { push(prog, parse_struct()); return }
|
||||
if is_id("enum") { push(prog, parse_enum()); return }
|
||||
if is_id("component") { push(prog, parse_component()); return }
|
||||
if is_id("archetype") { push(prog, parse_archetype()); return }
|
||||
if is_id("system") { push(prog, parse_system()); return }
|
||||
|
|
|
|||
|
|
@ -96,6 +96,17 @@ fn parse_spawn() -> Node {
|
|||
eat_op("}"); return n
|
||||
}
|
||||
|
||||
# enum Name { A, B, C } — named int constants; a variant's value is its index.
|
||||
# Accessed as `Name.A` (a compile-time int), so it names magic-int value spaces
|
||||
# (state ids, menu selections, mode registers) without a runtime cost.
|
||||
fn parse_enum() -> Node {
|
||||
pi = pi + 1; let n = node(N_ENUM); n.s = eat_id(); skipnl(); eat_op("{")
|
||||
while true { skipnl(); if is_op("}") { break }
|
||||
let v = node(E_ID); v.s = eat_id(); push(n.kids, v)
|
||||
if is_op(",") { pi = pi + 1 }; skipnl() }
|
||||
eat_op("}"); return n
|
||||
}
|
||||
|
||||
# archetype Name { CompA, CompB } — a named entity kind (bundle of components)
|
||||
fn parse_archetype() -> Node {
|
||||
pi = pi + 1; let n = node(N_ARCH); n.s = eat_id(); skipnl(); eat_op("{")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue