Commit graph

26 commits

Author SHA1 Message Date
d373f80aaf JIT: add named-let loops, let/let*, and/or, car/cdr/cons, 18 new tests
JIT now covers: if, cond, and, or, let, let*, named-let (native loops),
car, cdr, cons, null?, pair?, arithmetic, comparisons, recursion, TCO.
1309 lines of x86_64 codegen. 76 C tests + 114 functional tests pass.

Named-let loops compile to native jmp (zero call overhead):
  sum-to(50k): 0.33ms JIT vs 7.8ms CPython (24x faster than Python)
  ack(3,4):    0.20ms JIT vs 2.0ms CPython (10x faster)
  fib-rec(20): 0.42ms JIT vs 2.7ms CPython (6x faster)

EML benchmark added: integer-domain exp/ln composition under JIT.
2026-04-14 20:50:24 -04:00
c80eabac47 x86_64 JIT: 12-21x faster than CPython, 230x faster than interpreter
Real native machine code via mmap(PROT_EXEC). No exec(). No strings.
Raw x86_64 bytes: mov, add, sub, imul, cmp, je, jne, call, ret, jmp.

ack(3,4):    0.12ms JIT vs 1.5ms CPython vs 28ms interpreter
fib-rec(20): 0.16ms JIT vs 3.4ms CPython vs 40ms interpreter

Added cond support to JIT (cascaded comparisons → conditional jumps).
Fixed JIT cache: sentinel value prevents retry on unjittable functions.
System V AMD64 ABI: args in rdi/rsi/rdx, callee-saved r12-r15.
Tail calls use jmp (true TCO at machine code level).

691 lines of jit.c. 114 functional tests pass. All C tests pass.
2026-04-14 19:58:26 -04:00
46812e1885 Add GPU architecture notes and JIT header
docs/gpu-architecture.md — roadmap for GPU lambda execution:
  Phase 1: map/reduce (CUDA thread per element)
  Phase 2: trampolining (recursive lambdas without stack)
  Phase 3: interaction combinators (Bend/HVM approach, 74K MIPS)

c/jit.h — x86_64 JIT header: JitBlock, JitFunc typedef,
  jit_compile/jit_free API. Uses mmap for executable memory.
  System V AMD64 ABI calling convention.

jit.c implementation in progress (x86 instruction encoding).
2026-04-14 19:43:16 -04:00
d5e05bf538 Fix JIT name sanitization: fib-rec → fib_rec in generated Python
JIT now matches CPython speed:
  fib-rec(20): JIT 14ms vs VM 1245ms (87x faster)
  ack(3,4):    JIT 13ms vs VM 1053ms (82x faster)
Both at parity with hand-written CPython.
2026-04-14 18:54:20 -04:00
916f287e8b Add JIT: transpile Scheme AST to Python source, exec() it
JIT ack(3,4): 3ms. VM ack(3,4): 2680ms. 870x speedup.
JIT runs at CPython speed — eliminates the entire dispatch loop.

Transpiles: if, cond, and, or, arithmetic, comparison, car/cdr/cons,
predicates, recursive function calls. Generates Python ternary
expressions from Scheme conditionals.

(jit proc) — JIT a procedure, returns native callable
(jit-source proc) — show generated Python source

Named-let loops bail to VM (need statement-level code).
571 tests green.
2026-04-14 18:50:35 -04:00
db2cd77c62 Add shared functional test suite: 114 tests, both implementations pass
tests/functional.lsp — single .lsp file, runs identically in Python and C.
Covers: arithmetic, comparison, booleans, pairs, lists, strings, characters,
vectors, hash tables, control flow, let/lambda/closures, do loops, define,
recursion, TCO (100k depth), quasiquote, macros, type predicates, call/cc,
error handling, mergesort, higher-order programs.

Fixed C call/cc: proper escape continuations via setjmp/longjmp.

make test-all runs: Python unit (571) + C unit (58) + shared functional (114).
2026-04-14 15:21:17 -04:00
73440106c3 Add friction.sh benchmark: C is 3-6x faster than Python impl
fib(35):     C 0.1ms vs Python 0.6ms (6x)
fib-rec(20): C 44ms vs Python 283ms (6.4x)
ack(3,4):    C 31ms vs Python 93ms (3x)
sum-to(50k): C 129ms vs Python 515ms (4x)

Both still ~20-30x slower than native CPython (interpreter overhead).
SBCL would be within 2-5x of C with native compilation.
2026-04-14 15:11:43 -04:00
fc9eb5350c Add C implementation: 7,429 lines, 58 tests, identical output
Complete C port of the Scheme interpreter. Same .lsp files run in
both Python and C with identical output.

Architecture:
- NaN-boxed 64-bit values (zero-alloc numbers)
- Hash-map environments with parent chain + global shortcut
- Interned symbols
- TCO via explicit loop (eval) and TAIL_CALL/SELF_TAIL_CALL (VM)
- Bytecode compiler with all opcodes including superinstructions
- 58 unit + integration tests

Makefile targets:
  make test-all    run Python (571) + C (58) tests
  make examples    run examples in both, compare output
  make friction    benchmark same .lsp in Python vs C
  make c-build     build C interpreter
  make c-test      run C tests
  make c-repl      C REPL
2026-04-14 14:55:17 -04:00
b31e03216e Add OP_SELF_TAIL_CALL + cache len(instrs): 37-50% faster loops
- OP_SELF_TAIL_CALL: named-let loops reuse env instead of allocating
  new child env each iteration. Eliminates 50,000 dict allocations
  per sum-to(50000).
- Cache n_instrs = len(instrs): avoid per-dispatch len() call.
  Updated in all code-switching paths (CALL, TAIL_CALL, RETURN,
  CALL_CC, continuation resume).
- Combined with LOOK_ADD1/LOOK_SUB1 from previous commit:
  sum-to: 99x → 50x, ackermann: 79x → 50x, fib-rec: 85x → 63x.
- Serialization updated for new opcode operand format.
- 571 tests green.
2026-04-14 14:05:25 -04:00
e700273136 Add superinstructions LOOK+1, LOOK-1 for 25% faster loops
Fused opcodes: LOOK_ADD1 (lookup + increment) and LOOK_SUB1
(lookup + decrement) emitted directly by compiler for (+ sym 1)
and (- sym 1) patterns. Eliminates one dispatch per loop iteration.

sum-to(50000) ratio improved from 59x to 45x vs Python.
ackermann(3,4) steady at 83x. 571 tests green.

Also defines LOOK_LOOK, CONST_EQ_JF, LOOK_CONST_CALL2
superinstruction opcodes (VM handlers ready, compiler emission
for remaining patterns deferred to next pass).
2026-04-14 13:53:08 -04:00
b81c8923c0 Add friction benchmark to whitepaper: MOAD-0001 at the proof layer
Formal proof (Lean, 1.5s) is 40x faster than brute-force search
(uncommonlisp, 59s) with mathematical certainty vs floating-point
tolerance. This is O(N²) search friction where O(1) algebraic
reasoning suffices — the sedimentary defect in proof methodology.

Proof assistants are the hash set to numerical analysis's nested loop.
2026-04-14 13:34:28 -04:00
4d8cd9f1f8 Add whitepaper: Feedback Is All You Need
Permacomputer whitepaper covering uncommonlisp architecture,
bytecode VM, continuations, portal, EML universality proof,
and benchmarks. AGPL-3.0-only. Builds via make whitepaper
using a local venv (no sudo).
2026-04-14 13:32:42 -04:00
b3ab4bb19a Add proof friction benchmark, update README
Benchmark: Python 0.04s, uncommonlisp 59s, Lean 1.5s — for the same claim.
The formal proof is 40x faster than brute-force search with mathematical
certainty instead of floating-point tolerance.

This is MOAD-0001 at the proof layer: O(N²) search friction where
O(1) algebraic reasoning suffices. Proof assistants are the hash set
to numerical analysis's nested loop.
2026-04-14 13:31:05 -04:00
b5e24e98b1 Add formal Lean 4 proof of EML universality (no sorry)
Lean's type checker verifies all 5 theorems:
  1. exp(x) = eml(x, 1)
  2. e      = eml(1, 1)
  3. ln(x)  = eml(1, eml(eml(1,x), 1))
  4. 0      = eml(1, eml(eml(1,1), 1))
  5. a - b  = eml(ln(a), exp(b))

Zero sorry. Machine-verified. This is a proof, not numerical analysis.
2026-04-13 20:23:30 -04:00
1a94fc0720 Add EML universality proof — verify arXiv:2603.21852v2
Proof that eml(x,y) = exp(x) - ln(y) with constant 1 generates all
elementary functions. Both Python and uncommonlisp implementations.

Chain: e → exp → ln → 0 → subtraction → negatives → complex plane
(via ln(negative) = ln(|neg|) + iπ) → π, i, sin, cos, all arithmetic.

Python: 17 checks, 0.03s. uncommonlisp: 14 checks, 111s.
All checks pass at 1e-10 tolerance.
2026-04-13 19:43:18 -04:00
6b832d5154 Add portal: serialize and resume VM state across machines
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).
2026-04-13 19:00:11 -04:00
74c23cc677 Add source maps, multi-shot continuations, inline caching, bytecode serialization
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).
2026-04-13 17:57:29 -04:00
1326e8a106 Add peephole optimizer, --help, examples, README update
- Peephole optimizer: eliminates VOID+POP pairs, JUMP-to-next-instruction.
  Adjusts jump targets after dead code removal.
- --help/-h and --version/-v flags.
- 4 example programs: fibonacci, generator, mergesort, objects.
- README rewritten: documents bytecode compiler, --fast flag, all features.
- 529 tests green.
2026-04-13 16:56:21 -04:00
f89d3bce6f Add specialized opcodes, mutable strings, --fast flag
- 20 specialized opcodes: ADD, SUB, MUL, NEG, ADD1, SUB1, NUM_EQ, LT, GT,
  LE, GE, CAR, CDR, CONS, NULL?, PAIR?, NOT, ZERO?, VEC_REF, VEC_SET.
  Compiler pattern-matches (+ x 1) → ADD1, (- x 1) → SUB1.
- MutableString class: string-set!, string-fill!, string-copy! now work.
  make-string and string-copy return mutable strings.
- --fast / -f flag: auto-compile mode from command line.
- 529 tests green.
2026-04-13 16:19:27 -04:00
e091accd56 Add full continuations, explicit frame stack, env shortcut, constant folding
- 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.
2026-04-13 15:14:55 -04:00
f584ad76f2 Add auto-compile, VM optimization, disassemble, call/cc compilation
- 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
2026-04-13 14:49:32 -04:00
a7ca8e9f89 Add bytecode compiler and stack-based VM with 3-25x speedup
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.
2026-04-13 14:39:15 -04:00
52d14a2f59 Add parameterize fix, let-values, case=>, arithmetic, FS/system builtins, tracing, SRFI-64
Correctness:
- Fix parameterize: was restoring current value instead of saved old value
- Add let-values and let*-values special forms (R7RS multi-value binding)
- Update case macro to handle (datum... => proc) clauses

Numeric tower:
- truncate-quotient, truncate-remainder, floor-quotient, floor-remainder
- square, exact-integer?

Vectors:
- vector-copy now accepts optional start/end bounds
- vector-copy! for destination-vector mutation

File system and system interface:
- file-exists?, delete-file, rename-file, current-directory,
  set-current-directory!, directory-files, make-directory,
  file-size, file-directory?, file-regular?
- command-line, get-environment-variable, current-time,
  current-jiffy, jiffies-per-second, flush-output-port

Debuggability:
- Call stack tracing: _call_stack captured in LispErr.call_stack
  _call() pushes/pops frames; REPL prints last 5 frames on error
- trace/untrace macros + make-traced/untrace-proc builtins
  (set! f (make-traced f 'f)) wraps f to print args and return values

stdlib.lsp:
- SRFI-64 lightweight test framework: test-begin, test-end,
  test-assert, test-equal, test-error macros

Tests: 455 → 491 (+36 new tests)
2026-04-13 13:32:11 -04:00
66977049f1 Add string ports, error objects, rationals, modules, record inheritance, pretty-print
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)
2026-04-13 12:27:06 -04:00
d0247b2729 Add syntax-rules, SRFI-1, stdlib, benchmarks, README
- syntax-rules: full ellipsis support with hygienic bindings (_EllBind)
- define-syntax / let-syntax / letrec-syntax wired up
- cond => arrow form is now TCO (Proc path loops, builtin returns)
- SRFI-1: take-right, drop-right, last, first-fifth, concatenate,
  list-tabulate, unfold, reduce-right, lset-union/intersection/difference,
  proper-list?, dotted-list?, alist-cons, alist-copy, delete, delete-duplicates
- Fix _Nil/_Void/_EOF singletons (is None check vs __bool__)
- Fix flat-map: pass Pair results to _append, not Python lists
- Fix number->string duplicate definition
- stdlib.lsp: 60+ utility functions (string/list/numeric/hash/tree/OOP/coroutines)
- bench.py: 11 benchmarks vs CPython (all correct, ratios 15–1800x)
- README.md: full feature list, examples, usage
- Makefile: add bench target
2026-04-13 11:05:37 -04:00
f72190d2dc Initial implementation of uncommonlisp
Single-file Scheme-like Lisp interpreter in Python with:
- TCO via explicit while loop (no Python stack overflow at any depth)
- syntax-rules with ellipsis for hygienic macros
- define-macro for procedural macros
- Full numeric tower, strings, chars, vectors, hash tables
- SRFI-1 list library
- call/cc (escape continuations), values, dynamic-wind, guard
- Python interop (py-eval, py-import, py-call, py-attr)
- 396 passing unit/integration/functional tests
- stdlib.lsp with 60+ utility functions
- Benchmark suite vs CPython baseline
2026-04-13 11:01:04 -04:00