# ═══════════════════════════════════════════════════════════════════
# uncommonlisp — Python + C + Assembly implementations
# ═══════════════════════════════════════════════════════════════════
#
# Implementations:
#   Python    uncommonlisp.py         bytecode VM, full continuations, portal
#   C         c/uncommonlisp          tree-walker + bytecode VM + x86_64 JIT
#   Assembly  asm/uncommonlisp        pure x86_64, no libc, 13KB binary
#
# Test suites:
#   make test           Python unit/integration (571 tests)
#   make c-test         C unit/integration + JIT (76 tests) + functional (114)
#   make asm-test       Assembly unit/integration/functional (75 tests)
#   make functional-test  Shared .lsp suite in Python + C (114 each)
#   make test-all       Everything (836 total)
#
# Other:
#   make bench-all      Benchmarks for Python + C
#   make friction       Head-to-head timing: Python vs C vs CPython
#   make examples       Run examples in Python + C, compare output
#   make docs           Generate architecture diagrams
#   make whitepaper     Build PDF whitepaper
#   make clean-all      Clean everything

all: test

# ─── Python implementation ────────────────────────────────────────

test:
	python3 tests.py

test-verbose:
	python3 tests.py -v

bench:
	python3 bench.py

bench-verbose:
	python3 bench.py -v

repl:
	python3 uncommonlisp.py

lint:
	python3 -m py_compile uncommonlisp.py
	python3 -m py_compile tests.py
	python3 -m py_compile bench.py

# ─── C implementation ─────────────────────────────────────────────

c-build:
	$(MAKE) -C c all

c-test: c-build
	$(MAKE) -C c test
	@echo "── C functional tests (shared .lsp suite) ──"
	./c/uncommonlisp tests/functional.lsp

c-bench: c-build
	$(MAKE) -C c bench

c-repl: c-build
	./c/uncommonlisp

c-clean:
	$(MAKE) -C c clean

# ─── Assembly implementation ──────────────────────────────────────

asm-build:
	$(MAKE) -C asm all

asm-test: asm-build
	$(MAKE) -C asm test

asm-repl: asm-build
	./asm/uncommonlisp

asm-clean:
	$(MAKE) -C asm clean

# ─── All implementations ─────────────────────────────────────────

functional-test: c-build
	@echo "═══ Shared functional tests (114 tests) ═══"
	@echo "── Python ──"
	@python3 uncommonlisp.py --fast tests/functional.lsp | tail -3
	@echo "── C ──"
	@./c/uncommonlisp tests/functional.lsp | tail -3

test-all: test c-test asm-test functional-test
	@echo "════════════════════════════════════════════════════"
	@echo "All tests passed (Python + C + Assembly + functional)"

bench-all: bench c-bench

# ─── Examples ─────────────────────────────────────────────────────

examples: c-build
	@echo "═══ fibonacci.lsp ═══"
	@echo "--- Python ---" && python3 uncommonlisp.py --fast examples/fibonacci.lsp
	@echo "--- C ---" && ./c/uncommonlisp examples/fibonacci.lsp
	@echo
	@echo "═══ mergesort.lsp ═══"
	@echo "--- Python ---" && python3 uncommonlisp.py --fast examples/mergesort.lsp
	@echo "--- C ---" && ./c/uncommonlisp examples/mergesort.lsp
	@echo
	@echo "═══ objects.lsp ═══"
	@echo "--- Python ---" && python3 uncommonlisp.py examples/objects.lsp
	@echo "--- C ---" && ./c/uncommonlisp examples/objects.lsp

# ─── Friction benchmark ──────────────────────────────────────────

friction: c-build asm-build
	bash friction.sh

# ─── Documentation ────────────────────────────────────────────────

docs: docs/python-architecture.png docs/c-architecture.png docs/asm-architecture.png docs/jit-pipeline.png

docs/%.png: docs/%.dot
	dot -Tpng $< -o $@

# ─── Whitepaper ───────────────────────────────────────────────────

VENV        := whitepaper/.venv
RST         := whitepaper/uncommonlisp-whitepaper.rst
PDF         := whitepaper/uncommonlisp-whitepaper.pdf
STYLE       := whitepaper/whitepaper.style

$(VENV)/bin/rst2pdf:
	python3 -m venv $(VENV)
	$(VENV)/bin/pip install --upgrade pip
	$(VENV)/bin/pip install rst2pdf

whitepaper: $(PDF)

$(PDF): $(RST) $(STYLE) $(VENV)/bin/rst2pdf
	cd whitepaper && ../$(<D)/.venv/bin/rst2pdf \
		-s whitepaper.style \
		--fit-background-mode=scale \
		uncommonlisp-whitepaper.rst \
		-o uncommonlisp-whitepaper.pdf
	@ln -sf uncommonlisp-whitepaper.pdf whitepaper/WHITEPAPER.pdf
	@echo "Built: $(PDF)"

# ─── Clean ────────────────────────────────────────────────────────

clean:
	rm -rf __pycache__ *.pyc

clean-whitepaper:
	rm -rf $(VENV) $(PDF) whitepaper/WHITEPAPER.pdf

clean-docs:
	rm -f docs/*.png

clean-all: clean clean-whitepaper clean-docs 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-repl asm-clean \
        test-all bench-all examples friction functional-test \
        docs whitepaper clean clean-whitepaper clean-docs clean-all
