Completes the on-disk side of the uncommonlisp -> lumbda rename:
Filesystem: /home/fox/git/uncommonlisp -> /home/fox/git/lumbda
with a back-compat symlink
/home/fox/git/uncommonlisp -> lumbda
so any stale path reference (agent memory files,
shell history, other sessions) still resolves.
tests.py: cwd='/home/fox/git/uncommonlisp' -> '/home/fox/git/lumbda'
(the only hardcoded absolute path we left behind in
the previous rename commit, because the directory
itself hadn't moved yet).
Remote URL (git@git.unturf.com:engineering/unturf/uncommonlisp.git)
still points at the old name and needs to be flipped AFTER fox
renames the gitlab project — probe confirms the new URL currently
404s, so the flip waits for the gitlab rename to land.
Verified 571 Python tests pass under the new cwd; symlink lets
`cd /home/fox/git/uncommonlisp` still work for anything cached.
Historical internal name "uncommonlisp" retired in favor of the
public name "lumbda" ahead of lumbda.com going live. Scope of
this commit:
Source files renamed:
uncommonlisp.py -> lumbda.py
asm/uncommonlisp.s -> asm/lumbda.s
c/uncommonlisp.h -> c/lumbda.h
whitepaper/uncommonlisp-whitepaper -> whitepaper/lumbda-whitepaper (.rst + .pdf)
Binaries renamed (tracked ones; c/ was always gitignored):
asm/uncommonlisp, asm/uncommonlisp-gc, asm/uncommonlisp.o,
asm/uncommonlisp-gc.o -> asm/lumbda(-gc)(.o)
c/.gitignore -> ignores lumbda
Internal string updates (sed pass ordered longest-first):
asm/uncommonlisp -> asm/lumbda
c/uncommonlisp -> c/lumbda
uncommonlisp.py -> lumbda.py
UNCOMMONLISP_BIN -> LUMBDA_BIN (asm/test.sh env var)
"uncommonlisp> " -> "lumbda> " (asm REPL prompt baked into binary)
UNCOMMONLISP -> LUMBDA (macros, comments)
uncommonlisp -> lumbda (prose)
Binary portal magic updated:
"ULPORTAL" -> "LUMBDAB1" # "Lumbda Binary v1"
Old portal files are not backward-compatible — this is a deliberate
break since it's the rename moment. S-expression portals already
carry their own ";; lumbda-portal v1" header and remain cleanly
versioned.
WHITEPAPER.pdf / WHITEPAPER.rst symlinks repointed to the renamed
files. Makefile's whitepaper target targets lumbda-whitepaper.pdf.
Not changed (intentional, separate phases):
- Filesystem directory /home/fox/git/uncommonlisp itself
(fox renames locally and the gitlab repo URL in a follow-up)
- tests.py hardcoded cwd=/home/fox/git/uncommonlisp
(matches the current on-disk location; will flip when the
directory rename ships)
- Git history (immutable; old commits still say uncommonlisp,
which is correct — that's what they were)
Verified:
137 asm no-GC + 137 asm GC + 571 Python + 83 C + 189 shared
functional tests all pass under the new names.
bench-gc-http (2000 req): all 4 cells behave as expected
(cells 1/2 flat, 3 leaks, 4 bounded at 1 chunk).
Python REPL, C REPL, asm REPL all start cleanly.
Portal saves the full machine state — env chain, compiled procedures,
continuations, frame stack — to a JSON file. Another interpreter
instance loads it and resumes execution from the exact instruction.
Demo: start a primality test on machine A, checkpoint mid-computation,
resume on machine B. 1000000007 prime check: machine B picks up from
i=30000 and finishes in 6% of the original time.
Implementation:
- PortalSerializer: graph-aware with identity tracking for shared env
references. Handles cycles (closures referencing their own env).
- portal-checkpoint!: triggers mid-execution save from within VM loop.
Hooks into TAIL_CALL (loop back-edge) for compiled code.
- --portal-resume CLI flag: load .portal file and resume continuation.
- portal-save / portal-resume Scheme builtins.
571 tests green (7 new portal tests: unit + integration + functional).
Source maps: tokenizer tracks line numbers, parser attaches to Pair nodes,
compiler records in CodeObj.source_map, errors display source line.
Multi-shot continuations: FullCont snapshots env at capture time via
deep copy. Each invocation gets a fresh env copy. Generators and
multi-shot patterns both work correctly.
Inline caching: VM caches global env lookups per instruction site.
Local shadow check (arg not in env.b) prevents stale cache hits.
Compiler tracks compile-time scopes to suppress specialization/folding
when builtins are locally shadowed.
Bytecode serialization: JSON-based .lspc format. save-compiled/load-compiled
builtins. --compile CLI flag precompiles .lsp files. Round-trip tested for
all operand types including nested closures and quoted data.
564 tests green (35 new: unit + integration + functional for each feature).
- Full call/cc: upward continuations via explicit VM frame stack + trampoline.
Generators now work: (make-gen (lambda (yield) (yield 1) (yield 2)))
- Explicit frame stack: compiled→compiled CALL no longer grows Python stack.
Non-tail calls use frames list instead of recursive vm_exec.
- Env global shortcut: lookup checks local then global before walking chain,
O(1) for builtins instead of O(depth).
- Constant folding: arithmetic on literals folded at compile time.
- Auto-compile covers inline lambdas (not just define).
- 522 tests green, 7-19x speedup over interpreter.
- auto-compile! parameter: compile defines on the fly for zero-effort speedup
- VM optimization: local aliases, inlined truthiness checks (~15% faster)
- disassemble builtin: human-readable bytecode listing
- call/cc compiled natively in VM (escape-only, no longer falls back to eval)
- Makefile: add lint, bench-verbose, clean targets
- 518 tests green
Stack-based VM with 17 opcodes, TCO via in-place frame reset,
compile-time macro expansion, and seamless interop between
compiled and interpreted code. 514 tests green.
Core additions:
- StringInputPort / StringOutputPort — open-input-string, open-output-string,
get-output-string, read/read-char/peek-char/read-line on ports
- R7RS ErrorObject class — error-object?, error-object-message,
error-object-irritants; guard and with-exception-handler now receive
ErrorObject instances instead of raw strings
- Exact rational arithmetic via Fraction — (/ 1 3) => 1/3, literal 1/3
syntax, numerator/denominator, exact/inexact conversions
- Module system — (module name (export ...) body...) and (import name) /
(import (name sym ...)) for selective import
- define-record-type now a Python special form supporting (inherit parent)
for single-inheritance with subtype predicates
- Pretty-printer — pp/pretty-print with configurable line width
Correctness:
- R7RS letrec* body semantics for internal defines — names pre-declared
before any initializer runs, enabling mutual recursion in let bodies
- string->number detects #x/#b/#o/#d and 0x/0b/0o prefixes
- show() guarantees decimal point in float output
- number->string rounds through show() for consistent float representation
Performance:
- _body_env fast path: skip scan when first body form is not define/begin
- Proc.has_defs flag: skip _body_env entirely for procs without internal defines
- Single-form body optimization: skip begin wrapper, set expr directly
Tests: 396 → 455 (+59 new tests covering all new features)