diff --git a/CLAUDE.md b/CLAUDE.md index 13ea6bd..a926c91 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # Agent Blackops — Lumbda repo -This repo is operated by **agent blackops** — ml agent for fox/timehexon on the unsandbox/unturf/permacomputer platform. **Lumbda** is the language (home: lumbda.com); the repo directory and binaries still use the historical name `uncommonlisp` until the filesystem rename ships in a later phase. +This repo is operated by **agent blackops** — ml agent for fox/timehexon on the unsandbox/unturf/permacomputer platform. **Lumbda** is the language (home: lumbda.com); the repo directory and binaries still use the historical name `lumbda` until the filesystem rename ships in a later phase. ## Identity @@ -39,7 +39,7 @@ Then ask fox what the mission is. | Impl | Path | Build | Test | REPL | |------|------|-------|------|------| -| Python | `uncommonlisp.py` | — | `make test` | `make repl` | +| Python | `lumbda.py` | — | `make test` | `make repl` | | C | `c/` | `make c-build` | `make c-test` | `make c-repl` | | Assembly | `asm/` | `make asm-build` | `make asm-test` | `make asm-repl` | | All | — | — | `make test-all` | — | @@ -75,22 +75,22 @@ crash is not just "my problem" — it takes their state down too. The rules below are belt, suspenders, AND a parachute so that even if two safeguards fail, the kernel itself backstops. -**MANDATORY pattern — every asm/uncommonlisp test in a shell block:** +**MANDATORY pattern — every asm/lumbda test in a shell block:** ```bash set -e # (1) fail-fast ulimit -v 524288 # (2) KERNEL CAP: 512 MB virt # process gets SIGKILL at cap, no matter what -trap 'pkill -9 -u "$USER" -f "examples/http-server|asm/uncommonlisp" 2>/dev/null || true' \ +trap 'pkill -9 -u "$USER" -f "examples/http-server|asm/lumbda" 2>/dev/null || true' \ EXIT INT TERM # (3) cleanup always fires -timeout 30 asm/uncommonlisp < server.lsp & # (4) wall-clock ceiling +timeout 30 asm/lumbda < server.lsp & # (4) wall-clock ceiling SPID=$! # ... do the work (curl requests, measurements, etc.) ... kill -9 $SPID 2>/dev/null; wait $SPID 2>/dev/null # (5) explicit cleanup # (6) VERIFY the block is clean before moving on -pgrep -u "$USER" -f 'asm/uncommonlisp|examples/http-server' \ +pgrep -u "$USER" -f 'asm/lumbda|examples/http-server' \ && { echo "STRAGGLER"; exit 1; } || true ``` @@ -108,12 +108,12 @@ Additional rules: in `examples/http-server.lsp`). Never raise for long-running tests. - Use `pkill -u "$USER" -f ` not `pkill` alone — others may have their own processes on this machine. -- Prefer FOREGROUND runs when possible: `timeout 10 asm/uncommonlisp +- Prefer FOREGROUND runs when possible: `timeout 10 asm/lumbda < test.lsp` with the `.lsp` exiting on its own beats backgrounding. - C has Boehm GC via `GC_MALLOC`. Python has Python's GC. Asm has neither. Risk scales with how long the asm process lives. - If `ulimit` is unavailable (some container setups), use - `systemd-run --user --scope -p MemoryMax=512M -- asm/uncommonlisp ...` + `systemd-run --user --scope -p MemoryMax=512M -- asm/lumbda ...` as the equivalent cgroup-based cap. ## MOAD Scanner @@ -122,10 +122,10 @@ Additional rules: ```bash cd ~/git/unmoadner && make all -./unmoad ~/git/uncommonlisp/ # scan entire repo -./unmoad ~/git/uncommonlisp/asm/ # scan assembly only -./unmoad ~/git/uncommonlisp/c/ # scan C only -./unmoad ~/git/uncommonlisp/*.py # scan Python only +./unmoad ~/git/lumbda/ # scan entire repo +./unmoad ~/git/lumbda/asm/ # scan assembly only +./unmoad ~/git/lumbda/c/ # scan C only +./unmoad ~/git/lumbda/*.py # scan Python only ``` **MANDATORY before committing new code:** run `unmoad` on changed files. diff --git a/Makefile b/Makefile index d48ed2a..306235f 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ # ═══════════════════════════════════════════════════════════════════ -# uncommonlisp — Python + C + Assembly implementations +# lumbda — Python + C + Assembly implementations # ═══════════════════════════════════════════════════════════════════ # # Implementations: -# Python uncommonlisp.py bytecode VM, full continuations, portal -# C c/uncommonlisp tree-walker + bytecode VM + x86_64 JIT -# Assembly asm/uncommonlisp pure x86_64, no libc, 13KB binary +# Python lumbda.py bytecode VM, full continuations, portal +# C c/lumbda tree-walker + bytecode VM + x86_64 JIT +# Assembly asm/lumbda pure x86_64, no libc, 13KB binary # # Test suites: # make test Python unit/integration (571 tests) @@ -50,10 +50,10 @@ bench-verbose: python3 bench.py -v repl: - python3 uncommonlisp.py + python3 lumbda.py lint: - python3 -m py_compile uncommonlisp.py + python3 -m py_compile lumbda.py python3 -m py_compile tests.py python3 -m py_compile bench.py @@ -65,13 +65,13 @@ c-build: c-test: c-build $(MAKE) -C c test @echo "── C functional tests (shared .lsp suite) ──" - ./c/uncommonlisp tests/functional.lsp + ./c/lumbda tests/functional.lsp c-bench: c-build $(MAKE) -C c bench c-repl: c-build - ./c/uncommonlisp + ./c/lumbda c-clean: $(MAKE) -C c clean @@ -85,7 +85,7 @@ asm-test: asm-build $(MAKE) -C asm test asm-repl: asm-build - ./asm/uncommonlisp + ./asm/lumbda asm-clean: $(MAKE) -C asm clean @@ -95,9 +95,9 @@ asm-clean: functional-test: c-build @echo "═══ Shared functional tests (114 tests) ═══" @echo "── Python ──" - @python3 uncommonlisp.py --fast tests/functional.lsp | tail -3 + @python3 lumbda.py --fast tests/functional.lsp | tail -3 @echo "── C ──" - @./c/uncommonlisp tests/functional.lsp | tail -3 + @./c/lumbda tests/functional.lsp | tail -3 test-all: test c-test asm-test functional-test @echo "════════════════════════════════════════════════════" @@ -147,16 +147,16 @@ bench-all: bench c-bench bench-3way bench-portal bench-portal-cross bench-web be examples: c-build @echo "═══ fibonacci.lsp ═══" - @echo "--- Python ---" && python3 uncommonlisp.py --fast examples/fibonacci.lsp - @echo "--- C ---" && ./c/uncommonlisp examples/fibonacci.lsp + @echo "--- Python ---" && python3 lumbda.py --fast examples/fibonacci.lsp + @echo "--- C ---" && ./c/lumbda examples/fibonacci.lsp @echo @echo "═══ mergesort.lsp ═══" - @echo "--- Python ---" && python3 uncommonlisp.py --fast examples/mergesort.lsp - @echo "--- C ---" && ./c/uncommonlisp examples/mergesort.lsp + @echo "--- Python ---" && python3 lumbda.py --fast examples/mergesort.lsp + @echo "--- C ---" && ./c/lumbda examples/mergesort.lsp @echo @echo "═══ objects.lsp ═══" - @echo "--- Python ---" && python3 uncommonlisp.py examples/objects.lsp - @echo "--- C ---" && ./c/uncommonlisp examples/objects.lsp + @echo "--- Python ---" && python3 lumbda.py examples/objects.lsp + @echo "--- C ---" && ./c/lumbda examples/objects.lsp # ─── Friction benchmark ────────────────────────────────────────── @@ -176,8 +176,8 @@ docs/%.png: docs/%.dot # ─── Whitepaper ─────────────────────────────────────────────────── VENV := whitepaper/.venv -RST := whitepaper/uncommonlisp-whitepaper.rst -PDF := whitepaper/uncommonlisp-whitepaper.pdf +RST := whitepaper/lumbda-whitepaper.rst +PDF := whitepaper/lumbda-whitepaper.pdf STYLE := whitepaper/whitepaper.style $(VENV)/bin/rst2pdf: @@ -191,9 +191,9 @@ $(PDF): $(RST) $(STYLE) $(VENV)/bin/rst2pdf cd whitepaper && ../$( " +prompt_str: .ascii "lumbda> " .equ prompt_len, . - prompt_str newline_ch: .byte 10 @@ -351,7 +351,7 @@ s_hashset: .ascii "#" err_ht_miss: .ascii "Error: hash-table-ref: missing key\n" .equ err_ht_miss_len, . - err_ht_miss -portal_magic: .ascii "ULPORTAL" +portal_magic: .ascii "LUMBDAB1" .equ PORTAL_MAGIC_LEN, 8 .equ PORTAL_HDR_SIZE, 48 # magic(8) + heap_size(8) + heap_base(8) + r14(8) + r15(8) + reserved(8) diff --git a/asm/test.sh b/asm/test.sh index 9b5d9f1..73c55f4 100644 --- a/asm/test.sh +++ b/asm/test.sh @@ -10,7 +10,7 @@ cd "$(dirname "$0")" PASS=0 FAIL=0 -UL="${UNCOMMONLISP_BIN:-./uncommonlisp}" +UL="${LUMBDA_BIN:-./lumbda}" check() { local name="$1" input="$2" expected="$3" @@ -28,7 +28,7 @@ check() { } echo "═══════════════════════════════════════════════════════" -echo "asm/uncommonlisp test suite" +echo "asm/lumbda test suite" echo "═══════════════════════════════════════════════════════" # ─── UNIT TESTS: individual primitives ──────────────────── @@ -205,7 +205,7 @@ EOF check "load-proc" "(load \"$LOAD_TMP/b.lsp\") (square 9)" "81" echo "[unit] load — missing file returns #f" -check "load-missing" "(load \"/tmp/__nope_uncommonlisp_$$\")" "#f" +check "load-missing" "(load \"/tmp/__nope_lumbda_$$\")" "#f" echo "[unit] load — empty file is void" : > "$LOAD_TMP/empty.lsp" diff --git a/asm/uncommonlisp b/asm/uncommonlisp deleted file mode 100755 index 7bb9a80..0000000 Binary files a/asm/uncommonlisp and /dev/null differ diff --git a/asm/uncommonlisp-gc b/asm/uncommonlisp-gc deleted file mode 100755 index 5e1689a..0000000 Binary files a/asm/uncommonlisp-gc and /dev/null differ diff --git a/asm/uncommonlisp.o b/asm/uncommonlisp.o deleted file mode 100644 index 4390479..0000000 Binary files a/asm/uncommonlisp.o and /dev/null differ diff --git a/bench.py b/bench.py index ca700eb..33b3ddd 100644 --- a/bench.py +++ b/bench.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 """ -bench.py — benchmarks for uncommonlisp. +bench.py — benchmarks for lumbda. Compares interpreter time against equivalent CPython. Usage: python3 bench.py [-v] """ import sys, time, math sys.setrecursionlimit(10000) -from uncommonlisp import make_global_env, read_all, leval, PRELUDE, show, bc_compile_proc, Proc +from lumbda import make_global_env, read_all, leval, PRELUDE, show, bc_compile_proc, Proc VERBOSE = '-v' in sys.argv @@ -56,7 +56,7 @@ def bench(name, lisp_src, python_fn, iters=3): return lisp_best, py_best -print('uncommonlisp benchmarks') +print('lumbda benchmarks') print('=' * 75) # ── 1. Fibonacci (iterative, named let) ────────────────────────────────────── @@ -388,7 +388,7 @@ print() print('AUTO-COMPILE mode (auto-compile! #t)') print('=' * 75) -from uncommonlisp import _auto_compile +from lumbda import _auto_compile def bench_auto(name, lisp_src, python_fn, iters=3): """Time auto-compiled lisp vs python. Defines + runs in one pass.""" diff --git a/c/.gitignore b/c/.gitignore index 519e1fc..77c71aa 100644 --- a/c/.gitignore +++ b/c/.gitignore @@ -1,5 +1,5 @@ *.o -uncommonlisp +lumbda test_runner test_runner_dbg bench_runner diff --git a/c/Makefile b/c/Makefile index 6e26a65..751dd40 100644 --- a/c/Makefile +++ b/c/Makefile @@ -1,4 +1,4 @@ -# Makefile for uncommonlisp C interpreter +# Makefile for lumbda C interpreter # Targets: all, test, bench, clean CC = gcc @@ -15,9 +15,9 @@ OBJS = $(SRCS:.c=.o) .PHONY: all clean test bench -all: uncommonlisp +all: lumbda -uncommonlisp: main.o $(OBJS) +lumbda: main.o $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) test: test_runner @@ -26,14 +26,14 @@ test: test_runner test_runner: test.c $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -bench: bench_runner uncommonlisp +bench: bench_runner lumbda ulimit -s 65536 && ./bench_runner bench_runner: bench.c $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -%.o: %.c uncommonlisp.h +%.o: %.c lumbda.h $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o uncommonlisp test_runner bench_runner + rm -f *.o lumbda test_runner bench_runner diff --git a/c/TODO-named-let-bytecode.md b/c/TODO-named-let-bytecode.md index 5ee5f70..e8c8ad2 100644 --- a/c/TODO-named-let-bytecode.md +++ b/c/TODO-named-let-bytecode.md @@ -13,8 +13,8 @@ Expected output: `4` -Actual with `c/uncommonlisp --fast`: hangs or segfaults. -Tree-walker (`c/uncommonlisp` default) works correctly. +Actual with `c/lumbda --fast`: hangs or segfaults. +Tree-walker (`c/lumbda` default) works correctly. Python `--fast` and asm tree-walker both work correctly. ## What's special diff --git a/c/bench.c b/c/bench.c index f409d3d..7f1e36b 100644 --- a/c/bench.c +++ b/c/bench.c @@ -1,7 +1,7 @@ /* * bench.c — Benchmarks: interpreted vs compiled vs JIT */ -#include "uncommonlisp.h" +#include "lumbda.h" #include "jit.h" static double bench_time(void) { @@ -184,7 +184,7 @@ int main(void) { return 1; } - printf("uncommonlisp C benchmarks — interpreted vs compiled vs JIT\n"); + printf("lumbda C benchmarks — interpreted vs compiled vs JIT\n"); printf("═════════════════════════════════════════════════════════════════\n"); const char *modes[] = { "interp", "compiled", "jit", NULL }; diff --git a/c/builtins.c b/c/builtins.c index a330b88..16b64a6 100644 --- a/c/builtins.c +++ b/c/builtins.c @@ -1,7 +1,7 @@ /* * builtins.c — All built-in functions for the Scheme interpreter */ -#include "uncommonlisp.h" +#include "lumbda.h" /* ═══════════════════════════════════════════════════════════════════════════ * Helper macros @@ -1926,7 +1926,7 @@ Env *make_global_env(void) { env_define(g, intern("else"), VAL_TRUE); env_define(g, intern("..."), intern("...")); env_define(g, intern("*version*"), make_string_from_cstr("1.0.0")); - env_define(g, intern("*name*"), make_string_from_cstr("uncommonlisp")); + env_define(g, intern("*name*"), make_string_from_cstr("lumbda")); /* Portal builtins */ register_portal_builtins(g); diff --git a/c/eval.c b/c/eval.c index 57dd3ad..f26c333 100644 --- a/c/eval.c +++ b/c/eval.c @@ -3,7 +3,7 @@ * * Port of the Python leval() function with full special form support. */ -#include "uncommonlisp.h" +#include "lumbda.h" #include "jit.h" /* ═══════════════════════════════════════════════════════════════════════════ diff --git a/c/jit.c b/c/jit.c index 5423b7b..1525127 100644 --- a/c/jit.c +++ b/c/jit.c @@ -1,5 +1,5 @@ /* - * jit.c — x86_64 native code JIT compiler for uncommonlisp + * jit.c — x86_64 native code JIT compiler for lumbda * * Emits real machine code bytes into mmap'd executable memory. * Handles: integer arithmetic (+, -, *), comparisons (=, <, >, <=, >=), @@ -9,7 +9,7 @@ * * Code outlasts authors. */ -#include "uncommonlisp.h" +#include "lumbda.h" #include "jit.h" #include diff --git a/c/jit.h b/c/jit.h index f464162..ef0cc17 100644 --- a/c/jit.h +++ b/c/jit.h @@ -1,5 +1,5 @@ /* - * jit.h — x86_64 JIT compiler for uncommonlisp + * jit.h — x86_64 JIT compiler for lumbda * * Compiles Scheme procedures to native machine code. * Uses mmap(PROT_READ|PROT_WRITE|PROT_EXEC) for executable memory. @@ -9,7 +9,7 @@ #ifndef JIT_H #define JIT_H -#include "uncommonlisp.h" +#include "lumbda.h" /* A JIT-compiled function takes NaN-boxed Value args and returns a Value. * System V AMD64 ABI: args in rdi, rsi, rdx, rcx, r8, r9 */ diff --git a/c/uncommonlisp.h b/c/lumbda.h similarity index 99% rename from c/uncommonlisp.h rename to c/lumbda.h index fb432e1..0533ac5 100644 --- a/c/uncommonlisp.h +++ b/c/lumbda.h @@ -1,11 +1,11 @@ /* - * uncommonlisp.h — A Scheme interpreter in C (NaN-boxed values, Boehm-style GC) + * lumbda.h — A Scheme interpreter in C (NaN-boxed values, Boehm-style GC) * - * Complete port of uncommonlisp.py. + * Complete port of lumbda.py. * Part of the permacomputer platform — code outlasts authors. */ -#ifndef UNCOMMONLISP_H -#define UNCOMMONLISP_H +#ifndef LUMBDA_H +#define LUMBDA_H #include #include @@ -763,4 +763,4 @@ typedef struct Module { extern Module *g_modules; -#endif /* UNCOMMONLISP_H */ +#endif /* LUMBDA_H */ diff --git a/c/main.c b/c/main.c index 0f71328..45fab55 100644 --- a/c/main.c +++ b/c/main.c @@ -1,7 +1,7 @@ /* * main.c — REPL, script mode, -e mode */ -#include "uncommonlisp.h" +#include "lumbda.h" #include "jit.h" /* ═══════════════════════════════════════════════════════════════════════════ @@ -16,7 +16,7 @@ static char *find_stdlib(const char *argv0) { ssize_t n = readlink("/proc/self/exe", path, sizeof(path) - 1); if (n > 0) { path[n] = '\0'; - /* Go up one directory (from c/uncommonlisp to uncommonlisp/) */ + /* Go up one directory (from c/lumbda to lumbda/) */ char *slash = strrchr(path, '/'); if (slash) { *slash = '\0'; @@ -51,7 +51,7 @@ static char *find_stdlib(const char *argv0) { static void repl(Env *env) { char *version_str = show(env_lookup(env, intern("*version*")), true); - printf("uncommonlisp %s (C) — (exit) to quit, (load \"file.lsp\") to load\n", version_str); + printf("lumbda %s (C) — (exit) to quit, (load \"file.lsp\") to load\n", version_str); ul_free(version_str); char buf[16384]; @@ -161,10 +161,10 @@ int main(int argc, char **argv) { } if (help) { - printf("uncommonlisp — a Scheme interpreter in C\n\n" - "Usage: uncommonlisp [options] [script.lsp] [args...]\n" - " uncommonlisp -e '(+ 1 2)'\n" - " uncommonlisp (interactive REPL)\n\n" + printf("lumbda — a Scheme interpreter in C\n\n" + "Usage: lumbda [options] [script.lsp] [args...]\n" + " lumbda -e '(+ 1 2)'\n" + " lumbda (interactive REPL)\n\n" "Options:\n" " -e EXPR evaluate expression and print result\n" " -f, --fast auto-compile all defines (bytecode VM;\n" @@ -178,7 +178,7 @@ int main(int argc, char **argv) { } if (version) { - printf("uncommonlisp 1.0.0 (C)\n"); + printf("lumbda 1.0.0 (C)\n"); return 0; } diff --git a/c/portal.c b/c/portal.c index 2b3d7da..092ceda 100644 --- a/c/portal.c +++ b/c/portal.c @@ -4,7 +4,7 @@ * Port of the Python portal_save/portal_resume system. * Serializes environment bindings and full continuations. */ -#include "uncommonlisp.h" +#include "lumbda.h" /* ═══════════════════════════════════════════════════════════════════════════ * Portal checkpoint — thread-local signal for mid-execution save @@ -188,7 +188,7 @@ void portal_save(Env *env, const char *path, FullCont *continuation) { return; } - fputs("{\"format\":\"uncommonlisp-portal-v1\",\n", fp); + fputs("{\"format\":\"lumbda-portal-v1\",\n", fp); /* Environment bindings (user-defined only from global) */ fputs("\"env\":", fp); @@ -620,7 +620,7 @@ bool portal_resume(const char *path, Env *base_env, Env **out_env, FullCont **ou /* Check format */ const char *fmt = json_str(json_obj_get(root, "format")); - if (!fmt || strcmp(fmt, "uncommonlisp-portal-v1") != 0) { + if (!fmt || strcmp(fmt, "lumbda-portal-v1") != 0) { json_free(root); return false; } diff --git a/c/printer.c b/c/printer.c index 9149200..b5a004c 100644 --- a/c/printer.c +++ b/c/printer.c @@ -1,7 +1,7 @@ /* * printer.c — show/display/write for Scheme values */ -#include "uncommonlisp.h" +#include "lumbda.h" /* Dynamic string builder */ typedef struct { diff --git a/c/reader.c b/c/reader.c index 4bf74eb..045f863 100644 --- a/c/reader.c +++ b/c/reader.c @@ -1,7 +1,7 @@ /* * reader.c — Tokenizer + parser for Scheme source */ -#include "uncommonlisp.h" +#include "lumbda.h" /* ═══════════════════════════════════════════════════════════════════════════ * Tokenizer diff --git a/c/test.c b/c/test.c index 3be0ddd..9ae28f7 100644 --- a/c/test.c +++ b/c/test.c @@ -1,7 +1,7 @@ /* * test.c — Unit + integration tests for the C Scheme interpreter */ -#include "uncommonlisp.h" +#include "lumbda.h" #include "jit.h" static int tests_run = 0; @@ -876,7 +876,7 @@ TEST(portal_checkpoint_builtin) { int main(void) { init_symbols(); - printf("Running uncommonlisp C tests...\n\n"); + printf("Running lumbda C tests...\n\n"); printf("[types]\n"); run_test_nan_boxing_int(); run_test_nan_boxing_double(); diff --git a/c/types.c b/c/types.c index c24786a..71fab66 100644 --- a/c/types.c +++ b/c/types.c @@ -1,7 +1,7 @@ /* * types.c — Value types, NaN-boxing, symbol interning, Env, Pair, etc. */ -#include "uncommonlisp.h" +#include "lumbda.h" /* ═══════════════════════════════════════════════════════════════════════════ * Error context (thread-local) diff --git a/c/vm.c b/c/vm.c index 9bc5618..0633a31 100644 --- a/c/vm.c +++ b/c/vm.c @@ -1,7 +1,7 @@ /* * vm.c — Bytecode compiler + stack-based VM */ -#include "uncommonlisp.h" +#include "lumbda.h" /* ═══════════════════════════════════════════════════════════════════════════ * CodeObj @@ -625,7 +625,7 @@ void bc_compile(Value expr, CodeObj *code, Env *env, bool tail) { ul_free(call_args); } -/* syntax_transform_value is declared in uncommonlisp.h, implemented in eval.c */ +/* syntax_transform_value is declared in lumbda.h, implemented in eval.c */ /* ═══════════════════════════════════════════════════════════════════════════ * Compile a Proc into a CompiledProc diff --git a/docs/README.md b/docs/README.md index 80e9afa..95cb892 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,10 @@ -# uncommonlisp Architecture Documentation +# lumbda Architecture Documentation > "A diagram is worth 10,000 words." — russell@unturf.com Three implementations of the same Scheme language, sharing the same .lsp test files. -## Python Implementation (uncommonlisp.py) +## Python Implementation (lumbda.py) 3,324 lines. Bytecode compiler + stack VM + full continuations + portal. @@ -118,5 +118,5 @@ make test-all Total: 943 assertions ``` -The language is **R7RS Scheme**. uncommonlisp is the project name — a play on +The language is **R7RS Scheme**. lumbda is the project name — a play on Common Lisp, since this is decidedly uncommon. diff --git a/docs/c-architecture.dot b/docs/c-architecture.dot index 5331408..f3a3a42 100644 --- a/docs/c-architecture.dot +++ b/docs/c-architecture.dot @@ -21,7 +21,7 @@ digraph c_arch { } subgraph cluster_types { - label="Types (types.c, uncommonlisp.h)" + label="Types (types.c, lumbda.h)" style=rounded color="#666666" nanbox [label="NaN-Boxing\n64-bit doubles\ntype tags in NaN payload\nzero-alloc numbers" fillcolor="#e2d5f1"] diff --git a/examples/bench-hashset.lsp b/examples/bench-hashset.lsp index e2e4960..7243a56 100644 --- a/examples/bench-hashset.lsp +++ b/examples/bench-hashset.lsp @@ -3,7 +3,7 @@ ;;; ASM-ONLY: exercises the native hash-set-* primitives introduced ;;; alongside the portable-lib equivalent. C and Python tiers do not ;;; carry hash-set builtins (they have hash-table), so this file is -;;; driven from tests/bench-hashset.sh against asm/uncommonlisp only. +;;; driven from tests/bench-hashset.sh against asm/lumbda only. ;;; ;;; Phases: insert-N, hit-lookup-N, miss-lookup-N. ;;; Output: ms per phase + speedup (portable/native). diff --git a/examples/fibonacci.lsp b/examples/fibonacci.lsp index 142117a..68783e9 100644 --- a/examples/fibonacci.lsp +++ b/examples/fibonacci.lsp @@ -1,5 +1,5 @@ ;;; fibonacci.lsp — iterative and recursive Fibonacci -;;; Run: python3 uncommonlisp.py --fast examples/fibonacci.lsp +;;; Run: python3 lumbda.py --fast examples/fibonacci.lsp (define (fib-iter n) (let loop ((a 0) (b 1) (i 0)) diff --git a/examples/generator.lsp b/examples/generator.lsp index 72adb09..d95fb9b 100644 --- a/examples/generator.lsp +++ b/examples/generator.lsp @@ -1,5 +1,5 @@ ;;; generator.lsp — coroutine-style generators using full continuations -;;; Run: python3 uncommonlisp.py --fast examples/generator.lsp +;;; Run: python3 lumbda.py --fast examples/generator.lsp (define (make-generator thunk) (let ((k #f) (done #f)) diff --git a/examples/http-client-bench.lsp b/examples/http-client-bench.lsp index 482d96a..d897d8e 100644 --- a/examples/http-client-bench.lsp +++ b/examples/http-client-bench.lsp @@ -10,9 +10,9 @@ ;;; server throughput shows up. ;;; ;;; Usage: -;;; python3 uncommonlisp.py --fast examples/http-client-bench.lsp -;;; ./c/uncommonlisp examples/http-client-bench.lsp -;;; ./asm/uncommonlisp < examples/http-client-bench.lsp +;;; python3 lumbda.py --fast examples/http-client-bench.lsp +;;; ./c/lumbda examples/http-client-bench.lsp +;;; ./asm/lumbda < examples/http-client-bench.lsp ;;; ;;; Override N or PORT by pre-setting *n-requests* / *port* before load. diff --git a/examples/http-server-noarena.lsp b/examples/http-server-noarena.lsp index edaa8cc..69d1c27 100644 --- a/examples/http-server-noarena.lsp +++ b/examples/http-server-noarena.lsp @@ -56,7 +56,7 @@ (cond ((string=? path "/") (http-response "200 OK" "text/html" - "uncommonlisp

feedback is all you need

")) + "lumbda

feedback is all you need

")) ((string=? path "/bench") (http-response "200 OK" "text/plain" *bench-body*)) (else diff --git a/examples/http-server.lsp b/examples/http-server.lsp index bda5760..19ff20f 100644 --- a/examples/http-server.lsp +++ b/examples/http-server.lsp @@ -3,9 +3,9 @@ ;;; Runs identically in Python, C, and asm. The only primitives used are ;;; the six socket builtins + display/string-append/substring. ;;; -;;; python3 uncommonlisp.py --fast examples/http-server.lsp -;;; ./c/uncommonlisp examples/http-server.lsp -;;; ./asm/uncommonlisp < examples/http-server.lsp +;;; python3 lumbda.py --fast examples/http-server.lsp +;;; ./c/lumbda examples/http-server.lsp +;;; ./asm/lumbda < examples/http-server.lsp ;;; ;;; Default port 8080. First-line dispatch: GET / → greeting page. ;;; GET /bench → 1 KB body for throughput benchmarks. @@ -76,7 +76,7 @@ (cond ((string=? path "/") (http-response "200 OK" "text/html" - "uncommonlisp

feedback is all you need

portable HTTP in Scheme.

")) + "lumbda

feedback is all you need

portable HTTP in Scheme.

")) ((string=? path "/bench") (http-response "200 OK" "text/plain" *bench-body*)) ((string=? path "/hello") @@ -110,7 +110,7 @@ (server-loop (+ n 1) snap)))) (define (serve) - (display "uncommonlisp http server on :") (display *port*) + (display "lumbda http server on :") (display *port*) (display " (max ") (display *max-requests*) (display " requests)") (newline) (server-loop 0 (heap-snapshot))) diff --git a/examples/mergesort.lsp b/examples/mergesort.lsp index 99672f3..f027eab 100644 --- a/examples/mergesort.lsp +++ b/examples/mergesort.lsp @@ -1,5 +1,5 @@ ;;; mergesort.lsp — functional merge sort -;;; Run: python3 uncommonlisp.py --fast examples/mergesort.lsp +;;; Run: python3 lumbda.py --fast examples/mergesort.lsp (define (merge a b) (cond ((null? a) b) diff --git a/examples/objects.lsp b/examples/objects.lsp index 8ff9409..2f84860 100644 --- a/examples/objects.lsp +++ b/examples/objects.lsp @@ -1,5 +1,5 @@ ;;; objects.lsp — record types, closures as objects, hash tables -;;; Run: python3 uncommonlisp.py examples/objects.lsp +;;; Run: python3 lumbda.py examples/objects.lsp ;; Record types with inheritance (define-record-type @@ -42,7 +42,7 @@ ;; Hash table (define ht (make-hash-table)) -(hash-table-set! ht 'name "uncommonlisp") +(hash-table-set! ht 'name "lumbda") (hash-table-set! ht 'version "1.0.0") (hash-table-set! ht 'features '(bytecode continuations macros)) (display "Name: ") (display (hash-table-ref ht 'name)) (newline) diff --git a/examples/portal-http-client.lsp b/examples/portal-http-client.lsp index 1645636..d210afc 100644 --- a/examples/portal-http-client.lsp +++ b/examples/portal-http-client.lsp @@ -7,9 +7,9 @@ ;;; lines of string-munging plus (read-from-string) + (eval). ;;; ;;; Usage (server must be running first — see portal-http-server.lsp): -;;; python3 uncommonlisp.py --fast examples/portal-http-client.lsp -;;; ./c/uncommonlisp examples/portal-http-client.lsp -;;; ./asm/uncommonlisp < examples/portal-http-client.lsp +;;; python3 lumbda.py --fast examples/portal-http-client.lsp +;;; ./c/lumbda examples/portal-http-client.lsp +;;; ./asm/lumbda < examples/portal-http-client.lsp (define *host* "127.0.0.1") (define *port* 9085) diff --git a/examples/portal-http-server.lsp b/examples/portal-http-server.lsp index 9b8cf7b..a9caa72 100644 --- a/examples/portal-http-server.lsp +++ b/examples/portal-http-server.lsp @@ -10,9 +10,9 @@ ;;; sockets, using the language itself as the wire format. ;;; ;;; Runs byte-identically in Python, C, and asm: -;;; python3 uncommonlisp.py --fast examples/portal-http-server.lsp -;;; ./c/uncommonlisp examples/portal-http-server.lsp -;;; ./asm/uncommonlisp < examples/portal-http-server.lsp +;;; python3 lumbda.py --fast examples/portal-http-server.lsp +;;; ./c/lumbda examples/portal-http-server.lsp +;;; ./asm/lumbda < examples/portal-http-server.lsp ;;; ;;; Default port 9085. @@ -53,7 +53,7 @@ (define (portal-body) ;; Produce the S-expression portal as a single string. (string-append - ";; uncommonlisp portable portal\n" + ";; lumbda portable portal\n" "(define counter " (number->string counter) ")\n" "(define my-int " (number->string my-int) ")\n" "(define my-list '(" (list->string my-list) "))\n" @@ -91,7 +91,7 @@ (http-response "200 OK" "application/scheme" (portal-body))) ((string=? path "/") (http-response "200 OK" "text/html" - "portal-http

uncommonlisp portal-http

GET /portal returns the S-expression portal.

")) + "portal-http

lumbda portal-http

GET /portal returns the S-expression portal.

")) (else (http-response "404 Not Found" "text/plain" (string-append "not found: " path "\n")))))) diff --git a/examples/portal-prime.lsp b/examples/portal-prime.lsp index 1eb3bd8..f2baff3 100644 --- a/examples/portal-prime.lsp +++ b/examples/portal-prime.lsp @@ -1,9 +1,9 @@ ;;; portal-prime.lsp — portal a primality test between machines ;;; -;;; Machine A: python3 uncommonlisp.py --fast examples/portal-prime.lsp +;;; Machine A: python3 lumbda.py --fast examples/portal-prime.lsp ;;; (starts computing, saves checkpoint to prime-state.portal) ;;; -;;; Machine B: python3 uncommonlisp.py --portal-resume prime-state.portal +;;; Machine B: python3 lumbda.py --portal-resume prime-state.portal ;;; (resumes from checkpoint, finishes the computation) (define (prime? n) diff --git a/examples/proof-netspace-client.lsp b/examples/proof-netspace-client.lsp index b3974ad..c02d24d 100644 --- a/examples/proof-netspace-client.lsp +++ b/examples/proof-netspace-client.lsp @@ -13,9 +13,9 @@ ;;; until both hold the union of what either knew. ;;; ;;; Usage (start the server first): -;;; python3 uncommonlisp.py --fast examples/proof-netspace-client.lsp -;;; ./c/uncommonlisp examples/proof-netspace-client.lsp -;;; ./asm/uncommonlisp < examples/proof-netspace-client.lsp +;;; python3 lumbda.py --fast examples/proof-netspace-client.lsp +;;; ./c/lumbda examples/proof-netspace-client.lsp +;;; ./asm/lumbda < examples/proof-netspace-client.lsp (define *host* "127.0.0.1") (define *port* 9086) diff --git a/examples/proof-netspace-server.lsp b/examples/proof-netspace-server.lsp index 9e15ee2..58dca33 100644 --- a/examples/proof-netspace-server.lsp +++ b/examples/proof-netspace-server.lsp @@ -12,9 +12,9 @@ ;;; ;;; Portable across Python, C, and asm. Example: ;;; -;;; python3 uncommonlisp.py --fast examples/proof-netspace-server.lsp -;;; ./c/uncommonlisp --fast examples/proof-netspace-server.lsp -;;; ./asm/uncommonlisp < examples/proof-netspace-server.lsp +;;; python3 lumbda.py --fast examples/proof-netspace-server.lsp +;;; ./c/lumbda --fast examples/proof-netspace-server.lsp +;;; ./asm/lumbda < examples/proof-netspace-server.lsp ;;; ;;; For multi-node demos see proof-netspace-node-{a,b}.lsp. diff --git a/examples/repl-server.lsp b/examples/repl-server.lsp index c32a117..c06181e 100644 --- a/examples/repl-server.lsp +++ b/examples/repl-server.lsp @@ -11,9 +11,9 @@ ;;; because both sides already have a reader and an evaluator. ;;; ;;; Usage: -;;; python3 uncommonlisp.py --fast examples/repl-server.lsp -;;; ./c/uncommonlisp examples/repl-server.lsp -;;; ./asm/uncommonlisp < examples/repl-server.lsp +;;; python3 lumbda.py --fast examples/repl-server.lsp +;;; ./c/lumbda examples/repl-server.lsp +;;; ./asm/lumbda < examples/repl-server.lsp ;;; ;;; Then from a client: ;;; (define x 42) ; server mutates its global env diff --git a/examples/rpc-client.lsp b/examples/rpc-client.lsp index 84f0ef6..22cfa37 100644 --- a/examples/rpc-client.lsp +++ b/examples/rpc-client.lsp @@ -5,9 +5,9 @@ ;;; because they agree on S-expression framing. ;;; ;;; Usage: -;;; python3 uncommonlisp.py --fast examples/rpc-client.lsp -;;; ./c/uncommonlisp examples/rpc-client.lsp -;;; ./asm/uncommonlisp < examples/rpc-client.lsp +;;; python3 lumbda.py --fast examples/rpc-client.lsp +;;; ./c/lumbda examples/rpc-client.lsp +;;; ./asm/lumbda < examples/rpc-client.lsp ;;; ;;; Override *target-port* before loading to hit either rpc-server (9080) ;;; or repl-server (9081). diff --git a/examples/rpc-relay.lsp b/examples/rpc-relay.lsp index d856581..4081512 100644 --- a/examples/rpc-relay.lsp +++ b/examples/rpc-relay.lsp @@ -6,9 +6,9 @@ ;;; asm backend, where the same .lsp runs at every hop and the wire ;;; format (Scheme source) needs no translation. ;;; -;;; python3 uncommonlisp.py --fast examples/rpc-relay.lsp -;;; ./c/uncommonlisp examples/rpc-relay.lsp -;;; ./asm/uncommonlisp < examples/rpc-relay.lsp +;;; python3 lumbda.py --fast examples/rpc-relay.lsp +;;; ./c/lumbda examples/rpc-relay.lsp +;;; ./asm/lumbda < examples/rpc-relay.lsp ;;; ;;; Override *listen-port* / *backend-port* by pre-defining before load ;;; (or edit here for a one-off demo). diff --git a/examples/rpc-server.lsp b/examples/rpc-server.lsp index d015f25..33c1ff4 100644 --- a/examples/rpc-server.lsp +++ b/examples/rpc-server.lsp @@ -5,9 +5,9 @@ ;;; the parser on each side is already the right tool. ;;; ;;; Runs byte-identically in Python, C, and asm: -;;; python3 uncommonlisp.py --fast examples/rpc-server.lsp -;;; ./c/uncommonlisp examples/rpc-server.lsp -;;; ./asm/uncommonlisp < examples/rpc-server.lsp +;;; python3 lumbda.py --fast examples/rpc-server.lsp +;;; ./c/lumbda examples/rpc-server.lsp +;;; ./asm/lumbda < examples/rpc-server.lsp ;;; ;;; Request examples (send as plain text, one per connection): ;;; (ping) -> pong diff --git a/examples/spiral-client.lsp b/examples/spiral-client.lsp index 99e9a10..6ecf38d 100644 --- a/examples/spiral-client.lsp +++ b/examples/spiral-client.lsp @@ -12,7 +12,7 @@ ;;; direction. N nodes in a mesh converge after N-1 spiral passes. ;;; ;;; Usage (start both nodes first): -;;; python3 uncommonlisp.py --fast examples/spiral-client.lsp +;;; python3 lumbda.py --fast examples/spiral-client.lsp (define *host* "127.0.0.1") (define *port-a* 9086) diff --git a/examples/spiral-demo.sh b/examples/spiral-demo.sh index 591ebc3..e7a6980 100755 --- a/examples/spiral-demo.sh +++ b/examples/spiral-demo.sh @@ -19,9 +19,9 @@ trap 'pkill -9 -u "$USER" -f "proof-netspace-node|spiral-client" 2>/dev/null || IMPL="${1:-python}" case "$IMPL" in - python) BIN="python3 uncommonlisp.py --fast" ;; - c) BIN="./c/uncommonlisp --fast" ;; - asm) BIN="asm/uncommonlisp" ;; + python) BIN="python3 lumbda.py --fast" ;; + c) BIN="./c/lumbda --fast" ;; + asm) BIN="asm/lumbda" ;; *) echo "unknown impl: $IMPL (expected python|c|asm)"; exit 1 ;; esac diff --git a/friction.sh b/friction.sh index b4f9f93..773a85b 100644 --- a/friction.sh +++ b/friction.sh @@ -1,5 +1,5 @@ #!/bin/bash -# friction.sh — Head-to-head benchmark: CPython vs uncommonlisp-Python vs uncommonlisp-C +# friction.sh — Head-to-head benchmark: CPython vs lumbda-Python vs lumbda-C # # Usage: bash friction.sh @@ -7,7 +7,7 @@ set -e cd "$(dirname "$0")" echo "═══════════════════════════════════════════════════════════════" -echo "Friction Benchmark: CPython vs uncommonlisp-Python vs uncommonlisp-C" +echo "Friction Benchmark: CPython vs lumbda-Python vs lumbda-C" echo "═══════════════════════════════════════════════════════════════" echo @@ -27,9 +27,9 @@ def fib(n): t=time.perf_counter(); r=fib(35); print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-Python: " +printf " lumbda-Python: " python3 -c " -import time; from uncommonlisp import * +import time; from lumbda import * g=make_global_env(); [leval(e,g) for e in read_all(PRELUDE)] [leval(e,g) for e in read_all('(auto-compile! #t)')] [leval(e,g) for e in read_all('(define (fib n) (let loop ((a 0) (b 1) (i 0)) (if (= i n) a (loop b (+ a b) (+ i 1)))))')] @@ -37,8 +37,8 @@ t=time.perf_counter(); r=[leval(e,g) for e in read_all('(fib 35)')][-1] print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-C: " -/usr/bin/time -f "%e s" ./c/uncommonlisp -e '(define (fib n) (let loop ((a 0) (b 1) (i 0)) (if (= i n) a (loop b (+ a b) (+ i 1))))) (display (fib 35)) (newline)' 2>&1 +printf " lumbda-C: " +/usr/bin/time -f "%e s" ./c/lumbda -e '(define (fib n) (let loop ((a 0) (b 1) (i 0)) (if (= i n) a (loop b (+ a b) (+ i 1))))) (display (fib 35)) (newline)' 2>&1 echo @@ -54,9 +54,9 @@ def fib(n): t=time.perf_counter(); r=fib(20); print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-Python: " +printf " lumbda-Python: " python3 -c " -import time,sys; sys.setrecursionlimit(50000); from uncommonlisp import * +import time,sys; sys.setrecursionlimit(50000); from lumbda import * g=make_global_env(); [leval(e,g) for e in read_all(PRELUDE)] [leval(e,g) for e in read_all('(auto-compile! #t)')] [leval(e,g) for e in read_all('(define (fib n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2)))))')] @@ -64,8 +64,8 @@ t=time.perf_counter(); r=[leval(e,g) for e in read_all('(fib 20)')][-1] print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-C: " -/usr/bin/time -f "%e s" ./c/uncommonlisp -e '(define (fib n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))) (display (fib 20)) (newline)' 2>&1 +printf " lumbda-C: " +/usr/bin/time -f "%e s" ./c/lumbda -e '(define (fib n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))) (display (fib 20)) (newline)' 2>&1 echo @@ -82,9 +82,9 @@ def ack(m,n): t=time.perf_counter(); r=ack(3,4); print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-Python: " +printf " lumbda-Python: " python3 -c " -import time,sys; sys.setrecursionlimit(50000); from uncommonlisp import * +import time,sys; sys.setrecursionlimit(50000); from lumbda import * g=make_global_env(); [leval(e,g) for e in read_all(PRELUDE)] [leval(e,g) for e in read_all('(auto-compile! #t)')] [leval(e,g) for e in read_all('(define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1))))))')] @@ -92,8 +92,8 @@ t=time.perf_counter(); r=[leval(e,g) for e in read_all('(ack 3 4)')][-1] print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-C: " -/usr/bin/time -f "%e s" ./c/uncommonlisp -e '(define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1)))))) (display (ack 3 4)) (newline)' 2>&1 +printf " lumbda-C: " +/usr/bin/time -f "%e s" ./c/lumbda -e '(define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1)))))) (display (ack 3 4)) (newline)' 2>&1 echo @@ -110,9 +110,9 @@ def s(n): t=time.perf_counter(); r=s(50000); print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-Python: " +printf " lumbda-Python: " python3 -c " -import time; from uncommonlisp import * +import time; from lumbda import * g=make_global_env(); [leval(e,g) for e in read_all(PRELUDE)] [leval(e,g) for e in read_all('(auto-compile! #t)')] [leval(e,g) for e in read_all('(define (sum-to n) (let loop ((i n) (acc 0)) (if (= i 0) acc (loop (- i 1) (+ acc i)))))')] @@ -120,8 +120,8 @@ t=time.perf_counter(); r=[leval(e,g) for e in read_all('(sum-to 50000)')][-1] print(f'{(time.perf_counter()-t)*1000:.3f}ms result={r}') " -printf " uncommonlisp-C: " -/usr/bin/time -f "%e s" ./c/uncommonlisp -e '(define (sum-to n) (let loop ((i n) (acc 0)) (if (= i 0) acc (loop (- i 1) (+ acc i))))) (display (sum-to 50000)) (newline)' 2>&1 +printf " lumbda-C: " +/usr/bin/time -f "%e s" ./c/lumbda -e '(define (sum-to n) (let loop ((i n) (acc 0)) (if (= i 0) acc (loop (- i 1) (+ acc i))))) (display (sum-to 50000)) (newline)' 2>&1 echo echo "═══════════════════════════════════════════════════════════════" diff --git a/uncommonlisp.py b/lumbda.py similarity index 99% rename from uncommonlisp.py rename to lumbda.py index c59fd5c..6cfdce1 100644 --- a/uncommonlisp.py +++ b/lumbda.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 """ -uncommonlisp — a Lisp in one Python file. -Usage: python3 uncommonlisp.py [script.lsp] # run a file - python3 uncommonlisp.py # interactive REPL - python3 uncommonlisp.py -e '(+ 1 2)' # eval expression +lumbda — a Lisp in one Python file. +Usage: python3 lumbda.py [script.lsp] # run a file + python3 lumbda.py # interactive REPL + python3 lumbda.py -e '(+ 1 2)' # eval expression """ import sys, re, math, itertools, os as _os from fractions import Fraction @@ -2217,7 +2217,7 @@ def portal_save(env, path, continuation=None): """Save machine state to a .portal file.""" ser = _PortalSerializer() state = { - 'format': 'uncommonlisp-portal-v1', + 'format': 'lumbda-portal-v1', 'env': ser.serialize_env(env), 'continuation': ser.serialize_continuation(continuation) if continuation else None, 'auto_compile': _auto_compile[0], @@ -2231,7 +2231,7 @@ def portal_resume(path, base_env=None): """Resume machine state from a .portal file. Returns (env, continuation_or_None).""" with open(path) as f: state = _json.load(f) - if state.get('format') != 'uncommonlisp-portal-v1': + if state.get('format') != 'lumbda-portal-v1': raise LispErr(f'portal: unsupported format: {state.get("format")}') if base_env is None: base_env = make_global_env() @@ -3488,7 +3488,7 @@ def make_global_env(): d(S('else'), True) d(S('...'), S('...')) d(S('*version*'), '1.0.0') - d(S('*name*'), 'uncommonlisp') + d(S('*name*'), 'lumbda') return g @@ -3621,7 +3621,7 @@ PRELUDE = r""" def repl(env, prompt='λ> ', quiet=False): if not quiet: - print(f'uncommonlisp {env.lookup(S("*version*"))} ' + print(f'lumbda {env.lookup(S("*version*"))} ' f'— (exit) to quit, (load "file.lsp") to load') buf = '' while True: @@ -3674,11 +3674,11 @@ def main(): # --help / -h if '--help' in args or '-h' in args: - print('''uncommonlisp — a Scheme in one Python file + print('''lumbda — a Scheme in one Python file -Usage: uncommonlisp [options] [script.lsp] [args...] - uncommonlisp -e '(+ 1 2)' - uncommonlisp (interactive REPL) +Usage: lumbda [options] [script.lsp] [args...] + lumbda -e '(+ 1 2)' + lumbda (interactive REPL) Options: -e EXPR evaluate expression and print result @@ -3692,7 +3692,7 @@ Features: R7RS core, bytecode compiler, full continuations, macros, # --version / -v if '--version' in args or '-v' in args: - print(f'uncommonlisp 1.0.0'); return + print(f'lumbda 1.0.0'); return # --fast / -f: enable auto-compile if '--fast' in args or '-f' in args: @@ -3703,7 +3703,7 @@ Features: R7RS core, bytecode compiler, full continuations, macros, if '--compile' in args: args = [a for a in args if a != '--compile'] if not args: - print('usage: uncommonlisp --compile file.lsp', file=sys.stderr); sys.exit(1) + print('usage: lumbda --compile file.lsp', file=sys.stderr); sys.exit(1) path = args[0]; out = path.rsplit('.', 1)[0] + '.lspc' _auto_compile[0] = True _load(path, g) @@ -3721,7 +3721,7 @@ Features: R7RS core, bytecode compiler, full continuations, macros, if '--portal-resume' in args: args = [a for a in args if a != '--portal-resume'] if not args: - print('usage: uncommonlisp --portal-resume state.portal', file=sys.stderr); sys.exit(1) + print('usage: lumbda --portal-resume state.portal', file=sys.stderr); sys.exit(1) path = args[0] env, cont = portal_resume(path, g) if cont is not None: @@ -3739,7 +3739,7 @@ Features: R7RS core, bytecode compiler, full continuations, macros, # -e 'expr' mode if args and args[0] == '-e': if len(args) < 2: - print('usage: uncommonlisp -e ', file=sys.stderr) + print('usage: lumbda -e ', file=sys.stderr) sys.exit(1) for expr in read_all(args[1]): result = leval(expr, g) diff --git a/proof/benchmark.sh b/proof/benchmark.sh index b666e4e..0a5ca47 100644 --- a/proof/benchmark.sh +++ b/proof/benchmark.sh @@ -1,10 +1,10 @@ #!/bin/bash -# benchmark.sh — Run EML proof in both Python and uncommonlisp, compare times +# benchmark.sh — Run EML proof in both Python and lumbda, compare times # # Usage: cd proof && bash benchmark.sh echo "═══════════════════════════════════════════════════════════════" -echo "EML Universality Proof — Benchmark: Python vs uncommonlisp" +echo "EML Universality Proof — Benchmark: Python vs lumbda" echo "═══════════════════════════════════════════════════════════════" echo @@ -13,9 +13,9 @@ echo "---" time python3 eml_proof.py echo -echo ">>> uncommonlisp implementation (--fast = bytecode compiled)" +echo ">>> lumbda implementation (--fast = bytecode compiled)" echo "---" -time python3 ../uncommonlisp.py --fast eml_proof.lsp +time python3 ../lumbda.py --fast eml_proof.lsp echo echo "═══════════════════════════════════════════════════════════════" diff --git a/proof/benchmark_results.md b/proof/benchmark_results.md index 46d8537..46506cf 100644 --- a/proof/benchmark_results.md +++ b/proof/benchmark_results.md @@ -8,7 +8,7 @@ with constant 1 generates all elementary functions (arXiv:2603.21852v2). | Approach | Time | Guarantee | Friction | |----------|------|-----------|----------| | Python (numerical) | 0.04s | 1e-10 tolerance | Low | -| uncommonlisp (numerical) | 59s | 1e-10 tolerance | High | +| lumbda (numerical) | 59s | 1e-10 tolerance | High | | Lean 4 (formal proof) | 1.5s | kernel-verified | Medium | ## Analysis @@ -16,7 +16,7 @@ with constant 1 generates all elementary functions (arXiv:2603.21852v2). **The formal proof is 40x faster than brute-force search and provides mathematical certainty instead of floating-point tolerance.** -The numerical approaches (Python and uncommonlisp) perform O(N²) pairwise +The numerical approaches (Python and lumbda) perform O(N²) pairwise enumeration of EML trees, evaluating at transcendental test points and comparing against target functions. This is MOAD-0001 at the proof layer: quadratic search friction where algebraic reasoning suffices. diff --git a/proof/eml_proof.lsp b/proof/eml_proof.lsp index 540e95b..7c7bff9 100644 --- a/proof/eml_proof.lsp +++ b/proof/eml_proof.lsp @@ -1,9 +1,9 @@ -;;; eml_proof.lsp — Verify EML universality in uncommonlisp +;;; eml_proof.lsp — Verify EML universality in lumbda ;;; ;;; eml(x, y) = exp(x) - ln(y) generates all elementary functions. ;;; Reference: "All elementary functions from a single operator" (arXiv:2603.21852v2) ;;; -;;; Run: python3 uncommonlisp.py --fast proof/eml_proof.lsp +;;; Run: python3 lumbda.py --fast proof/eml_proof.lsp ;;; ═══════════════════════════════════════════════════════════════════ ;;; EML operator and test infrastructure @@ -35,7 +35,7 @@ (define gamma 0.5772156649015329) (define apery 1.2020569031595943) -(display "EML Universality Proof — uncommonlisp") (newline) +(display "EML Universality Proof — lumbda") (newline) (display "eml(x, y) = exp(x) - ln(y)") (newline) (display "======================================================================") (newline) @@ -118,7 +118,7 @@ (display "----------------------------------------------------------------------") (newline) (display " Key insight: ln(negative) = ln(|neg|) + iπ") (newline) (display " From -1, ln(-1) = iπ, giving access to complex plane.") (newline) -(display " uncommonlisp uses real arithmetic; verifying the chain:") (newline) +(display " lumbda uses real arithmetic; verifying the chain:") (newline) (newline) ;; Verify the real-arithmetic building blocks that WOULD give complex access: diff --git a/proof/eml_proof_in_lumbda.lsp b/proof/eml_proof_in_lumbda.lsp index 643d4bf..0513cc5 100644 --- a/proof/eml_proof_in_lumbda.lsp +++ b/proof/eml_proof_in_lumbda.lsp @@ -12,9 +12,9 @@ ;;; that checks it live in the same file. ;;; ;;; Runs byte-identically in Python, C, and asm: -;;; python3 uncommonlisp.py --fast proof/eml_proof_in_lumbda.lsp -;;; ./c/uncommonlisp proof/eml_proof_in_lumbda.lsp -;;; ./asm/uncommonlisp < proof/eml_proof_in_lumbda.lsp +;;; python3 lumbda.py --fast proof/eml_proof_in_lumbda.lsp +;;; ./c/lumbda proof/eml_proof_in_lumbda.lsp +;;; ./asm/lumbda < proof/eml_proof_in_lumbda.lsp ;;; ═══════════════════════════════════════════════════════════════ ;;; Term-rewriting engine diff --git a/stdlib.lsp b/stdlib.lsp index 74e6ef7..16c3197 100644 --- a/stdlib.lsp +++ b/stdlib.lsp @@ -1,6 +1,6 @@ -;;; stdlib.lsp — standard library for uncommonlisp +;;; stdlib.lsp — standard library for lumbda ;;; Load with: (load "stdlib.lsp") -;;; Automatically loaded by the interpreter if found next to uncommonlisp.py. +;;; Automatically loaded by the interpreter if found next to lumbda.py. ;;;; ── Syntax-rules versions of core macros ──────────────────────────────── diff --git a/tests.py b/tests.py index 07ebe69..eff79a4 100644 --- a/tests.py +++ b/tests.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -tests.py — unit, integration, and functional tests for uncommonlisp. +tests.py — unit, integration, and functional tests for lumbda. Run: python3 tests.py [-v] """ @@ -8,7 +8,7 @@ import sys, io, unittest, math, textwrap sys.setrecursionlimit(200) # intentionally low — proves TCO works # ── import the interpreter ──────────────────────────────────────────────────── -from uncommonlisp import ( +from lumbda import ( Symbol, S, NIL, Pair, Proc, Macro, VOID, EOF, LispErr, show, _tokenize, _tokenize_lines, read_all, _L, _P, _truthy, _formals, _equal, Env, _qq, leval, _call, make_global_env, PRELUDE, @@ -67,7 +67,7 @@ class TestSymbol(unittest.TestCase): class TestNil(unittest.TestCase): def test_singleton(self): - from uncommonlisp import _Nil + from lumbda import _Nil assert _Nil() is NIL def test_falsy(self): @@ -1509,7 +1509,7 @@ class TestCommandLine(unittest.TestCase): def _run(self, *args, input_text=None): import subprocess result = subprocess.run( - [sys.executable, 'uncommonlisp.py'] + list(args), + [sys.executable, 'lumbda.py'] + list(args), capture_output=True, text=True, input=input_text, cwd='/home/fox/git/uncommonlisp' ) @@ -1670,7 +1670,7 @@ class TestStringPorts(unittest.TestCase): def test_open_input_string_eof(self): r = run('(let ((p (open-input-string ""))) (read p))', self.g) - from uncommonlisp import EOF + from lumbda import EOF assert r is EOF def test_open_input_string_read_char(self): @@ -1728,7 +1728,7 @@ class TestErrorObjects(unittest.TestCase): def test_error_object_irritants_empty(self): r = run('(guard (e (#t (error-object-irritants e))) (error "no-irritants"))', self.g) - from uncommonlisp import NIL + from lumbda import NIL assert r is NIL def test_with_exception_handler_gets_error_object(self): @@ -2717,7 +2717,7 @@ class TestSourceMaps(unittest.TestCase): f.write('(define x 1)\n(define y 2)\n(+ x y)') path = f.name try: - from uncommonlisp import _load + from lumbda import _load env = fresh() _load(path, env) assert env.lookup(S('x')) == 1 @@ -3029,7 +3029,7 @@ class TestBytecodeSerialization(unittest.TestCase): lspc = path.rsplit('.', 1)[0] + '.lspc' try: result = subprocess.run( - ['python3', 'uncommonlisp.py', '--compile', path], + ['python3', 'lumbda.py', '--compile', path], capture_output=True, text=True, timeout=30) assert result.returncode == 0 assert os.path.exists(lspc) @@ -3177,7 +3177,7 @@ class TestPortal(unittest.TestCase): try: portal_save(self.g, path) result = subprocess.run( - ['python3', 'uncommonlisp.py', '--portal-resume', path, + ['python3', 'lumbda.py', '--portal-resume', path, '-e', '(display answer)'], capture_output=True, text=True, timeout=30) # portal-resume loads state, then -e isn't processed (portal-resume returns) @@ -3195,7 +3195,7 @@ class TestPortal(unittest.TestCase): portal_save(self.g, path) with open(path) as f: data = json.load(f) - assert data['format'] == 'uncommonlisp-portal-v1' + assert data['format'] == 'lumbda-portal-v1' assert 'objects' in data assert 'env' in data finally: diff --git a/tests/bench-3way.sh b/tests/bench-3way.sh index ec2d4aa..1b0b281 100755 --- a/tests/bench-3way.sh +++ b/tests/bench-3way.sh @@ -60,15 +60,15 @@ best_of_two() { } echo "── Python (--fast) ──" -best_of_two "python3 uncommonlisp.py --fast /tmp/bench-3way.lsp" +best_of_two "python3 lumbda.py --fast /tmp/bench-3way.lsp" echo echo "── C (--fast) ──" -best_of_two "c/uncommonlisp --fast /tmp/bench-3way.lsp" +best_of_two "c/lumbda --fast /tmp/bench-3way.lsp" echo echo "── asm ──" -best_of_two "asm/uncommonlisp < /tmp/bench-3way.lsp" +best_of_two "asm/lumbda < /tmp/bench-3way.lsp" echo rm -f /tmp/bench-3way.lsp diff --git a/tests/bench-gc-adaptive.sh b/tests/bench-gc-adaptive.sh index 0667689..5cf0354 100755 --- a/tests/bench-gc-adaptive.sh +++ b/tests/bench-gc-adaptive.sh @@ -6,7 +6,7 @@ set -e cd "$(dirname "$0")/.." ulimit -v 524288 -trap 'pkill -9 -u "$USER" -f "asm/uncommonlisp" 2>/dev/null || true' EXIT +trap 'pkill -9 -u "$USER" -f "asm/lumbda" 2>/dev/null || true' EXIT make -s -C asm all @@ -20,7 +20,7 @@ run_phase() { echo "(define *workload* $workload)" echo "(define *mode* $mode)" cat examples/bench-gc-adaptive.lsp - } | timeout 60 ./asm/uncommonlisp-gc + } | timeout 60 ./asm/lumbda-gc echo "" } @@ -31,7 +31,7 @@ run_phase "hostile" 1 1 "adaptive" run_phase "mixed" 2 0 "greedy" run_phase "mixed" 2 1 "adaptive" -if pgrep -u "$USER" -f 'asm/uncommonlisp' > /dev/null; then +if pgrep -u "$USER" -f 'asm/lumbda' > /dev/null; then echo "STRAGGLER" >&2 exit 1 fi diff --git a/tests/bench-gc-arena.sh b/tests/bench-gc-arena.sh index 7df86d6..492e34a 100755 --- a/tests/bench-gc-arena.sh +++ b/tests/bench-gc-arena.sh @@ -7,12 +7,12 @@ set -e cd "$(dirname "$0")/.." ulimit -v 524288 -trap 'pkill -9 -u "$USER" -f "asm/uncommonlisp" 2>/dev/null || true' EXIT +trap 'pkill -9 -u "$USER" -f "asm/lumbda" 2>/dev/null || true' EXIT make -s -C asm all echo "== asm (naive GC, with arena as meta fast path) ==" -./asm/uncommonlisp-gc < examples/bench-gc-arena.lsp & +./asm/lumbda-gc < examples/bench-gc-arena.lsp & pid=$! peak=0 while kill -0 "$pid" 2>/dev/null; do @@ -24,7 +24,7 @@ wait "$pid" || true echo "" echo "peak_rss_kb=$peak" -if pgrep -u "$USER" -f 'asm/uncommonlisp' > /dev/null; then +if pgrep -u "$USER" -f 'asm/lumbda' > /dev/null; then echo "STRAGGLER" >&2 exit 1 fi diff --git a/tests/bench-gc-http.sh b/tests/bench-gc-http.sh index 5e54a1c..b0a46d5 100755 --- a/tests/bench-gc-http.sh +++ b/tests/bench-gc-http.sh @@ -96,9 +96,9 @@ run_case() { # to completion rather than OOM'd. VCAP=${VCAP:-524288} -run_case "asm no-GC + snapshot loop" "./asm/uncommonlisp" "examples/http-server.lsp" "$VCAP" || true -run_case "asm GC + snapshot loop" "./asm/uncommonlisp-gc" "examples/http-server.lsp" "$VCAP" || true -run_case "asm no-GC + no snapshot" "./asm/uncommonlisp" "examples/http-server-noarena.lsp" "$VCAP" || true -run_case "asm GC + no snapshot" "./asm/uncommonlisp-gc" "examples/http-server-noarena.lsp" "$VCAP" || true +run_case "asm no-GC + snapshot loop" "./asm/lumbda" "examples/http-server.lsp" "$VCAP" || true +run_case "asm GC + snapshot loop" "./asm/lumbda-gc" "examples/http-server.lsp" "$VCAP" || true +run_case "asm no-GC + no snapshot" "./asm/lumbda" "examples/http-server-noarena.lsp" "$VCAP" || true +run_case "asm GC + no snapshot" "./asm/lumbda-gc" "examples/http-server-noarena.lsp" "$VCAP" || true printf "\n" diff --git a/tests/bench-gc-memory.sh b/tests/bench-gc-memory.sh index 97dac03..c8bf059 100755 --- a/tests/bench-gc-memory.sh +++ b/tests/bench-gc-memory.sh @@ -7,7 +7,7 @@ set -e cd "$(dirname "$0")/.." ulimit -v 524288 -trap 'pkill -9 -u "$USER" -f "asm/uncommonlisp" 2>/dev/null || true' EXIT +trap 'pkill -9 -u "$USER" -f "asm/lumbda" 2>/dev/null || true' EXIT make -s -C asm all @@ -35,12 +35,12 @@ run_with_sampling() { echo "" } -run_with_sampling ./asm/uncommonlisp "asm (no GC, 64 MB chunks)" -run_with_sampling ./asm/uncommonlisp-gc "asm (naive GC, 1 MB chunks)" +run_with_sampling ./asm/lumbda "asm (no GC, 64 MB chunks)" +run_with_sampling ./asm/lumbda-gc "asm (naive GC, 1 MB chunks)" rm -f /tmp/gc-bench.out -if pgrep -u "$USER" -f 'asm/uncommonlisp' > /dev/null; then +if pgrep -u "$USER" -f 'asm/lumbda' > /dev/null; then echo "STRAGGLER detected" >&2 exit 1 fi diff --git a/tests/bench-hashset.sh b/tests/bench-hashset.sh index d849cb7..fd2bbc9 100755 --- a/tests/bench-hashset.sh +++ b/tests/bench-hashset.sh @@ -5,26 +5,26 @@ set +e cd "$(dirname "$0")/.." ulimit -v 524288 -trap 'pkill -9 -u "$USER" -f "asm/uncommonlisp" 2>/dev/null || true' EXIT +trap 'pkill -9 -u "$USER" -f "asm/lumbda" 2>/dev/null || true' EXIT # Build if needed -if [ ! -x asm/uncommonlisp ] || [ asm/uncommonlisp.s -nt asm/uncommonlisp ]; then +if [ ! -x asm/lumbda ] || [ asm/lumbda.s -nt asm/lumbda ]; then make -s asm-build fi echo "── asm no-GC ──" -timeout 60 ./asm/uncommonlisp < examples/bench-hashset.lsp +timeout 60 ./asm/lumbda < examples/bench-hashset.lsp echo "" echo "── asm GC (GC_NAIVE build) ──" # Under GC_NAIVE the heap is 1 MB per chunk; build-list(K=500) runs # into the bump threshold and triggers implicit GC. That's the # intended comparison — same primitives, different allocator. -timeout 60 ./asm/uncommonlisp-gc < examples/bench-hashset.lsp +timeout 60 ./asm/lumbda-gc < examples/bench-hashset.lsp # Verify cleanup. pgrep with -x matches the exact command basename # so it doesn't false-positive on the parent shell. -if pgrep -u "$USER" -x uncommonlisp > /dev/null || \ - pgrep -u "$USER" -x uncommonlisp-gc > /dev/null; then +if pgrep -u "$USER" -x lumbda > /dev/null || \ + pgrep -u "$USER" -x lumbda-gc > /dev/null; then echo "STRAGGLER asm binary detected" >&2 exit 1 fi diff --git a/tests/bench-proof.sh b/tests/bench-proof.sh index ab09044..987e518 100755 --- a/tests/bench-proof.sh +++ b/tests/bench-proof.sh @@ -52,17 +52,17 @@ echo "════════════════════════ printf " %-38s %s\n" "Lumbda tier" "cold cached" printf " %-38s %s\n" "─────────────────────────────────────" "───────────────" printf " %-38s %4s ms %4s ms\n" "Python --fast" \ - "$(bestof_cold 'python3 uncommonlisp.py --fast proof/eml_proof_in_lumbda.lsp')" \ - "$(bestof_cached 'python3 uncommonlisp.py --fast proof/eml_proof_in_lumbda.lsp')" + "$(bestof_cold 'python3 lumbda.py --fast proof/eml_proof_in_lumbda.lsp')" \ + "$(bestof_cached 'python3 lumbda.py --fast proof/eml_proof_in_lumbda.lsp')" printf " %-38s %4s ms %4s ms\n" "C (tree-walker)" \ - "$(bestof_cold 'c/uncommonlisp proof/eml_proof_in_lumbda.lsp')" \ - "$(bestof_cached 'c/uncommonlisp proof/eml_proof_in_lumbda.lsp')" + "$(bestof_cold 'c/lumbda proof/eml_proof_in_lumbda.lsp')" \ + "$(bestof_cached 'c/lumbda proof/eml_proof_in_lumbda.lsp')" printf " %-38s %4s ms %4s ms\n" "C --fast (bytecode VM)" \ - "$(bestof_cold 'timeout 15 c/uncommonlisp --fast proof/eml_proof_in_lumbda.lsp')" \ - "$(bestof_cached 'timeout 15 c/uncommonlisp --fast proof/eml_proof_in_lumbda.lsp')" + "$(bestof_cold 'timeout 15 c/lumbda --fast proof/eml_proof_in_lumbda.lsp')" \ + "$(bestof_cached 'timeout 15 c/lumbda --fast proof/eml_proof_in_lumbda.lsp')" printf " %-38s %4s ms %4s ms\n" "asm" \ - "$(bestof_cold 'asm/uncommonlisp < proof/eml_proof_in_lumbda.lsp')" \ - "$(bestof_cached 'asm/uncommonlisp < proof/eml_proof_in_lumbda.lsp')" + "$(bestof_cold 'asm/lumbda < proof/eml_proof_in_lumbda.lsp')" \ + "$(bestof_cached 'asm/lumbda < proof/eml_proof_in_lumbda.lsp')" echo "" echo " Lean 4 comparison:" diff --git a/tests/functional.lsp b/tests/functional.lsp index 3d3621d..34ac7da 100644 --- a/tests/functional.lsp +++ b/tests/functional.lsp @@ -1,8 +1,8 @@ ;;; functional.lsp — Shared functional test suite ;;; Runs identically in both Python and C implementations. ;;; -;;; Python: python3 uncommonlisp.py --fast tests/functional.lsp -;;; C: ./c/uncommonlisp tests/functional.lsp +;;; Python: python3 lumbda.py --fast tests/functional.lsp +;;; C: ./c/lumbda tests/functional.lsp ;;; ;;; Output: lines of "PASS: name" or "FAIL: name got=X expected=Y" ;;; Exit: displays summary at end @@ -595,11 +595,11 @@ ;;; File I/O: write-file / file->string round-trip ;;; ═══════════════════════════════════════════════════════════════ -(define *tmp-path* "/tmp/uncommonlisp-functional-fio.txt") +(define *tmp-path* "/tmp/lumbda-functional-fio.txt") (assert-true "write-file basic" (write-file *tmp-path* "hello\n")) (assert-equal "file->string round-trip" (file->string *tmp-path*) "hello\n") -(assert-false "file->string missing" (file->string "/tmp/__nope_uncommonlisp_fio__")) +(assert-false "file->string missing" (file->string "/tmp/__nope_lumbda_fio__")) (assert-true "write-file overwrite" (begin (write-file *tmp-path* "second") (string=? (file->string *tmp-path*) "second"))) @@ -608,7 +608,7 @@ ;;; Cross-impl state exchange using only string primitives ;;; ═══════════════════════════════════════════════════════════════ -(define *portal-path* "/tmp/uncommonlisp-functional-portal.sexp") +(define *portal-path* "/tmp/lumbda-functional-portal.sexp") (write-file *portal-path* "(define portal-x 111)\n(define portal-y 222)\n(define portal-z 333)\n") diff --git a/tests/portal-benchmark.sh b/tests/portal-benchmark.sh index a7fa816..1534d41 100755 --- a/tests/portal-benchmark.sh +++ b/tests/portal-benchmark.sh @@ -11,9 +11,9 @@ set -u cd "$(dirname "$0")/.." -PY="python3 uncommonlisp.py --fast" -C="./c/uncommonlisp" -ASM="./asm/uncommonlisp" +PY="python3 lumbda.py --fast" +C="./c/lumbda" +ASM="./asm/lumbda" N=50 pad() { printf " %-42s " "$1"; } diff --git a/tests/portal-cross-test.sh b/tests/portal-cross-test.sh index 7c08587..a982dda 100755 --- a/tests/portal-cross-test.sh +++ b/tests/portal-cross-test.sh @@ -13,9 +13,9 @@ set -e cd "$(dirname "$0")/.." -PY="python3 uncommonlisp.py --fast" -C="./c/uncommonlisp" -ASM="./asm/uncommonlisp" +PY="python3 lumbda.py --fast" +C="./c/lumbda" +ASM="./asm/lumbda" SEXP=/tmp/portal-xtest.sexp PASS=0 diff --git a/tests/portal-exchange.lsp b/tests/portal-exchange.lsp index 78bb0fd..cc43cbb 100644 --- a/tests/portal-exchange.lsp +++ b/tests/portal-exchange.lsp @@ -16,7 +16,7 @@ ;; Write all user-defined bindings as (define name value) forms ;; that any Scheme can evaluate to restore state (let ((port (open-output-file filename))) - (display ";; uncommonlisp portable state" port) + (display ";; lumbda portable state" port) (newline port) (display ";; generated by portal-save-sexp" port) (newline port) diff --git a/tests/portal-formats.lsp b/tests/portal-formats.lsp index 611b11d..11e0b7d 100644 --- a/tests/portal-formats.lsp +++ b/tests/portal-formats.lsp @@ -4,9 +4,9 @@ ;;; 2. JSON (Python + C) ;;; 3. Binary heap dump (assembly only, fastest) ;;; -;;; Run in Python: python3 uncommonlisp.py --fast tests/portal-formats.lsp -;;; Run in C: ./c/uncommonlisp tests/portal-formats.lsp -;;; Asm: asm/uncommonlisp < tests/portal-cross-load.lsp (no `load` builtin) +;;; Run in Python: python3 lumbda.py --fast tests/portal-formats.lsp +;;; Run in C: ./c/lumbda tests/portal-formats.lsp +;;; Asm: asm/lumbda < tests/portal-cross-load.lsp (no `load` builtin) ;;; ;;; ── Observed results (2026-04-16, same laptop) ───────────────── ;;; @@ -47,7 +47,7 @@ (define (write-sexp-portal filename) (let ((port (open-output-file filename))) ;; Header - (display ";; uncommonlisp portable state (S-expression format)" port) + (display ";; lumbda portable state (S-expression format)" port) (newline port) (display ";; resume: (load \"" port) (display filename port) diff --git a/tests/rpc-chain-bench.sh b/tests/rpc-chain-bench.sh index f39fbfe..ff081d3 100755 --- a/tests/rpc-chain-bench.sh +++ b/tests/rpc-chain-bench.sh @@ -24,7 +24,7 @@ SPAWNED=() cleanup() { for pid in "${SPAWNED[@]}"; do kill -9 "$pid" 2>/dev/null; done sleep 0.2 - pkill -9 -u "$USER" -f 'uncommonlisp.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true + pkill -9 -u "$USER" -f 'lumbda.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true } trap cleanup EXIT INT TERM @@ -61,17 +61,17 @@ stop_bg() { verify_clean() { local strays - strays=$(pgrep -u "$USER" -f 'uncommonlisp.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true) + strays=$(pgrep -u "$USER" -f 'lumbda.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true) if [ -n "$strays" ]; then echo "!! STRAYS: $strays" >&2 - pkill -9 -u "$USER" -f 'uncommonlisp.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true + pkill -9 -u "$USER" -f 'lumbda.*(rpc|repl)-(server|relay|chain-bench)\.lsp' 2>/dev/null || true return 1 fi } -PY="python3 uncommonlisp.py --fast" -C="./c/uncommonlisp" -ASM="./asm/uncommonlisp" +PY="python3 lumbda.py --fast" +C="./c/lumbda" +ASM="./asm/lumbda" # Always use Python client to drive (identical across benches). # We sed the hardcoded port in-place because asm's top-level diff --git a/tests/web-benchmark.sh b/tests/web-benchmark.sh index daa33ae..3d7705a 100755 --- a/tests/web-benchmark.sh +++ b/tests/web-benchmark.sh @@ -1,5 +1,5 @@ #!/bin/bash -# web-benchmark.sh — race the three uncommonlisp HTTP servers +# web-benchmark.sh — race the three lumbda HTTP servers # against Python http.server and busybox httpd. # # No wrk/ab/nginx dependency — we use xargs+curl for concurrency. @@ -12,10 +12,10 @@ cd "$(dirname "$0")/.." REQUESTS=${REQUESTS:-500} CONCURRENCY=${CONCURRENCY:-10} -PY="python3 uncommonlisp.py --fast" -C="./c/uncommonlisp" -ASM="./asm/uncommonlisp" -ASM_GC="./asm/uncommonlisp-gc" +PY="python3 lumbda.py --fast" +C="./c/lumbda" +ASM="./asm/lumbda" +ASM_GC="./asm/lumbda-gc" # Track every server PID we spawn; the EXIT trap kills them all. # Asm has no GC — a leaked server leaks 64 MB per heap growth @@ -34,7 +34,7 @@ cleanup() { rm -rf "${STATIC_DIR:-/nonexistent/xyz}" # Final sanity: any stray servers from examples/http-server? # Narrow to processes actually serving the HTTP example, not the - # shell running this script or tmux sessions with "uncommonlisp" + # shell running this script or tmux sessions with "lumbda" # in their name. local strays strays=$(pgrep -u "$USER" -f 'examples/http-server\.lsp|http\.server 8080' | wc -l) @@ -106,25 +106,25 @@ stop_server() { sleep 0.2 } -# ── uncommonlisp Python ── +# ── lumbda Python ── PID=$(start_server "$PY examples/http-server.lsp" 8080) -bench_one "uncommonlisp Python (/bench, 1 KB)" 8080 /bench +bench_one "lumbda Python (/bench, 1 KB)" 8080 /bench stop_server "$PID" -# ── uncommonlisp C ── +# ── lumbda C ── PID=$(start_server "$C examples/http-server.lsp" 8080) -bench_one "uncommonlisp C (/bench, 1 KB)" 8080 /bench +bench_one "lumbda C (/bench, 1 KB)" 8080 /bench stop_server "$PID" -# ── uncommonlisp asm (bump-only) ── +# ── lumbda asm (bump-only) ── PID=$(start_server "$ASM < examples/http-server.lsp" 8080) -bench_one "uncommonlisp asm (/bench, 1 KB)" 8080 /bench +bench_one "lumbda asm (/bench, 1 KB)" 8080 /bench stop_server "$PID" -# ── uncommonlisp asm-gc (naive mark-sweep + meta-GC build) ── +# ── lumbda asm-gc (naive mark-sweep + meta-GC build) ── if [ -x "$ASM_GC" ]; then PID=$(start_server "$ASM_GC < examples/http-server.lsp" 8080) - bench_one "uncommonlisp asm-gc (/bench, 1 KB)" 8080 /bench + bench_one "lumbda asm-gc (/bench, 1 KB)" 8080 /bench stop_server "$PID" fi @@ -148,9 +148,9 @@ echo echo "═══════════════════════════════════════════════════════════════" echo "Binary sizes" echo "═══════════════════════════════════════════════════════════════" -printf " uncommonlisp asm: %s\n" "$(du -b asm/uncommonlisp | cut -f1) bytes" -[ -x asm/uncommonlisp-gc ] && \ -printf " uncommonlisp asm-gc: %s\n" "$(du -b asm/uncommonlisp-gc | cut -f1) bytes (GC_NAIVE build)" -printf " uncommonlisp C: %s\n" "$(du -b c/uncommonlisp | cut -f1) bytes" +printf " lumbda asm: %s\n" "$(du -b asm/lumbda | cut -f1) bytes" +[ -x asm/lumbda-gc ] && \ +printf " lumbda asm-gc: %s\n" "$(du -b asm/lumbda-gc | cut -f1) bytes (GC_NAIVE build)" +printf " lumbda C: %s\n" "$(du -b c/lumbda | cut -f1) bytes" printf " busybox httpd: %s\n" "$(du -b /usr/bin/busybox | cut -f1) bytes (multi-call)" printf " python3: %s bytes (interpreter binary)\n" "$(du -bL $(which python3) | cut -f1)" diff --git a/whitepaper/WHITEPAPER.pdf b/whitepaper/WHITEPAPER.pdf index 695f540..e0bb2fa 120000 --- a/whitepaper/WHITEPAPER.pdf +++ b/whitepaper/WHITEPAPER.pdf @@ -1 +1 @@ -uncommonlisp-whitepaper.pdf \ No newline at end of file +lumbda-whitepaper.pdf \ No newline at end of file diff --git a/whitepaper/WHITEPAPER.rst b/whitepaper/WHITEPAPER.rst index b61560e..3a2671a 120000 --- a/whitepaper/WHITEPAPER.rst +++ b/whitepaper/WHITEPAPER.rst @@ -1 +1 @@ -uncommonlisp-whitepaper.rst \ No newline at end of file +lumbda-whitepaper.rst \ No newline at end of file diff --git a/whitepaper/uncommonlisp-whitepaper.pdf b/whitepaper/lumbda-whitepaper.pdf similarity index 99% rename from whitepaper/uncommonlisp-whitepaper.pdf rename to whitepaper/lumbda-whitepaper.pdf index d5b6246..1314234 100644 --- a/whitepaper/uncommonlisp-whitepaper.pdf +++ b/whitepaper/lumbda-whitepaper.pdf @@ -584,7 +584,7 @@ endobj endobj 69 0 obj << -/Author () /CreationDate (D:20260419094254-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260419094254-04'00') /Producer (ReportLab PDF Library - \(opensource\)) +/Author () /CreationDate (D:20260419101758-04'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260419101758-04'00') /Producer (ReportLab PDF Library - \(opensource\)) /Subject (\(unspecified\)) /Title () /Trapped /False >> endobj @@ -875,7 +875,7 @@ endobj endobj 125 0 obj << -/Dest [ 57 0 R /XYZ 57.02362 265.0236 0 ] /Next 126 0 R /Parent 123 0 R /Prev 124 0 R /Title (12.2 MOAD-0002: The Intertangle in Our Own Design) +/Dest [ 57 0 R /XYZ 57.02362 277.0236 0 ] /Next 126 0 R /Parent 123 0 R /Prev 124 0 R /Title (12.2 MOAD-0002: The Intertangle in Our Own Design) >> endobj 126 0 obj @@ -4473,7 +4473,7 @@ endstream endobj 143 0 obj << -/Length 8523 +/Length 8511 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -4492,7 +4492,7 @@ n -6 -6 480.0283 31.2 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 11.2 Tm /F5 8 Tf 9.6 TL (as --64 --defsym GC_NAIVE=1 uncommonlisp.s # collecting build) Tj T* (as --64 uncommonlisp.s # default, bump-only) Tj T* ET +BT 1 0 0 1 0 11.2 Tm /F5 8 Tf 9.6 TL (as --64 --defsym GC_NAIVE=1 lumbda.s # collecting build) Tj T* (as --64 lumbda.s # default, bump-only) Tj T* ET Q Q Q @@ -6477,7 +6477,7 @@ endstream endobj 148 0 obj << -/Length 10633 +/Length 10627 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -6920,7 +6920,7 @@ n -6 -6 480.0283 21.6 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 1.6 Tm /F5 8 Tf 9.6 TL (python3 uncommonlisp.py --portal-resume state.portal) Tj T* ET +BT 1 0 0 1 0 1.6 Tm /F5 8 Tf 9.6 TL (python3 lumbda.py --portal-resume state.portal) Tj T* ET Q Q Q @@ -7905,7 +7905,7 @@ endstream endobj 152 0 obj << -/Length 10223 +/Length 10217 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -8206,7 +8206,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm .886835 Tw 12 TL /F3 10 Tf 0 0 0 rg (Self-hosted verification) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (proof/eml_proof.lsp) Tj /F1 10 Tf (\): The same proof runs in Lumbda's bytecode VM) Tj T* 0 Tw 2.063543 Tw (\() Tj /F5 10 Tf (python3) Tj ( ) Tj (uncommonlisp.py) Tj ( ) Tj (--fast) Tj ( ) Tj (proof/eml_proof.lsp) Tj /F1 10 Tf (\). The language verifies its own) Tj T* 0 Tw (mathematical foundations.) Tj T* ET +BT 1 0 0 1 0 26 Tm .886835 Tw 12 TL /F3 10 Tf 0 0 0 rg (Self-hosted verification) Tj /F1 10 Tf ( \() Tj /F5 10 Tf (proof/eml_proof.lsp) Tj /F1 10 Tf (\): The same proof runs in Lumbda's bytecode VM) Tj T* 0 Tw 6.563543 Tw (\() Tj /F5 10 Tf (python3) Tj ( ) Tj (lumbda.py) Tj ( ) Tj (--fast) Tj ( ) Tj (proof/eml_proof.lsp) Tj /F1 10 Tf (\). The language verifies its own) Tj T* 0 Tw (mathematical foundations.) Tj T* ET Q Q q @@ -9374,7 +9374,7 @@ endstream endobj 157 0 obj << -/Length 16605 +/Length 16587 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -10123,7 +10123,7 @@ q n -6 -6 480.0283 40.8 re B* Q q -BT 1 0 0 1 0 20.8 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (python3 uncommonlisp.py --fast examples/http-server.lsp) Tj T* (./c/uncommonlisp examples/http-server.lsp) Tj T* (./asm/uncommonlisp ) Tj (<) Tj ( examples/http-server.lsp) Tj T* ET +BT 1 0 0 1 0 20.8 Tm 9.6 TL /F5 8 Tf 0 0 0 rg (python3 lumbda.py --fast examples/http-server.lsp) Tj T* (./c/lumbda examples/http-server.lsp) Tj T* (./asm/lumbda ) Tj (<) Tj ( examples/http-server.lsp) Tj T* ET Q Q Q @@ -10975,7 +10975,7 @@ endstream endobj 161 0 obj << -/Length 8009 +/Length 7971 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET @@ -11091,7 +11091,7 @@ Q q 1 0 0 1 23 -3 cm q -BT 1 0 0 1 0 26 Tm .908543 Tw 12 TL /F5 10 Tf 0 0 0 rg (uncommonlisp.py) Tj /F1 10 Tf ('s ) Tj /F5 10 Tf (_tokenize_lines) Tj /F1 10 Tf ( called ) Tj /F5 10 Tf (src.count\('\\n',) Tj ( ) Tj (0,) Tj ( ) Tj (m.start\(\)\)) Tj /F1 10 Tf ( per token to) Tj T* 0 Tw 1.140596 Tw (compute line numbers. O\(N\267M\). Replaced with a single pass that builds a ) Tj /F5 10 Tf (line_starts) Tj /F1 10 Tf ( array, then) Tj T* 0 Tw (bisects per token. O\(M + N log M\).) Tj T* ET +BT 1 0 0 1 0 26 Tm .237594 Tw 12 TL /F5 10 Tf 0 0 0 rg (lumbda.py) Tj /F1 10 Tf ('s ) Tj /F5 10 Tf (_tokenize_lines) Tj /F1 10 Tf ( called ) Tj /F5 10 Tf (src.count\('\\n',) Tj ( ) Tj (0,) Tj ( ) Tj (m.start\(\)\)) Tj /F1 10 Tf ( per token to compute) Tj T* 0 Tw .39789 Tw (line numbers. O\(N\267M\). Replaced with a single pass that builds a ) Tj /F5 10 Tf (line_starts) Tj /F1 10 Tf ( array, then bisects per) Tj T* 0 Tw (token. O\(M + N log M\).) Tj T* ET Q Q q @@ -11102,39 +11102,39 @@ q 1 0 0 1 57.02362 387.0236 cm Q q -1 0 0 1 57.02362 297.0236 cm +1 0 0 1 57.02362 309.0236 cm q -BT 1 0 0 1 0 74 Tm 4.926213 Tw 12 TL /F1 10 Tf 0 0 0 rg (A third correctness fix landed after the portal-over-HTTP demo exposed it: ) Tj /F5 10 Tf (uncommonlisp.py) Tj /F1 10 Tf ('s) Tj T* 0 Tw .515223 Tw /F5 10 Tf (Env.lookup) Tj /F1 10 Tf ( used to short-cut from the local frame directly to the global frame before walking intermediate) Tj T* 0 Tw 1.47713 Tw (parents. That was fast but wrong \227 a let-loop parameter named the same as a global builtin \() Tj /F5 10 Tf (count) Tj /F1 10 Tf (, a) Tj T* 0 Tw .409897 Tw (SRFI-1 procedure\) got shadowed in reverse, the shortcut returned the global builtin instead of walking up to) Tj T* 0 Tw .07402 Tw (the loop's parameter frame. Fix: walk ) Tj /F5 10 Tf (self) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (self.p) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (...) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (global) Tj /F1 10 Tf ( in order, without any shortcut.) Tj T* 0 Tw 1.17189 Tw (The inline cache at ) Tj /F5 10 Tf (OP_LOOKUP) Tj /F1 10 Tf ( was correspondingly tightened to validate the full chain before firing. 980) Tj T* 0 Tw (tests remained green.) Tj T* ET +BT 1 0 0 1 0 62 Tm .226796 Tw 12 TL /F1 10 Tf 0 0 0 rg (A third correctness fix landed after the portal-over-HTTP demo exposed it: ) Tj /F5 10 Tf (lumbda.py) Tj /F1 10 Tf ('s ) Tj /F5 10 Tf (Env.lookup) Tj /F1 10 Tf ( used) Tj T* 0 Tw .794272 Tw (to short-cut from the local frame directly to the global frame before walking intermediate parents. That was) Tj T* 0 Tw .366019 Tw (fast but wrong \227 a let-loop parameter named the same as a global builtin \() Tj /F5 10 Tf (count) Tj /F1 10 Tf (, a SRFI-1 procedure\) got) Tj T* 0 Tw .949897 Tw (shadowed in reverse, the shortcut returned the global builtin instead of walking up to the loop's parameter) Tj T* 0 Tw .453797 Tw (frame. Fix: walk ) Tj /F5 10 Tf (self) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (self.p) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (...) Tj ( ) Tj /F6 10 Tf 12 TL (\256) Tj /F5 10 Tf 12 TL ( ) Tj (global) Tj /F1 10 Tf ( in order, without any shortcut. The inline cache at) Tj T* 0 Tw /F5 10 Tf (OP_LOOKUP) Tj /F1 10 Tf ( was correspondingly tightened to validate the full chain before firing. 980 tests remained green.) Tj T* ET Q Q q -1 0 0 1 57.02362 279.0236 cm +1 0 0 1 57.02362 291.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Every release audit surfaces more. Writing new code is writing new sediment, unless the audit runs.) Tj T* ET Q Q q -1 0 0 1 57.02362 253.0236 cm +1 0 0 1 57.02362 265.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf .133333 .133333 .133333 rg (12.2 MOAD-0002: The Intertangle in Our Own Design) Tj T* ET Q Q q -1 0 0 1 57.02362 235.0236 cm +1 0 0 1 57.02362 247.0236 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (All three implementations share mutable global state between subsystems:) Tj T* ET Q Q q -1 0 0 1 57.02362 229.0236 cm +1 0 0 1 57.02362 241.0236 cm Q q -1 0 0 1 57.02362 229.0236 cm +1 0 0 1 57.02362 241.0236 cm Q q -1 0 0 1 57.02362 181.0236 cm +1 0 0 1 57.02362 193.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -11156,10 +11156,10 @@ Q Q Q q -1 0 0 1 57.02362 175.0236 cm +1 0 0 1 57.02362 187.0236 cm Q q -1 0 0 1 57.02362 139.0236 cm +1 0 0 1 57.02362 151.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -11181,10 +11181,10 @@ Q Q Q q -1 0 0 1 57.02362 133.0236 cm +1 0 0 1 57.02362 145.0236 cm Q q -1 0 0 1 57.02362 97.02362 cm +1 0 0 1 57.02362 109.0236 cm q 0 0 0 rg BT /F1 10 Tf 12 TL ET @@ -11206,7 +11206,7 @@ Q Q Q q -1 0 0 1 57.02362 79.02362 cm +1 0 0 1 57.02362 91.02362 cm Q endstream @@ -12146,66 +12146,66 @@ xref 0002447433 00000 n 0002457549 00000 n 0002466915 00000 n -0002475491 00000 n -0002486442 00000 n -0002498945 00000 n -0002509558 00000 n -0002518581 00000 n -0002529268 00000 n -0002536885 00000 n -0002546473 00000 n -0002554309 00000 n -0002564586 00000 n -0002574527 00000 n -0002581044 00000 n -0002582879 00000 n -0002596335 00000 n -0002612994 00000 n -0002623502 00000 n -0002630961 00000 n -0002637635 00000 n -0002645697 00000 n -0002653633 00000 n -0002660101 00000 n -0002662257 00000 n -0002663335 00000 n -0002663739 00000 n -0002663774 00000 n -0002663809 00000 n -0002663844 00000 n -0002663879 00000 n -0002663914 00000 n -0002663949 00000 n -0002663984 00000 n -0002664019 00000 n -0002664054 00000 n -0002664090 00000 n -0002664126 00000 n -0002664162 00000 n -0002664198 00000 n -0002664234 00000 n -0002664270 00000 n -0002664306 00000 n -0002664342 00000 n -0002664378 00000 n -0002664414 00000 n -0002664450 00000 n -0002664486 00000 n -0002664522 00000 n -0002664558 00000 n -0002664594 00000 n -0002664630 00000 n -0002664666 00000 n -0002664702 00000 n -0002664738 00000 n -0002664774 00000 n -0002664810 00000 n -0002664846 00000 n -0002664882 00000 n +0002475479 00000 n +0002486430 00000 n +0002498933 00000 n +0002509546 00000 n +0002518569 00000 n +0002529250 00000 n +0002536867 00000 n +0002546455 00000 n +0002554291 00000 n +0002564562 00000 n +0002574503 00000 n +0002581020 00000 n +0002582855 00000 n +0002596311 00000 n +0002612952 00000 n +0002623460 00000 n +0002630919 00000 n +0002637593 00000 n +0002645617 00000 n +0002653553 00000 n +0002660021 00000 n +0002662177 00000 n +0002663255 00000 n +0002663659 00000 n +0002663694 00000 n +0002663729 00000 n +0002663764 00000 n +0002663799 00000 n +0002663834 00000 n +0002663869 00000 n +0002663904 00000 n +0002663939 00000 n +0002663974 00000 n +0002664010 00000 n +0002664046 00000 n +0002664082 00000 n +0002664118 00000 n +0002664154 00000 n +0002664190 00000 n +0002664226 00000 n +0002664262 00000 n +0002664298 00000 n +0002664334 00000 n +0002664370 00000 n +0002664406 00000 n +0002664442 00000 n +0002664478 00000 n +0002664514 00000 n +0002664550 00000 n +0002664586 00000 n +0002664622 00000 n +0002664658 00000 n +0002664694 00000 n +0002664730 00000 n +0002664766 00000 n +0002664802 00000 n trailer << /ID -[<1d446ae1004a02d6f40b0a19c1f8b013><1d446ae1004a02d6f40b0a19c1f8b013>] +[<256838ea1d698f91db2ad0c26a223907><256838ea1d698f91db2ad0c26a223907>] % ReportLab generated PDF document -- digest (opensource) /Info 69 0 R @@ -12213,5 +12213,5 @@ trailer /Size 200 >> startxref -2664918 +2664838 %%EOF diff --git a/whitepaper/uncommonlisp-whitepaper.rst b/whitepaper/lumbda-whitepaper.rst similarity index 98% rename from whitepaper/uncommonlisp-whitepaper.rst rename to whitepaper/lumbda-whitepaper.rst index b2ae75f..4308f63 100644 --- a/whitepaper/uncommonlisp-whitepaper.rst +++ b/whitepaper/lumbda-whitepaper.rst @@ -482,8 +482,8 @@ To measure what a collector would actually cost, we built a second asm binary be .. code-block:: - as --64 --defsym GC_NAIVE=1 uncommonlisp.s # collecting build - as --64 uncommonlisp.s # default, bump-only + as --64 --defsym GC_NAIVE=1 lumbda.s # collecting build + as --64 lumbda.s # default, bump-only Same source, same tests (137/137 pass on both). The GC build adds an 8-byte ``(size << 1 | mark)`` header on every heap block, a stop-the-world mark-sweep triggered by bump overflow, and a free-list allocator that first-fits reclaimed space. @@ -746,7 +746,7 @@ During VM execution, ``portal-checkpoint!`` triggers at ``OP_JUMP`` & ``OP_TAIL_ :: - python3 uncommonlisp.py --portal-resume state.portal + python3 lumbda.py --portal-resume state.portal The computation does not need to restart from the beginning. @@ -954,7 +954,7 @@ The proof has been verified at six distinct levels. Times are best-of-3 on the i 1. **Numerical verification** (``proof/eml_proof.py``): Python script using ``cmath`` at high precision. Verifies every derivation step with tolerance ``1e-10``. Includes brute-force tree search at depth ≤ 4 confirming that eml compositions reach the expected targets. -2. **Self-hosted verification** (``proof/eml_proof.lsp``): The same proof runs in Lumbda's bytecode VM (``python3 uncommonlisp.py --fast proof/eml_proof.lsp``). The language verifies its own mathematical foundations. +2. **Self-hosted verification** (``proof/eml_proof.lsp``): The same proof runs in Lumbda's bytecode VM (``python3 lumbda.py --fast proof/eml_proof.lsp``). The language verifies its own mathematical foundations. 3. **Formal proof** (``proof/lean/EmlProof/Basic.lean``): Lean 4 proof with zero ``sorry``. Five theorems: @@ -1143,9 +1143,9 @@ Sockets share the same port representation as files — in asm the fd is packed :: - python3 uncommonlisp.py --fast examples/http-server.lsp - ./c/uncommonlisp examples/http-server.lsp - ./asm/uncommonlisp < examples/http-server.lsp + python3 lumbda.py --fast examples/http-server.lsp + ./c/lumbda examples/http-server.lsp + ./asm/lumbda < examples/http-server.lsp The companion ``examples/http-client-bench.lsp`` is a 45-line load generator using only the six ``tcp-*`` primitives plus ``current-time-ms``. In-process client eliminates the ~2 ms/request fork overhead that curl-based benchmarks suffer, so real server throughput shows through. **Reproduce:** ``make bench-web`` (source: ``tests/web-benchmark.sh``). @@ -1314,9 +1314,9 @@ The Python implementation had a similar defect: ``_define_record_type`` used ``l **Two more MOAD-0001 defects surfaced during the HTTP server work and were fixed in the same pass:** - ``c/builtins.c``'s ``bi_string_replace`` scanned the source byte-by-byte, calling ``strncmp(src, from, from_len)`` at every position. O(N·k). Replaced with ``strstr`` (libc-tuned, typically Boyer-Moore-Horspool) called in a loop that skips to the next match. O(N + matches·k). -- ``uncommonlisp.py``'s ``_tokenize_lines`` called ``src.count('\\n', 0, m.start())`` per token to compute line numbers. O(N·M). Replaced with a single pass that builds a ``line_starts`` array, then bisects per token. O(M + N log M). +- ``lumbda.py``'s ``_tokenize_lines`` called ``src.count('\\n', 0, m.start())`` per token to compute line numbers. O(N·M). Replaced with a single pass that builds a ``line_starts`` array, then bisects per token. O(M + N log M). -A third correctness fix landed after the portal-over-HTTP demo exposed it: ``uncommonlisp.py``'s ``Env.lookup`` used to short-cut from the local frame directly to the global frame before walking intermediate parents. That was fast but wrong — a let-loop parameter named the same as a global builtin (``count``, a SRFI-1 procedure) got shadowed in reverse, the shortcut returned the global builtin instead of walking up to the loop's parameter frame. Fix: walk ``self → self.p → ... → global`` in order, without any shortcut. The inline cache at ``OP_LOOKUP`` was correspondingly tightened to validate the full chain before firing. 980 tests remained green. +A third correctness fix landed after the portal-over-HTTP demo exposed it: ``lumbda.py``'s ``Env.lookup`` used to short-cut from the local frame directly to the global frame before walking intermediate parents. That was fast but wrong — a let-loop parameter named the same as a global builtin (``count``, a SRFI-1 procedure) got shadowed in reverse, the shortcut returned the global builtin instead of walking up to the loop's parameter frame. Fix: walk ``self → self.p → ... → global`` in order, without any shortcut. The inline cache at ``OP_LOOKUP`` was correspondingly tightened to validate the full chain before firing. 980 tests remained green. Every release audit surfaces more. Writing new code is writing new sediment, unless the audit runs.