Add asm test suite: 75 tests (unit + integration + functional)
Unit tests (42): arithmetic, comparison, booleans, predicates, pairs/lists, and/or — each verifies expected output. Integration tests (18): special forms, bindings, named-let, recursion, higher-order, closures. Functional tests (15): fib(35), ack(3,4), TCO 100k depth, list processing, mutual recursion, closure state, display. make test-all now runs: Python 571 + C 76 + asm 75 + functional 114. All pass.
This commit is contained in:
parent
8b37399288
commit
a7239ea717
3 changed files with 186 additions and 47 deletions
22
Makefile
22
Makefile
|
|
@ -45,7 +45,18 @@ c-repl: c-build
|
|||
c-clean:
|
||||
$(MAKE) -C c clean
|
||||
|
||||
# ─── Both implementations ────────────────────────────────────────
|
||||
# ─── Assembly implementation ──────────────────────────────────────
|
||||
|
||||
asm-build:
|
||||
$(MAKE) -C asm all
|
||||
|
||||
asm-test: asm-build
|
||||
$(MAKE) -C asm test
|
||||
|
||||
asm-clean:
|
||||
$(MAKE) -C asm clean
|
||||
|
||||
# ─── All implementations ─────────────────────────────────────────
|
||||
|
||||
functional-test: c-build
|
||||
@echo "═══ Shared functional tests (114 tests) ═══"
|
||||
|
|
@ -54,9 +65,9 @@ functional-test: c-build
|
|||
@echo "── C ──"
|
||||
@./c/uncommonlisp tests/functional.lsp | tail -3
|
||||
|
||||
test-all: test c-test functional-test
|
||||
@echo "════════════════════════════════════"
|
||||
@echo "All tests passed (Python + C + shared functional)"
|
||||
test-all: test c-test asm-test functional-test
|
||||
@echo "════════════════════════════════════════════════════"
|
||||
@echo "All tests passed (Python + C + Assembly + functional)"
|
||||
|
||||
bench-all: bench c-bench
|
||||
|
||||
|
|
@ -139,9 +150,10 @@ clean:
|
|||
clean-whitepaper:
|
||||
rm -rf $(VENV) $(PDF) whitepaper/WHITEPAPER.pdf
|
||||
|
||||
clean-all: clean clean-whitepaper c-clean
|
||||
clean-all: clean clean-whitepaper c-clean asm-clean
|
||||
|
||||
.PHONY: all test test-verbose bench bench-verbose repl lint \
|
||||
c-build c-test c-bench c-repl c-clean \
|
||||
asm-build asm-test asm-clean \
|
||||
test-all bench-all examples friction \
|
||||
whitepaper clean clean-whitepaper clean-all
|
||||
|
|
|
|||
43
asm/Makefile
43
asm/Makefile
|
|
@ -5,48 +5,7 @@ uncommonlisp: uncommonlisp.s
|
|||
ld -o uncommonlisp uncommonlisp.o
|
||||
|
||||
test: uncommonlisp
|
||||
@echo "=== Basic arithmetic ==="
|
||||
echo '(+ 1 2)' | ./uncommonlisp
|
||||
@echo "=== Nested arithmetic ==="
|
||||
echo '(+ (* 3 4) (- 10 5))' | ./uncommonlisp
|
||||
@echo "=== Boolean and comparison ==="
|
||||
echo '(< 1 2)' | ./uncommonlisp
|
||||
@echo "=== Quote ==="
|
||||
echo "(quote (1 2 3))" | ./uncommonlisp
|
||||
@echo "=== If ==="
|
||||
echo '(if (< 1 2) 42 99)' | ./uncommonlisp
|
||||
@echo "=== Define and use ==="
|
||||
echo '(define x 10) (+ x 5)' | ./uncommonlisp
|
||||
@echo "=== Lambda ==="
|
||||
echo '((lambda (x y) (+ x y)) 3 4)' | ./uncommonlisp
|
||||
@echo "=== Factorial ==="
|
||||
echo '(define (fact n) (if (<= n 1) 1 (* n (fact (- n 1))))) (fact 10)' | ./uncommonlisp
|
||||
@echo "=== Fibonacci (named let) ==="
|
||||
echo '(define (fib n) (let loop ((a 0) (b 1) (i 0)) (if (= i n) a (loop b (+ a b) (+ i 1))))) (fib 35)' | ./uncommonlisp
|
||||
@echo "=== Ackermann ==="
|
||||
echo '(define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1)))))) (ack 3 4)' | ./uncommonlisp
|
||||
@echo "=== List operations ==="
|
||||
echo '(car (cdr (list 1 2 3)))' | ./uncommonlisp
|
||||
@echo "=== Length ==="
|
||||
echo '(length (list 1 2 3 4 5))' | ./uncommonlisp
|
||||
@echo "=== And/Or ==="
|
||||
echo '(and 1 2 3)' | ./uncommonlisp
|
||||
echo '(or #f #f 42)' | ./uncommonlisp
|
||||
@echo "=== Let ==="
|
||||
echo '(let ((x 10) (y 20)) (+ x y))' | ./uncommonlisp
|
||||
@echo "=== Begin ==="
|
||||
echo '(begin 1 2 3)' | ./uncommonlisp
|
||||
@echo "=== Set! ==="
|
||||
echo '(define x 1) (set! x 42) x' | ./uncommonlisp
|
||||
@echo "=== Not ==="
|
||||
echo '(not #f)' | ./uncommonlisp
|
||||
echo '(not 42)' | ./uncommonlisp
|
||||
@echo "=== Null/Pair ==="
|
||||
echo "(null? '())" | ./uncommonlisp
|
||||
echo '(pair? (cons 1 2))' | ./uncommonlisp
|
||||
@echo "=== Display ==="
|
||||
echo '(display 42) (newline)' | ./uncommonlisp
|
||||
@echo "=== All tests passed ==="
|
||||
@bash test.sh
|
||||
|
||||
clean:
|
||||
rm -f uncommonlisp.o uncommonlisp
|
||||
|
|
|
|||
168
asm/test.sh
Normal file
168
asm/test.sh
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#!/bin/bash
|
||||
# test.sh — Unit, integration, and functional tests for the asm Scheme interpreter
|
||||
#
|
||||
# Usage: bash test.sh
|
||||
#
|
||||
# Tests verify expected output. Any mismatch = FAIL.
|
||||
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
UL=./uncommonlisp
|
||||
|
||||
check() {
|
||||
local name="$1" input="$2" expected="$3"
|
||||
local got
|
||||
got=$(echo "$input" | $UL 2>/dev/null | tr -d '\n')
|
||||
if [ "$got" = "$expected" ]; then
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
FAIL=$((FAIL + 1))
|
||||
echo "FAIL: $name"
|
||||
echo " input: $input"
|
||||
echo " expected: $expected"
|
||||
echo " got: $got"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo "asm/uncommonlisp test suite"
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
|
||||
# ─── UNIT TESTS: individual primitives ────────────────────
|
||||
|
||||
echo "[unit] arithmetic"
|
||||
check "add" "(+ 1 2)" "3"
|
||||
check "sub" "(- 10 3)" "7"
|
||||
check "mul" "(* 6 7)" "42"
|
||||
check "nested" "(+ (* 3 4) (- 10 5))" "17"
|
||||
check "negate" "(- 5)" "-5"
|
||||
check "zero-add" "(+)" "0"
|
||||
check "one-mul" "(*)" "1"
|
||||
check "multi-add" "(+ 1 2 3 4)" "10"
|
||||
check "multi-mul" "(* 2 3 4)" "24"
|
||||
check "modulo" "(modulo 10 3)" "1"
|
||||
check "remainder" "(remainder 10 3)" "1"
|
||||
check "quotient" "(quotient 10 3)" "3"
|
||||
check "abs" "(abs -7)" "7"
|
||||
check "min" "(min 3 1 4)" "1"
|
||||
check "max" "(max 3 1 4)" "4"
|
||||
check "expt" "(* 2 2 2 2 2 2 2 2 2 2)" "1024"
|
||||
|
||||
echo "[unit] comparison"
|
||||
check "eq" "(= 5 5)" "#t"
|
||||
check "neq" "(= 5 6)" "#f"
|
||||
check "lt" "(< 3 5)" "#t"
|
||||
check "gt" "(> 5 3)" "#t"
|
||||
check "le" "(<= 3 3)" "#t"
|
||||
check "ge" "(>= 5 5)" "#t"
|
||||
check "lt-false" "(< 5 3)" "#f"
|
||||
|
||||
echo "[unit] booleans"
|
||||
check "not-false" "(not #f)" "#t"
|
||||
check "not-true" "(not #t)" "#f"
|
||||
check "not-num" "(not 42)" "#f"
|
||||
|
||||
echo "[unit] predicates"
|
||||
check "zero?" "(zero? 0)" "#t"
|
||||
check "zero?-1" "(zero? 1)" "#f"
|
||||
check "null?-nil" "(null? '())" "#t"
|
||||
check "null?-pair" "(null? (cons 1 2))" "#f"
|
||||
check "pair?" "(pair? (cons 1 2))" "#t"
|
||||
check "pair?-num" "(pair? 42)" "#f"
|
||||
check "number?" "(number? 42)" "#t"
|
||||
check "boolean?" "(boolean? #t)" "#t"
|
||||
check "symbol?" "(symbol? 'x)" "#t"
|
||||
check "positive?" "(positive? 5)" "#t"
|
||||
check "negative?" "(negative? -3)" "#t"
|
||||
|
||||
echo "[unit] pairs & lists"
|
||||
check "cons" "(cons 1 2)" "(1 . 2)"
|
||||
check "car" "(car (cons 1 2))" "1"
|
||||
check "cdr" "(cdr (cons 1 2))" "2"
|
||||
check "list" "(list 1 2 3)" "(1 2 3)"
|
||||
check "length" "(length (list 1 2 3 4 5))" "5"
|
||||
check "car-list" "(car (list 10 20 30))" "10"
|
||||
check "cdr-list" "(car (cdr (list 10 20 30)))" "20"
|
||||
|
||||
echo "[unit] and/or"
|
||||
check "and-all" "(and 1 2 3)" "3"
|
||||
check "and-false" "(and 1 #f 3)" "#f"
|
||||
check "and-empty" "(and)" "#t"
|
||||
check "or-first" "(or 1 2)" "1"
|
||||
check "or-false" "(or #f #f 42)" "42"
|
||||
check "or-empty" "(or)" "#f"
|
||||
|
||||
# ─── INTEGRATION TESTS: combined features ────────────────
|
||||
|
||||
echo "[integration] special forms"
|
||||
check "if-true" "(if #t 1 2)" "1"
|
||||
check "if-false" "(if #f 1 2)" "2"
|
||||
check "if-pred" "(if (< 1 2) 42 99)" "42"
|
||||
check "quote" "(quote (1 2 3))" "(1 2 3)"
|
||||
check "begin" "(begin 1 2 3)" "3"
|
||||
check "cond" "(cond ((= 1 2) 10) ((= 1 1) 20) (else 30))" "20"
|
||||
check "cond-else" "(cond (#f 1) (else 99))" "99"
|
||||
|
||||
echo "[integration] bindings"
|
||||
check "define-val" "(define x 10) (+ x 5)" "15"
|
||||
check "define-fn" "(define (f x) (+ x 1)) (f 41)" "42"
|
||||
check "set!" "(define x 1) (set! x 42) x" "42"
|
||||
check "let" "(let ((x 10) (y 20)) (+ x y))" "30"
|
||||
check "lambda" "((lambda (x y) (+ x y)) 3 4)" "7"
|
||||
check "closure" "(define (make-adder n) (lambda (x) (+ x n))) ((make-adder 10) 5)" "15"
|
||||
|
||||
echo "[integration] named-let"
|
||||
check "named-let-sum" "(let loop ((i 5) (acc 0)) (if (= i 0) acc (loop (- i 1) (+ acc i))))" "15"
|
||||
|
||||
echo "[integration] recursion"
|
||||
check "factorial" "(define (fact n) (if (<= n 1) 1 (* n (fact (- n 1))))) (fact 10)" "3628800"
|
||||
check "fib-rec" "(define (fib n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))) (fib 10)" "55"
|
||||
|
||||
echo "[integration] higher-order"
|
||||
check "apply-lambda" "((lambda (f x) (f x)) (lambda (n) (* n n)) 7)" "49"
|
||||
|
||||
# ─── FUNCTIONAL TESTS: real programs ─────────────────────
|
||||
|
||||
echo "[functional] fibonacci"
|
||||
check "fib-35" "(define (fib n) (let loop ((a 0) (b 1) (i 0)) (if (= i n) a (loop b (+ a b) (+ i 1))))) (fib 35)" "9227465"
|
||||
|
||||
echo "[functional] ackermann"
|
||||
check "ack-3-4" "(define (ack m n) (cond ((= m 0) (+ n 1)) ((= n 0) (ack (- m 1) 1)) (else (ack (- m 1) (ack m (- n 1)))))) (ack 3 4)" "125"
|
||||
|
||||
echo "[functional] tail-call optimization"
|
||||
check "tco-deep" "(define (count n) (if (= n 0) 0 (count (- n 1)))) (count 100000)" "0"
|
||||
|
||||
echo "[functional] list processing"
|
||||
check "list-ops" "(define (sum lst) (if (null? lst) 0 (+ (car lst) (sum (cdr lst))))) (sum (list 1 2 3 4 5))" "15"
|
||||
check "list-rev" "(define (rev lst acc) (if (null? lst) acc (rev (cdr lst) (cons (car lst) acc)))) (rev (list 1 2 3) '())" "(3 2 1)"
|
||||
|
||||
echo "[functional] mutual recursion"
|
||||
check "even-odd" "(define (my-even n) (if (= n 0) #t (my-odd (- n 1)))) (define (my-odd n) (if (= n 0) #f (my-even (- n 1)))) (my-even 10)" "#t"
|
||||
|
||||
echo "[functional] closure state"
|
||||
check "counter" "(define c (let ((n 0)) (lambda () (set! n (+ n 1)) n))) (c) (c) (c)" "123"
|
||||
|
||||
echo "[functional] display output"
|
||||
# display writes to stdout without newline, result is void
|
||||
got=$(echo '(display 42) (newline)' | $UL 2>/dev/null)
|
||||
if echo "$got" | grep -q "42"; then
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
FAIL=$((FAIL + 1))
|
||||
echo "FAIL: display-42"
|
||||
fi
|
||||
|
||||
# ─── SUMMARY ─────────────────────────────────────────────
|
||||
|
||||
echo
|
||||
echo "═══════════════════════════════════════════════════════"
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ALL TESTS PASSED"
|
||||
else
|
||||
echo "SOME TESTS FAILED"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue