# Clojure/Nim Architecture ## Overview Clojure/Nim is a **compiler**, not an interpreter. It follows the model of ClojureScript: Clojure source is read, macro-expanded, analyzed, and emitted as Nim source code, which then compiles to C and finally to a native binary. ## Compilation Pipeline ``` ┌─────────────┐ │ .clj File │ └──────┬──────┘ │ ┌────▼────┐ │ Reader │ ← EDN parser. Produces Clojure data structures. └────┬────┘ │ ┌────▼────┐ │ Macros │ ← defmacro expansion. Operates on Clojure data. └────┬────┘ │ ┌────▼────┐ │ Analyzer│ ← Special forms, locals, closure analysis. └────┬────┘ │ ┌────▼────┐ │ Emitter │ ← Generates Nim AST / source code. └────┬────┘ │ ┌────▼────┐ │ Nim CC │ ← Nim → C compilation. └────┬────┘ │ ┌────▼────┐ │ C CC │ ← C → machine code (GCC/Clang). └────┬────┘ │ ┌────▼────┐ │ Binary │ ← Single native executable. └─────────┘ ``` ## Key Design Decisions ### 1. AOT Compiler We compile ahead-of-time, like ClojureScript. This gives us: - Fast runtime execution (C speed) - Small binary size - No interpreter overhead The trade-off is that REPL compilation is slower (each form is compiled individually). ### 2. Clojure Macros on Clojure Data Macro expansion happens **before** reaching Nim. Nim never sees Clojure macros: ```clojure (defmacro unless [condition & body] `(if (not ~condition) (do ~@body))) ``` This macro operates on `CljVal` objects (Clojure lists, symbols), not Nim AST. ### 3. Runtime in Nim The `lib/cljnim_runtime.nim` module provides: - `CljVal` — tagged union representing all Clojure values - `cljAdd`, `cljMul`, etc. — polymorphic arithmetic - `cljRepr` — string representation ### 4. Nim Interop (Future) Instead of Java interop, we will have Nim interop: ```clojure (nim/import "strutils") (nim/call "strutils.join" ", " ["a" "b"]) ``` ## Module Responsibilities | Module | Role | |---|---| | `src/reader.nim` | Parses `.clj` text into `CljVal` AST | | `src/emitter.nim` | Transforms `CljVal` AST into Nim source | | `src/repl.nim` | Human and AI REPL implementation | | `src/types.nim` | AST node types (used by reader/emitter) | | `src/macros.nim` | Macro expansion engine | | `src/runtime.nim` | Additional runtime helpers | | `lib/cljnim_runtime.nim` | Core runtime library | ## Memory Model - Uses Nim's ORC garbage collector - `CljVal` is a `ref object` (heap-allocated) - Future: persistent data structures use structural sharing