Commit graph

9 commits

Author SHA1 Message Date
121053e179 feat(stdlib): 2D Vector type + Vector.* namespace (issue #25)
Some checks failed
docs / build-and-deploy (push) Has been cancelled
Implement the Vec.* half of #25 under the proper (de-abbreviated) name
Vector, unblocking it with a self-contained value type instead of waiting
on the full #1 type system.

A Vector is two Q16.16 fixed components (x, y) packed into one i64 — a true
by-value type that lives in a register and never allocates (reuses the new
`long`/i64 support; llty maps `Vector` to i64). Fifteen operations, all
deterministic fixed-point reusing fx_mul/fx_div/fx_lerp and the @fn_fx_*
prelude: make/zero/x/y, add/sub/scale/dot, length/distance/normalize/lerp,
rotate/angle/from_angle.

New selfhost/emit_vector.ludic (wired into emit_ns_call + the frag list),
the `Vector` primitive type in llty and the grammars/LSP/JetBrains tokens,
docs (type-vector + 15 Vector.* pages + section), and a registered test.
Reseeded; C-free fixpoint holds; all suites green (45/25/29); site + check.py OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 02:09:38 +03:00
2e0047514b refactor(lang): rename builtins flr->floor and fx->fixed
De-abbreviate the two bare fixed-point conversion builtins:
  flr(f) -> int     ->  floor(f) -> int    (fixed -> int, flooring)
  fx(i)  -> fixed   ->  fixed(i) -> fixed  (int -> fixed; mirrors how the
                                            stringify builtin is `string`)

Updates the compiler dispatch, all call sites, the grammars/LSP/JetBrains
tokens, and the docs (fn-flr -> fn-floor, fn-fx -> fn-fixed). Reseeded;
C-free fixpoint holds; all suites green (45/24/29); site + check.py OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 02:01:56 +03:00
effb3f637f refactor(lang): rename the ptr/ptrs types to pointer/pointers
Expand the abbreviated pointer types to full words on the language surface:
  ptr   ->  pointer     (a raw address / FFI handle)
  ptrs  ->  pointers    (a buffer of pointers)

The Ludic type name is distinct from LLVM's own `ptr` spelling: llty() maps
`pointer`/`pointers` to LLVM `ptr`, and the emitted IR keeps `ptr`, so only
the Ludic-level surface changes. Rewrites type annotations across all
sources, the 8 hardcoded pointer type-tags, the `pointers`-buffer indexing
in emit_addr, the grammars/LSP/JetBrains tokens, and the docs
(type-ptr -> type-pointer, type-ptrs -> type-pointers). int/bool keep their
conventional short spelling (like Math).

Reseeded; C-free fixpoint holds; all suites green (45/24/29); site + check.py OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 01:58:54 +03:00
b7745a4600 refactor(lang): rename the str type (and stringify builtin) to string
Expand the abbreviated string type and its conversion builtin to the full
word everywhere:
  str            ->  string        (the immutable-string type)
  str(x) -> str  ->  string(x) -> string   (the stringify builtin;
                                            what `{…}` interpolation calls)

Types are recognized by identifier, and llty maps both spellings to LLVM
`ptr`, so this is an atomic source rewrite: type annotations, the Ludic
type tags, the builtin name/dispatch, and the interpolation desugar, plus
the grammars, LSP, docs (type-str -> type-string, fn-str -> fn-string), and
inventory. int/bool stay (universally accepted, like Math).

Reseeded; C-free fixpoint holds; all suites green (45/24/29); site + check.py OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 01:51:11 +03:00
4c48077d68 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>
2026-08-30 01:43:22 +03:00
2f19c8d8e2 refactor(stdlib): de-abbreviate namespaces (Mem/Sys/Net/Collide)
Expand the abbreviated public namespaces to full words, part of the
language-wide de-abbreviation pass:
  Mem -> Memory, Sys -> System, Net -> Network, Collide -> Collision

Math stays (universally accepted, like int/bool). Renames the dispatch
strings, LSP signatures, docs (dirs, files, frontmatter), and the
inventory manifest; behavior is byte-identical (the bare rt_ targets are
unchanged). Reseeded; C-free bootstrap fixpoint holds; all suites green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 01:30:47 +03:00
2002e977d9 feat(lang,stdlib): 64-bit long type + 64-bit Hash variants (issue #17)
Some checks are pending
docs / build-and-deploy (push) Waiting to run
Add `long`, a 64-bit signed integer primitive (i64), threaded through
codegen: llty; int<->long coercion (coerce_code/to_long) at let/assign/
return/call-args; i64 arithmetic + comparison promotion in emit_bin;
unary negate/~; print via %lld and str()/interpolation via @fn_long_str.
Editor vocabulary (syntax header, TextMate grammar, formatter, LSP)
synced; check-vocabulary green. Numeric literals stay i32 — build large
values by widening (documented on the type page).

Complete the Hash.* namespace (issue #17) with both 32- and 64-bit
algorithms: Hash.of/fnv1a/crc32/mix/combine (32-bit) and
Hash.of64/fnv1a_64/mix64 (64-bit, returning long). Deterministic and
C-free; CRC-32 (poly 0xEDB88320) and FNV vectors verified against
reference implementations.

Tests: selfhost/tests/{hash,long}.ludic. Docs: docs/language/hash/*,
type-long.md. Seed reseeded; C-free bootstrap fixpoint holds; 23
selfhost + 45 regression + 29 tooling checks green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 01:01:06 +03:00
a38195128f feat(stdlib): namespaced standard library (issue #2)
Implement the bulk of the namespaced-stdlib proposal (workshopsoft/ludic#2):
156 namespace methods across Math, Text, List, Ease, Collide, World, Net,
Sys, Save, Mem, extended Screen, Color functions, extended Random, and Time.
All deterministic fixed-point; self-hosting (C-free bootstrap fixpoint holds).

Compiler (selfhost/):
- Math.*: sqrt/sin/cos/tan/atan2/asin/acos (fixed-point runtime prelude —
  bit-by-bit isqrt, 256-entry interpolated sine table, Ross atan2), plus
  hypot/dist/dist2/deg_to_rad/rad_to_deg/posmod/wrap/ping_pong/snapped/
  move_toward/smoothstep/lerp/remap/sign/floor/ceil/round.
- Text.* (complete): upper/lower/trim/repeat/pad, split/join/replace,
  and the libc-backed queries.
- List.* (complete): insert/remove_at/remove/sort plus the earlier ops.
- Ease.* (in/out/in_out/back/bounce) and Collide.* (rects/point_rect/
  circles/rect_circle).
- Phase 3: World/Net/Sys/Save namespaced over the bare builtins (byte-
  identical IR) and Mem.* (bytes/words/copy/fill/peek/poke).
- Screen.* extended (line/circle/fill_circle/triangle/fill_triangle via new
  runtime primitives; sprite/sprite_scaled aliases), Color.* functions,
  Random.* (value/int/sign), Time.* (frame/delta/elapsed/now — new
  game-loop frame counter).
- Fix a lexer bug: fixed-point literals with >4 fractional digits overflowed.

Docs & tooling:
- 129 new per-symbol doc pages; gen.py made data-driven (namespaces
  discovered from the docs, no hardcoded list); new check-impl.py enforces
  that every implemented namespace method / keyword / type / phase has a
  doc page, wired into `x test-tools`. Document the previously-undocumented
  keywords (break/continue/where/entry/new/public + and/or/not tokens).
- LSP: namespaced signature help (ns_method_sig) covering every namespace.

Tests: 12 new self-host/regression tests + a golden render for the drawing
primitives. All suites green (selfhost 21, regression 45, tools 29).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 00:26:19 +03:00
bca8f126fc Networking N2–N6, and a fully C-free toolchain
Implement the rest of NETWORKING-DESIGN.md (N2–N6) and eliminate every
`.c` file from the repo. clang remains only the LLVM-IR assembler; no C
is compiled anywhere.

Networking (selfhost/emit_net.ludic + parser/emit changes):
- N2 @Sync: per-model serialize/apply + by-kind dispatchers; POD-scalar
  compile error and empty-participation warning; selective replication.
- N3 @Owned: @L_owner array + owner/set_owner/is_owner; owners snapshot.
- N4 @ToServer/@ToClients remote events: framed net_send + net_pump re-emit.
- N5 @Server/@Predicted role guards + drivable sim (tick_fixed/tick_render,
  entry-owns-the-loop).
- Built-in loopback transport so multiplayer runs with zero foreign code;
  extern fn net_send/net_poll still overrides it for a real socket.
- N6 blessed runtime (examples/net_rt.ludic) + end-to-end demo (net_demo).
- Fix: llty("entity") is now i32 (entities are i32 handles), so let e = self().

C elimination:
- Networking + foreign-mod-ABI tests rewritten as self-contained pure-Ludic
  programs (examples/net_*, world_*, mod_events, scoped); tests/ removed.
- Reflection ABI exposed to Ludic as world_* builtins (Ludic-to-Ludic modding).
- Formatter rewritten C→Ludic: tools/ludic-tools/fmt.ludic.
- Language server rewritten C→Ludic: tools/ludic-tools/lsp.ludic (lexer, index
  parser, cross-file workspace resolver, JSON, all LSP handlers).
- Obsolete migrate_*.c codemods deleted; ludic_syntax.h kept as vocabulary data.

Suites: ./test.sh 44/44, ./tools/test-tools.sh 28/28 (LSP 42/42), fixpoint holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-29 15:08:23 +03:00