docs: reorganize into en/ and bg/ subfolders with numbered indices

- New docs/index.md with language selector
- docs/en/ — 01-getting-started, 02-architecture, 03-ai-integration,
  04-api-reference, 05-user-guide, 06-roadmap
- docs/bg/ — same structure in Bulgarian
- Root README.md trimmed to quick-start + links to docs/
- Removed old flat docs/ files (ARCHITECTURE.md, AI_FIRST.md, etc.)
- Added swap!/reset! examples to getting-started guides
This commit is contained in:
2026-05-08 23:24:47 +03:00
parent 2b32640eeb
commit 10e4ec07d6
18 changed files with 490 additions and 443 deletions
+127
View File
@@ -0,0 +1,127 @@
[← Back to Index](index.md)
---
# Getting Started
> A Clojure dialect that compiles to Nim → C → native binaries.
## Prerequisites
- **Nim** >= 2.0.0
- **GCC** or **Clang**
- **make**
- **curl** (for AI features, optional)
## Installation
```bash
git clone https://gitlab.com/balvatar/lisp-nim.git
cd lisp-nim
make build
```
## Verify Installation
```bash
make check # build + 276+ tests + all examples
```
## CLI Commands
| Command | Description |
|---------|-------------|
| `./cljnim compile <file.clj>` | Compile to Nim source |
| `./cljnim compile-lib <file.clj>` | Compile to Nim with exported functions (`*`) |
| `./cljnim run <file.clj>` | Compile and run binary |
| `./cljnim read <file.clj>` | Parse and print AST |
| `./cljnim repl` | Start human REPL |
| `./cljnim repl --json` | Start JSON REPL (for AI agents) |
| `./cljnim deps` | Resolve dependencies from `deps.edn` |
| `./cljnim -e '<code>'` | Evaluate expression |
| `./cljnim ai '<description>'` | Generate Clojure code with AI |
## Quick Examples
### Hello World
```clojure
;; examples/hello.clj
(println "Hello, Nim world!")
(println (+ 1 2 3))
```
```bash
$ ./cljnim run examples/hello.clj
Hello, Nim world!
6
```
### Functions & Recursion
```clojure
(defn square [x] (* x x))
(defn factorial [n]
(if (= n 0)
1
(* n (factorial (- n 1)))))
(let [a 5]
(println (square a))
(println (factorial a)))
```
### loop/recur
```clojure
(defn sum [n]
(loop [acc 0 i 1]
(if (> i n)
acc
(recur (+ acc i) (inc i)))))
(println (sum 10)) ;; => 55
```
### Atoms (REPL)
```clojure
user> (def a (atom 0))
user> (swap! a inc)
1
user> (reset! a 42)
42
user> (deref a)
42
```
## AI Setup (Optional)
```bash
export DEEPSEEK_API_KEY="sk-..."
# or OPENAI_API_KEY, or MIMO_API_KEY
```
See [03-ai-integration.md](03-ai-integration.md) for full AI documentation.
## Project Structure
```
├── src/ # Compiler source
│ ├── cljnim.nim # CLI entry point
│ ├── reader.nim # EDN parser
│ ├── emitter.nim # Clojure AST → Nim
│ ├── eval.nim # Tree-walking interpreter (REPL fast path)
│ └── ai_assist.nim # AI API integration
├── lib/ # Runtime libraries
│ ├── cljnim_runtime.nim # Native runtime
│ └── cljnim_runtime_js.nim # JS runtime
├── tests/ # Test suites (8 files, 276+ tests)
├── examples/ # Example .clj files
├── benchmarks/ # Performance benchmarks
├── docs/ # Documentation
└── experiments/ # Web, WASM, native-lib targets
```
## Next Steps
- [02-architecture.md](02-architecture.md) — How the compiler works
- [03-ai-integration.md](03-ai-integration.md) — AI-powered development
- [04-api-reference.md](04-api-reference.md) — JSON REPL protocol
- [05-user-guide.md](05-user-guide.md) — Macros, interop, advanced patterns
+107
View File
@@ -0,0 +1,107 @@
[← Back to Index](index.md)
---
# 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
Instead of Java interop, we have direct Nim interop:
```clojure
(nim/math/sin x)
(nim/strutils/toUpper s)
```
Nim modules are auto-imported when called via the `nim/module/fn` pattern.
## 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/eval.nim` | Tree-walking interpreter for fast in-memory eval |
| `src/deps.nim` | Dependency resolution (deps.edn format) |
| `src/core.nim` | Core runtime functions (AOT compiled) |
| `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 |
| `lib/cljnim_pvec.nim` | Persistent Vector (HAMT implementation) |
| `lib/cljnim_pmap.nim` | Persistent Hash Map (HAMT implementation) |
| `lib/cljnim_async.nim` | core.async channels runtime |
## Memory Model
- Uses Nim's ORC garbage collector
- `CljVal` is a `ref object` (heap-allocated)
- Persistent data structures (Vector, Map, Set) use structural sharing via HAMT
+112
View File
@@ -0,0 +1,112 @@
[← Back to Index](index.md)
---
# AI-First Design Philosophy
## Why AI-First?
Modern software development is increasingly done by **AI agents** operating in terminal environments. These agents do not use GUIs, IDEs, or syntax highlighting. They need:
1. **Structured I/O** — JSON/EDN, not plain text
2. **Programmatic Control** — Every operation must be scriptable
3. **Self-Describing Systems** — AI can discover capabilities at runtime
4. **Git Integration** — Version control as part of the workflow
## Principles
### 1. Structured I/O
All REPL communication uses JSON:
```json
// Input
{"op": "eval", "form": "(+ 1 2)", "request-id": "uuid"}
// Output
{
"status": "ok",
"request-id": "uuid",
"result": {"type": "int", "value": 3, "printed": "3"},
"meta": {"ms": 0.5, "ns": "user"}
}
```
### 2. Batch Operations
AI agents evaluate multiple forms at once:
```json
{"op": "eval-batch",
"forms": [
"(defn add [a b] (+ a b))",
"(add 10 20)"
]}
```
### 3. Session Persistence
Definitions persist within a REPL session, allowing incremental development:
```json
{"op": "eval", "form": "(defn square [x] (* x x))"}
{"op": "eval", "form": "(square 5)"}
{"op": "get-defs"}
```
### 4. Error Recovery
All errors are structured with type, message, and context:
```json
{
"status": "error",
"error": {
"type": "compiler/unknown-symbol",
"symbol": "unknwon-fn",
"message": "Unknown symbol: unknwon-fn",
"form": "(unknwon-fn 1 2)"
}
}
```
## AI Workflow
```bash
# 1. Clone repo
git clone git@gitlab.com:balvatar/lisp-nim.git
cd lisp-nim
# 2. Start AI REPL
cljnim repl --json
# 3. AI evaluates forms, gets structured responses
# 4. AI writes files via (file/write ...) [future]
# 5. AI commits via (git/commit ...) [future]
# 6. AI pushes via (git/push) [future]
```
## Comparison
| Aspect | Human IDE | AI Terminal |
|---|---|---|
| Interface | GUI + mouse | Text + commands |
| Navigation | Clicking | `(apropos ...)`, `(doc ...)` |
| Refactoring | Manual | Batch eval + git diff |
| Testing | Run button | `(run-tests)` structured response |
| Commit | GUI dialog | `(git/commit "msg")` |
## Future: Tool-Call Format
Direct integration with AI frameworks:
```json
{
"tool": "cljnim/eval",
"arguments": {
"code": "(defn fib [n] ...)",
"mode": "compile"
}
}
```
+180
View File
@@ -0,0 +1,180 @@
[← Back to Index](index.md)
---
# REPL API Reference
## JSON REPL Protocol
Start the JSON REPL:
```bash
cljnim repl --json
```
The REPL reads one JSON object per line and responds with one JSON object per line.
## Operations
### `eval`
Evaluate a single Clojure form.
**Request:**
```json
{"op": "eval", "form": "(+ 1 2 3)"}
```
**Response (success):**
```json
{
"status": "ok",
"result": {
"type": "unknown",
"value": "6",
"printed": "6"
},
"meta": {
"ns": "user",
"ms": 861.5,
"form": "(+ 1 2 3)"
}
}
```
**Response (error):**
```json
{
"status": "error",
"error": {
"type": "reader/error",
"message": "Unterminated list",
"form": "( + 1 2"
},
"meta": {
"ns": "user",
"ms": 0.1
}
}
```
**Optional fields:**
- `request-id` — Correlation ID, echoed in the response
- `ns` — Target namespace (default: `"user"`)
---
### `eval-batch`
Evaluate multiple forms in sequence.
**Request:**
```json
{"op": "eval-batch", "forms": ["(defn f [x] x)", "(f 42)"]}
```
**Response:**
```json
{
"status": "ok",
"results": [
{"status": "ok", "result": {"type": "var", "name": "f", ...}},
{"status": "ok", "result": {"printed": "42"}, ...}
]
}
```
---
### `get-defs`
List all vars defined in the current session.
**Request:**
```json
{"op": "get-defs"}
```
**Response:**
```json
{"status": "ok", "defs": ["add", "square"], "ns": "user"}
```
---
### `clear`
Clear all session definitions.
**Request:**
```json
{"op": "clear"}
```
**Response:**
```json
{"status": "ok", "cleared": true}
```
---
### `quit`
Exit the REPL.
**Request:**
```json
{"op": "quit"}
```
**Response:**
```json
{"status": "ok", "bye": true}
```
## Response Schema
All responses contain:
- `status``"ok"` or `"error"`
On success:
- `result` — Evaluation result object
- `type``"var"`, `"unknown"`, etc.
- `printed` — String representation of the result
- `meta` — Metadata
- `ns` — Current namespace
- `ms` — Execution time in milliseconds
- `form` — Original form (if `eval`)
On error:
- `error` — Error object
- `type` — Error category
- `message` — Human-readable message
- `meta` — Same as success
## File Operations (from Clojure code)
| Function | Example | Returns |
|---|---|---|
| `file/read` | `(file/read "path")` | String content or error map |
| `file/write` | `(file/write "path" "content")` | `true` or error map |
| `file/append` | `(file/append "path" "more")` | `true` or error map |
| `file/ls` | `(file/ls "dir")` | Vector of filenames |
| `file/exists?` | `(file/exists? "path")` | `true` / `false` |
## Git Operations (from Clojure code)
| Function | Example | Returns |
|---|---|---|
| `git/status` | `(git/status)` | Map with `:branch`, `:modified`, `:untracked`, `:staged`, `:clean` |
| `git/commit` | `(git/commit "msg")` | Map with `:sha`, `:success` |
| `git/push` | `(git/push)` | Map with `:success`, `:output` |
| `git/diff` | `(git/diff)` | Diff string |
| `git/log` | `(git/log)` or `(git/log 10)` | Vector of commit strings |
## Human REPL Commands
In human mode (`cljnim repl`):
| Command | Description |
|---|---|
| `:quit`, `:q` | Exit REPL |
| `:help`, `:h` | Show help |
| `:defs` | List defined vars |
| `:clear` | Clear definitions |
| `:ns` | Show current namespace |
+155
View File
@@ -0,0 +1,155 @@
[← Back to Index](index.md)
---
# Clojure/Nim User Guide
## Installation
### Prerequisites
- Nim >= 2.0
- GCC or Clang
- make
### Build from Source
```bash
git clone https://gitlab.com/balvatar/lisp-nim.git
cd lisp-nim
make build
```
## CLI Commands
### `compile` — Compile to Nim
```bash
./cljnim compile input.clj output.nim
```
Generates a `.nim` file from Clojure source.
### `run` — Compile and Execute
```bash
./cljnim run examples/hello.clj
```
Compiles to Nim, then to C, then to a binary, and runs it.
### `read` — Parse and Print AST
```bash
./cljnim read examples/hello.clj
```
Shows the Clojure AST as S-expressions.
### `repl` — Interactive REPL
```bash
# Human-friendly mode
./cljnim repl
# AI mode (structured JSON)
./cljnim repl --json
```
## Writing Clojure/Nim Programs
### Basic Syntax
```clojure
; Comments start with semicolon
; Define a variable
(def x 42)
; Define a function
(defn greet [name]
(println "Hello, " name))
; Call a function
(greet "World")
; Arithmetic
(+ 1 2 3) ; => 6
(* 10 20) ; => 200
(/ 100 4) ; => 25
; Conditionals
(if (> x 0)
"positive"
"non-positive")
; Local bindings
(let [a 10
b 20]
(+ a b)) ; => 30
```
### Working with Data
```clojure
; Vectors (use Nim seq internally)
(def nums [1 2 3 4 5])
; Keywords
(def person {:name "Alice" :age 30})
; Maps and sets use persistent HAMT data structures
; with structural sharing and O(log₃₂ n) operations.
```
### Recursion
```clojure
(defn factorial [n]
(if (= n 0)
1
(* n (factorial (- n 1)))))
(println (factorial 5)) ; => 120
```
## AI REPL Guide
The JSON REPL is designed for programmatic interaction.
### Start AI REPL
```bash
./cljnim repl --json
```
### Evaluate a Form
```json
{"op": "eval", "form": "(+ 1 2 3)"}
```
Response:
```json
{
"status": "ok",
"result": {"printed": "6"},
"meta": {"ns": "user", "ms": 861, "form": "(+ 1 2 3)"}
}
```
### Batch Evaluation
```json
{"op": "eval-batch", "forms": ["(defn f [x] x)", "(f 42)"]}
```
### List Definitions
```json
{"op": "get-defs"}
```
Response:
```json
{"status": "ok", "defs": ["f"], "ns": "user"}
```
### Clear Session
```json
{"op": "clear"}
```
### Exit
```json
{"op": "quit"}
```
## Tips
- Use `:help` in human REPL for available commands.
- Definitions in REPL persist across evaluations in the same session.
- The `--json` flag makes the REPL fully machine-readable.
+91
View File
@@ -0,0 +1,91 @@
[← Back to Index](index.md)
---
# Development Roadmap
## Phase 0: Compiler Core ✅
- [x] Clojure Reader (EDN parser)
- [x] Reader supports: lists `()`, vectors `[]`, maps `{}`, strings, keywords, symbols, numbers, booleans, nil
- [x] Reader supports: quote `'`, syntax-quote `` ` ``, unquote `~`, unquote-splicing `~@`
- [x] Reader supports: comments `;`, read-all
- [x] AST → Nim Emitter
- [x] CLI (`compile`, `run`, `read`, `repl`)
- [x] Special forms: `def`, `defn`, `fn`, `let`, `if`, `do`, `quote`
- [x] Special forms: `when`, `cond`
- [x] Arithmetic operators: `+`, `-`, `*`, `/`
- [x] Comparison operators: `=`, `not=`, `not`, `<`, `>`, `<=`, `>=`
- [x] Core functions: `println`, `map`, `filter`, `reduce`
- [x] Runtime type system: `CljVal` with `nil`, `bool`, `int`, `float`, `string`, `keyword`, `symbol`, `list`, `vector`, `map`, `fn`, `atom`
## Phase 1: Macro System ✅
- [x] `macroexpand`, `macroexpand-1`
- [x] `syntax-quote`, `unquote`, `unquote-splicing`
- [x] `gensym`
- [x] `defmacro` (user-defined macros)
- [x] Built-in macros: `->`, `->>`, `and`, `or`, `when`, `when-not`, `cond`
- [x] Built-in macros: `cond->`, `cond->>`, `doto`, `as->`, `some->`, `some->>`
- [x] Built-in macros: `for`, `doseq`, `dotimes`
- [x] Built-in macros: `when-let`, `if-let`
- [x] Built-in macros: `comment`, `assert`, `with-open`
## Phase 2: REPL & Tooling ✅
- [x] Human REPL (`:help`, `:defs`, `:clear`, `:ns`, `:quit`)
- [x] JSON REPL (`--json`) with structured I/O
- [x] Batch evaluation (`eval-batch`)
- [x] Structured errors (type, message, form, line)
- [x] Session persistence for `def`/`defn` definitions
## Phase 3: Nim Interop ✅
- [x] Call Nim functions: `(nim/math/sin x)`, `(nim/strutils/toUpper s)`
- [x] C FFI via Nim `importc`
## Phase 4: AI-Native Tooling ✅
- [x] File operations: `(file/read "path")`, `(file/write "path" "content")`, `(file/append "path" "content")`
- [x] File operations: `(file/ls "dir")`, `(file/exists? "path")`
- [x] Git operations: `(git/status)`, `(git/commit "msg")`, `(git/push)`
- [x] Git operations: `(git/diff)`, `(git/log)`
- [x] nREPL protocol compatibility (JSON over TCP, `--tcp PORT`)
- [x] Tool-call format for AI framework integration
## Phase 5: Persistent Data Structures ✅ (Complete)
- [x] Persistent Vector (Hash Array Mapped Trie, 32-way branching)
- [x] Persistent Map (HAMT) — `pmapAssoc`, `pmapDissoc`, `pmapGet` in O(log₃₂ n)
- [x] Persistent Set — backed by HAMT map, `conj`/`disj`/`contains?`/`get`
- [x] `conj`, `assoc`, `dissoc`, `get`, `get-in`
- [x] `nth`, `first`, `rest`, `last`, `count` on persistent collections
- [x] Transients for batch mutations
- [x] `conj!`, `assoc!`, `persistent!`
## Phase 6: Clojure Core Library ✅ (Complete)
- [x] `range` (0/1/2/3 args), `repeat`, `cycle`, `iterate`
- [x] `take`, `drop`, `partition`, `interleave`, `concat`
- [x] `str`, `pr-str`, `println`, `prn`
- [x] `slurp`, `spit`, `read-line`
- [x] `meta`, `with-meta`, `vary-meta`
- [x] `type`, `instance?`, `satisfies?`
## Phase 7: Project Compilation
- [x] Compile entire projects (not just single files)
- [x] Namespace system (`ns`, `(:require [lib :as alias])`)
- [x] Module caching for faster REPL startup
- [x] Dependency resolution (deps.edn, Git deps to .deps/)
## Phase 8: Self-Hosted REPL ✅
- [x] Compile forms in memory (tree-walking interpreter, <1ms eval)
- [x] Fast REPL startup (~0.02ms per eval vs 1133ms compiled)
- [x] Hot code reloading (def/defn update env immediately)
## Phase 9: Concurrency ✅
- [x] Atoms (compare-and-swap)
- [x] Agents (send, await, deref — sync dispatch in interpreter)
- [x] core.async channels (chan, >!, <!, close!, go — interpreter-first)
## Known Issues
- `->>` threading macro with nested `map`/`reduce` requires proper macro expansion context
## Recent Bug Fixes (2026-05-08)
- Fixed: ffi/interop examples — temp files now use isolated subdirectories to avoid shadowing Nim stdlib modules (e.g., `math.nim` shadowing `import math`)
- Fixed: `quot`/`rem` — added `cljQuot`/`cljRem` to runtime + interpreter support
- Cleanup: removed unused `processAgentActions` proc, unused `sequtils` import in repl.nim
+36
View File
@@ -0,0 +1,36 @@
[← Back to Index](index.md)
---
# Clojure/Nim Documentation (English)
> A Clojure dialect that compiles to Nim → C → native binaries.
## Table of Contents
| # | Document | Description |
|---|----------|-------------|
| 01 | [Getting Started](01-getting-started.md) | Installation, build, CLI commands, quick examples |
| 02 | [Architecture](02-architecture.md) | Compiler pipeline, design decisions, internal structure |
| 03 | [AI Integration](03-ai-integration.md) | DeepSeek, OpenAI, MiMo — error assistance, code generation, optimization, debugging |
| 04 | [API Reference](04-api-reference.md) | JSON REPL protocol, operations, tool-call format |
| 05 | [User Guide](05-user-guide.md) | Macros, threading, interop, advanced patterns |
| 06 | [Roadmap](06-roadmap.md) | Completed phases, future plans, performance targets |
## Quick Start
```bash
git clone https://gitlab.com/balvatar/lisp-nim.git
cd lisp-nim
make build
make check # build + tests + examples
./cljnim repl # human REPL
```
## Stats
- **Tests:** 276+ across 8 suites
- **Compiler:** Nim → C → native
- **Targets:** Linux, macOS, Windows, JS, WASM, C shared libraries
- **AI Support:** DeepSeek API, OpenAI-compatible, Xiaomi MiMo