Demo program that lives entirely on lib/* and libwwrt.a — no @symbol
FFI of its own. The interpreter sits in lispcore.ww (exports for the
test driver); lisp.ww is a 3-line entry that calls lispcore.repl().
Language surface: integers, floats, symbols, strings, lists, lambdas
with closures, define / set! / if / quote / let / begin, recursion
(fact / fib / ackermann / gcd), map / filter / reduce as user code.
REPL is line-buffered: each read tries to parse one top-level form,
asks for more on "unterminated list", evaluates and prints, then
shifts consumed bytes off the front of the buffer. Lookahead-aware —
the parser primes one extra token so we shift to L.curstart, not
L.pos, otherwise the first byte of the next form gets eaten.
lisp_test.ww exec'd as a regular binary (ww test drops -I in single-
file mode); 66 probes cover arithmetic, lists, closures, recursion,
errors. test_*.lisp drive the live REPL through `make demo`.
The wwstage cgen still mis-lowers a handful of patterns at this
shape of program — top-level array indexing, global-ptr deref,
two-level field stores, f64 routing through *T, alloc(structlit{})
for f64/str fields, (slice | E) returns, xs[i].kind chains, f64
compound assigns. Each workaround is annotated at its use site;
the full taxonomy is in examples/lisp/CLAUDE.md.
64 lines
1.7 KiB
Common Lisp
64 lines
1.7 KiB
Common Lisp
; test_lambda.lisp — lambdas, define, recursion, higher-order.
|
|
; Run: cat test_lambda.lisp | ./lisp
|
|
|
|
; one-liner lambda
|
|
((lambda (n) (* n n)) 7) ; => 49
|
|
|
|
; named function
|
|
(define square (lambda (n) (* n n)))
|
|
(square 9) ; => 81
|
|
(square 12) ; => 144
|
|
|
|
; classic recursion
|
|
(define fact (lambda (n)
|
|
(if (<= n 1) 1
|
|
(* n (fact (- n 1))))))
|
|
(fact 5) ; => 120
|
|
(fact 10) ; => 3628800
|
|
(fact 12) ; => 479001600
|
|
|
|
(define fib (lambda (n)
|
|
(if (< n 2) n
|
|
(+ (fib (- n 1)) (fib (- n 2))))))
|
|
(fib 10) ; => 55
|
|
(fib 15) ; => 610
|
|
(fib 20) ; => 6765
|
|
|
|
(define gcd (lambda (a b)
|
|
(if (= b 0) a
|
|
(gcd b (mod a b)))))
|
|
(gcd 60 48) ; => 12
|
|
(gcd 1024 768) ; => 256
|
|
|
|
; higher-order: map / filter / reduce
|
|
(define map (lambda (f l)
|
|
(if (null? l) '()
|
|
(cons (f (car l)) (map f (cdr l))))))
|
|
(define filter (lambda (p l)
|
|
(if (null? l) '()
|
|
(if (p (car l))
|
|
(cons (car l) (filter p (cdr l)))
|
|
(filter p (cdr l))))))
|
|
(define reduce (lambda (f acc l)
|
|
(if (null? l) acc
|
|
(reduce f (f acc (car l)) (cdr l)))))
|
|
|
|
(define inc (lambda (n) (+ n 1)))
|
|
(define even? (lambda (n) (= (mod n 2) 0)))
|
|
|
|
(map inc '(1 2 3 4 5)) ; => (2 3 4 5 6)
|
|
(filter even? '(1 2 3 4 5 6)) ; => (2 4 6)
|
|
(reduce + 0 '(1 2 3 4 5 6 7 8 9 10)) ; => 55
|
|
|
|
; closure over the captured env
|
|
(define adder (lambda (k) (lambda (x) (+ x k))))
|
|
(define add5 (adder 5))
|
|
(add5 10) ; => 15
|
|
(add5 100) ; => 105
|
|
|
|
; mutual-like with set!
|
|
(define c 0)
|
|
(set! c 41)
|
|
(set! c (+ c 1))
|
|
c ; => 42
|