lumbda/docs/asm-architecture.dot
russell@unturf.com 670487c01d Add architecture docs with dot diagrams, update Makefile and CLAUDE.md
4 architecture diagrams (Graphviz DOT → PNG):
  python-architecture.dot  — bytecode VM + continuations + portal
  c-architecture.dot       — tree-walker + VM + JIT tiers
  asm-architecture.dot     — syscalls-only, 13KB binary
  jit-pipeline.dot         — AST → x86_64 machine code flow

docs/README.md — full architecture docs with embedded diagrams
and performance summary across all implementations.

Makefile: add asm-repl, docs target, clean-docs. Header comments
document all targets and test suites.

CLAUDE.md: add "A diagram is worth 10,000 words" (russell@unturf.com),
implementation table, test suite inventory.

Assembly is 2.5-4x faster than C interpreter on recursive workloads.
JIT remains 33x faster than hand-written assembly.
2026-04-15 14:07:59 -04:00

69 lines
2.6 KiB
Text

// Assembly implementation architecture
// "A diagram is worth 10,000 words." — russell@unturf.com
digraph asm_arch {
rankdir=TB
node [shape=box, style=filled, fontname="Helvetica"]
edge [fontname="Helvetica", fontsize=10]
subgraph cluster_binary {
label="Binary: 13KB, zero dependencies"
style=rounded
color="#333333"
fontcolor="#333333"
start [label="_start\nno libc\nno main()" fillcolor="#2d3436" fontcolor=white]
}
subgraph cluster_syscalls {
label="Linux Syscalls Only"
style=rounded
color="#666666"
read [label="sys_read (0)\nstdin" fillcolor="#dfe6e9"]
write [label="sys_write (1)\nstdout" fillcolor="#dfe6e9"]
mmap_s [label="sys_mmap (9)\n64MB heap" fillcolor="#dfe6e9"]
exit [label="sys_exit (60)" fillcolor="#dfe6e9"]
}
subgraph cluster_memory {
label="Memory Model"
style=rounded
color="#666666"
bump [label="Bump Allocator\n%r15 = heap ptr\nalloc = mov + add" fillcolor="#ffeaa7"]
tags [label="Tag-in-Low-3-Bits\n0=int 1=pair 2=sym\n3=closure 4=builtin\n5=special 6=string" fillcolor="#ffeaa7"]
}
subgraph cluster_interp {
label="Interpreter (2592 lines of asm)"
style=rounded
color="#666666"
tokenize [label="Tokenizer\nchar-by-char\nrep cmpsb for strings" fillcolor="#fff3cd"]
read_fn [label="Reader\nrecursive descent\n→ tagged cons cells" fillcolor="#fff3cd"]
eval_fn [label="Evaluator\nTCO via jmp .eval_top\nall special forms" fillcolor="#d4edda"]
print_fn [label="Printer\nitoa for ints\nlist traversal" fillcolor="#81ecec"]
builtins [label="34 Builtins\n+,-,*,=,<,>,cons,car,\ncdr,list,length,null?,\npair?,not,display..." fillcolor="#a29bfe"]
}
subgraph cluster_env {
label="Environment"
style=rounded
color="#666666"
env_chain [label="Linked List\n24 bytes per binding\n[sym | val | next]" fillcolor="#e2d5f1"]
sym_intern [label="Symbol Table\nlinear scan\ninterned on first use" fillcolor="#e2d5f1"]
}
start -> mmap_s [label="allocate heap"]
start -> read [label="read input"]
read -> tokenize
tokenize -> read_fn
read_fn -> eval_fn
eval_fn -> eval_fn [label="TCO: jmp" style=bold color=red]
eval_fn -> builtins [label="apply"]
eval_fn -> env_chain [label="lookup/define"]
eval_fn -> print_fn [label="result"]
print_fn -> write
env_chain -> sym_intern
bump -> tags
eval_fn -> bump [label="cons/closure alloc"]
{rank=same; read; write; mmap_s; exit}
{rank=same; tokenize; read_fn}
}