refactor(lang): rename the fn keyword to function
Expand the function-declaration keyword to the full word across the whole
language and toolchain:
fn name(...) -> T { ... } -> function name(...) -> T { ... }
Done as a self-hosting migration: teach the parser both spellings, reseed,
rewrite every .ludic definition to `function`, then drop `fn`. The compiler
now rejects `fn`. Touches the parser, all selfhost/tools/runtime/example/test
sources, the grammars (TextMate shared+vscode, ludic_syntax.h, JetBrains
LudicTokens.kt), the LSP and formatter, the Python doc/vocab tools
(check-impl, check-docs, validate, palette, test-lsp), and the docs
(fences, prose, kw-fn -> kw-function).
Reseeded; C-free bootstrap fixpoint holds. All suites green (45 regression,
24 self-host, 29 tool); the docs site generates and check.py passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2f19c8d8e2
commit
4c48077d68
86 changed files with 793 additions and 793 deletions
|
|
@ -19,11 +19,11 @@ var g_uses_loopback: bool = false
|
|||
# component participates in the entity's model (the model member is @Sync,
|
||||
# member.ival==1). Participation is decided per model use-site.
|
||||
|
||||
fn net_field_ibytes(ty: ptr) -> int { if (llty(ty) == "i8") { return 1 }; return 4 }
|
||||
fn net_field_bytes(ty: ptr) -> ptr { if (llty(ty) == "i8") { return "1" }; return "4" }
|
||||
function net_field_ibytes(ty: ptr) -> int { if (llty(ty) == "i8") { return 1 }; return 4 }
|
||||
function net_field_bytes(ty: ptr) -> ptr { if (llty(ty) == "i8") { return "1" }; return "4" }
|
||||
|
||||
# total replicated bytes for model m (compile-time constant)
|
||||
fn net_model_bytes(m: Node) -> int {
|
||||
function net_model_bytes(m: Node) -> int {
|
||||
var total = 0
|
||||
var ci = 0
|
||||
while ci < len(m.kids) {
|
||||
|
|
@ -39,16 +39,16 @@ fn net_model_bytes(m: Node) -> int {
|
|||
return total
|
||||
}
|
||||
|
||||
fn net_model_syncs(m: Node) -> bool { return net_model_bytes(m) > 0 }
|
||||
function net_model_syncs(m: Node) -> bool { return net_model_bytes(m) > 0 }
|
||||
|
||||
fn net_has_sync() -> bool {
|
||||
function net_has_sync() -> bool {
|
||||
var i = 0
|
||||
while i < len(prog) { if prog[i].kind == N_ARCH { if net_model_syncs(prog[i]) { return true } }; i = i + 1 }
|
||||
return false
|
||||
}
|
||||
|
||||
# ---- N3: ownership -----------------------------------------------------------
|
||||
fn net_has_owned() -> bool {
|
||||
function net_has_owned() -> bool {
|
||||
var i = 0
|
||||
while i < len(prog) { if prog[i].kind == N_ARCH and (prog[i].ival == 1) { return true }; i = i + 1 }
|
||||
return false
|
||||
|
|
@ -56,7 +56,7 @@ fn net_has_owned() -> bool {
|
|||
|
||||
# ---- N5: role-tagged handlers ------------------------------------------------
|
||||
# A handler tagged @Server (ival==1) or @Predicted (ival==2) has a network role.
|
||||
fn net_has_role() -> bool {
|
||||
function net_has_role() -> bool {
|
||||
var i = 0
|
||||
while i < len(prog) { if prog[i].kind == N_SYS and (prog[i].ival != 0) { return true }; i = i + 1 }
|
||||
return false
|
||||
|
|
@ -64,10 +64,10 @@ fn net_has_role() -> bool {
|
|||
|
||||
# Any networking feature in use → emit the shared role registers (@L_role /
|
||||
# @L_localid). A runtime sets them; offline they keep their single-player default.
|
||||
fn net_any() -> bool { return net_has_sync() or net_has_owned() or net_has_role() }
|
||||
function net_any() -> bool { return net_has_sync() or net_has_owned() or net_has_role() }
|
||||
|
||||
# ---- diagnostics -------------------------------------------------------------
|
||||
fn net_warn(msg: ptr) -> void {
|
||||
function net_warn(msg: ptr) -> void {
|
||||
let e = file_stderr()
|
||||
file_write(e, "ludicc(self): warning: ", 23)
|
||||
file_write(e, msg, len(msg))
|
||||
|
|
@ -77,7 +77,7 @@ fn net_warn(msg: ptr) -> void {
|
|||
# Validate @Sync usage: a participating member whose component replicates nothing
|
||||
# is a warning (participation that replicates nothing); a @Sync ptr field is a
|
||||
# hard error (footgun 3 — networked fields must be POD scalars).
|
||||
fn net_check() -> void {
|
||||
function net_check() -> void {
|
||||
var i = 0
|
||||
while i < len(prog) {
|
||||
if prog[i].kind == N_ARCH {
|
||||
|
|
@ -110,7 +110,7 @@ fn net_check() -> void {
|
|||
# ---- N2: per-model serializer / applier --------------------------------------
|
||||
# serialize_<M>(e, buf) -> bytes written. Copies each replicated field, tightly
|
||||
# packed in member-then-field order, so apply reads the identical layout.
|
||||
fn emit_net_serialize(m: Node) -> void {
|
||||
function emit_net_serialize(m: Node) -> void {
|
||||
ll_t = 0
|
||||
let me = itoa(MAX_ENT)
|
||||
emit("define i32 @L_serialize_"); emit(m.s); emit("(i32 %e, ptr %buf) {\nentry:\n")
|
||||
|
|
@ -143,7 +143,7 @@ fn emit_net_serialize(m: Node) -> void {
|
|||
# apply_<M>(e, buf, len): the inverse — copy each replicated field back from the
|
||||
# buffer into component storage. `len` is accepted for symmetry (the runtime's
|
||||
# framing) but the layout is fixed, so it is not consulted.
|
||||
fn emit_net_apply(m: Node) -> void {
|
||||
function emit_net_apply(m: Node) -> void {
|
||||
ll_t = 0
|
||||
let me = itoa(MAX_ENT)
|
||||
emit("define void @L_apply_"); emit(m.s); emit("(i32 %e, ptr %buf, i32 %len) {\nentry:\n")
|
||||
|
|
@ -177,7 +177,7 @@ fn emit_net_apply(m: Node) -> void {
|
|||
# ludic_serialize(e, buf) -> bytes / ludic_apply(e, buf, len) / ludic_sync_size(e)
|
||||
# route on the entity's model kind to the per-model function above, so a
|
||||
# replication runtime replicates any entity without knowing its type.
|
||||
fn emit_net_dispatch() -> void {
|
||||
function emit_net_dispatch() -> void {
|
||||
let me = itoa(MAX_ENT)
|
||||
|
||||
emit("define i32 @ludic_serialize(i32 %e, ptr %buf) {\nentry:\n")
|
||||
|
|
@ -236,7 +236,7 @@ fn emit_net_dispatch() -> void {
|
|||
# @L_owner: one i32 owner id per entity, -1 = unowned. Only emitted when a model
|
||||
# is @Owned, and L_reset clears it to -1 on alloc/free (see emit_ecs). owner()/
|
||||
# set_owner()/is_owner() read and write it; the authority assigns.
|
||||
fn emit_net_owner() -> void {
|
||||
function emit_net_owner() -> void {
|
||||
let me = itoa(MAX_ENT)
|
||||
emit("define i32 @L_owner(i32 %e) {\nentry:\n")
|
||||
emit(" %p = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_owner_arr, i32 0, i32 %e\n %v = load i32, ptr %p\n ret i32 %v\n}\n\n")
|
||||
|
|
@ -256,7 +256,7 @@ fn emit_net_owner() -> void {
|
|||
# with NO foreign host at all (the Ludic-native default). Datagram-preserving:
|
||||
# one message per poll, matching how replication/RPC frame. Emitted only when a
|
||||
# program actually calls net_send/net_poll without an extern override.
|
||||
fn emit_loopback() -> void {
|
||||
function emit_loopback() -> void {
|
||||
emith("@L_netq = internal global [64 x [2048 x i8]] zeroinitializer\n")
|
||||
emith("@L_netlen = internal global [64 x i32] zeroinitializer\n")
|
||||
emith("@L_nethead = internal global i32 0\n")
|
||||
|
|
@ -294,24 +294,24 @@ fn emit_loopback() -> void {
|
|||
# re-emits each into the ordinary @ev_<E> dispatch on the far side. Reuses the
|
||||
# EV0 payload (already flat) and the transport seam — no new concept.
|
||||
|
||||
fn net_has_remote() -> bool {
|
||||
function net_has_remote() -> bool {
|
||||
var i = 0
|
||||
while i < len(g_events) { if (g_events[i].ty != null) { return true }; i = i + 1 }
|
||||
return false
|
||||
}
|
||||
# stable wire id for an event = its index in g_events (same program both peers)
|
||||
fn net_event_id(name: ptr) -> int {
|
||||
function net_event_id(name: ptr) -> int {
|
||||
var i = 0
|
||||
while i < len(g_events) { if (g_events[i].s == name) { return i }; i = i + 1 }
|
||||
return 0 - 1
|
||||
}
|
||||
# the transport symbols: an `extern fn` override, else the built-in loopback.
|
||||
fn net_send_sym() -> ptr { let x = find_extern("net_send"); if (x != null) { return x.a.s }; return "L_net_send" }
|
||||
fn net_poll_sym() -> ptr { let x = find_extern("net_poll"); if (x != null) { return x.a.s }; return "L_net_poll" }
|
||||
function net_send_sym() -> ptr { let x = find_extern("net_send"); if (x != null) { return x.a.s }; return "L_net_send" }
|
||||
function net_poll_sym() -> ptr { let x = find_extern("net_poll"); if (x != null) { return x.a.s }; return "L_net_poll" }
|
||||
|
||||
# net_pump(): poll every pending frame and re-emit it locally. The receive path
|
||||
# of a remote event — the runtime/game calls this each tick.
|
||||
fn emit_net_pump() -> void {
|
||||
function emit_net_pump() -> void {
|
||||
emith("@L_recvbuf = internal global [2048 x i8] zeroinitializer\n")
|
||||
if (find_extern("net_poll") == null) { g_uses_loopback = true }
|
||||
let psym = net_poll_sym()
|
||||
|
|
@ -352,7 +352,7 @@ fn emit_net_pump() -> void {
|
|||
}
|
||||
|
||||
# ---- driver ------------------------------------------------------------------
|
||||
fn emit_net() -> void {
|
||||
function emit_net() -> void {
|
||||
if net_has_sync() {
|
||||
net_check()
|
||||
var i = 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue