lumbda/c
russell@unturf.com 06b93c588a portal over HTTP: 9/9 cross-runtime, plus eval-to-global-env fix
Closes the last loop promised in the whitepaper's Future Work: a
node serves its state as an S-expression portal over HTTP, another
node pulls it down with tcp-connect + tcp-recv and materializes the
bindings locally via (eval (read-from-string line)).

examples/portal-http-server.lsp (90 lines):
- Holds some state (counter, my-int, my-list, my-fib, my-str)
- GET /portal → S-expression body: a sequence of (define ...) forms
- GET / → HTML index
- Uses heap-snapshot / heap-restore for O(1) memory on asm

examples/portal-http-client.lsp (90 lines):
- tcp-connect, send HTTP/1.0 GET, receive full response
- Strip headers (walk to first \r\n\r\n)
- Split body by \n, eval each non-empty, non-comment line
- The remote bindings are now live locally

3×3 server/client matrix: all 9 combinations green. Every runtime
hosts, every runtime consumes. The wire format is Scheme source;
no schema, no JSON, no Protobuf.

Prerequisite fix: `eval` semantics aligned across all three impls.

Python and C's `eval` special form previously evaluated its result
in the CALLER's env, so a nested (eval (read-from-string
"(define x 42)")) would install x in the local function scope —
invisible to later top-level code. asm's bi_eval always used the
global env (r14). With this commit, all three impls evaluate the
eval'd result in the global env, matching asm's existing behavior.

Python: uncommonlisp.py leval eval-handler now does `env = env.g`
before continuing the trampoline.
C: c/eval.c SYM_EVAL branch now does `env = env->global`.
asm: no change (already correct).

One pre-existing Python defect surfaced by the client:
`count` is a SRFI-1-style builtin (`d(S('count'), ...)`), so a
local let-loop variable named `count` collides with it in the
inline-cache lookup path and OP_LOOK_ADD1 fires on the builtin
instead of the local. Worked around by renaming the loop
accumulator to `cnt`. Underlying Env.lookup shortcut-to-global
issue is out of scope for this commit.

Regression: 975 tests still green.
2026-04-17 13:41:48 -04:00
..
.gitignore Add C implementation: 7,429 lines, 58 tests, identical output 2026-04-14 14:55:17 -04:00
bench.c JIT: add named-let loops, let/let*, and/or, car/cdr/cons, 18 new tests 2026-04-14 20:50:24 -04:00
builtins.c S-expressions over sockets — RPC + remote REPL in portable Scheme 2026-04-17 09:00:04 -04:00
eval.c portal over HTTP: 9/9 cross-runtime, plus eval-to-global-env fix 2026-04-17 13:41:48 -04:00
jit.c JIT: add named-let loops, let/let*, and/or, car/cdr/cons, 18 new tests 2026-04-14 20:50:24 -04:00
jit.h Add GPU architecture notes and JIT header 2026-04-14 19:43:16 -04:00
main.c x86_64 JIT: 12-21x faster than CPython, 230x faster than interpreter 2026-04-14 19:58:26 -04:00
Makefile C: add full continuations, portal save/resume, 7 new tests 2026-04-15 20:07:09 -04:00
portal.c C: add full continuations, portal save/resume, 7 new tests 2026-04-15 20:07:09 -04:00
printer.c Add C implementation: 7,429 lines, 58 tests, identical output 2026-04-14 14:55:17 -04:00
reader.c Add C implementation: 7,429 lines, 58 tests, identical output 2026-04-14 14:55:17 -04:00
test.c C: add full continuations, portal save/resume, 7 new tests 2026-04-15 20:07:09 -04:00
types.c C: add deep_copy_env, VM frame stack for continuations 2026-04-15 19:57:17 -04:00
uncommonlisp.h C: add full continuations, portal save/resume, 7 new tests 2026-04-15 20:07:09 -04:00
vm.c C: add full continuations, portal save/resume, 7 new tests 2026-04-15 20:07:09 -04:00