Files
bara-lang/docs/ARCHITECTURE.md
T

2.9 KiB

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:

(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:

(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