A Clojure compiler implemented on top of Chez Scheme https://jolt-lang.github.io/
Find a file
2026-06-04 15:40:59 -04:00
.beads docs: PLAN.md + memory updates for conformance gap-closing batch 2026-06-04 15:28:30 -04:00
.claude bd init: initialize beads issue tracking 2026-06-04 13:46:11 -04:00
.clj-kondo/.cache/v1/clj feat: assoc-in/update-in/fnil; fix update to use immutable assoc; fix latent core-assoc table-copy bug (splice of pairs) 2026-06-04 14:36:58 -04:00
.lsp/.cache feat: assoc-in/update-in/fnil; fix update to use immutable assoc; fix latent core-assoc table-copy bug (splice of pairs) 2026-06-04 14:36:58 -04:00
src/jolt feat: proper char type ({:jolt/type :jolt/char :ch N}) — reader literals, char?/char/int/str, =, seq/first/rest/nth of strings yield chars, char printing; fix REPL multi-line input accumulation 2026-06-04 15:40:59 -04:00
test feat: proper char type ({:jolt/type :jolt/char :ch N}) — reader literals, char?/char/int/str, =, seq/first/rest/nth of strings yield chars, char printing; fix REPL multi-line input accumulation 2026-06-04 15:40:59 -04:00
vendor feat: SCI submodule, gensym, doto, defrecord, multi-arity defn 2026-06-02 01:41:44 -04:00
.gitignore bd init: initialize beads issue tracking 2026-06-04 13:46:11 -04:00
.gitmodules feat: SCI submodule, gensym, doto, defrecord, multi-arity defn 2026-06-02 01:41:44 -04:00
AGENTS.md bd init: initialize beads issue tracking 2026-06-04 13:46:11 -04:00
CLAUDE.md bd init: initialize beads issue tracking 2026-06-04 13:46:11 -04:00
fix-core.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
LICENSE Initial commit: Jolt — Clojure interpreter on Janet 2026-06-01 16:48:56 -04:00
PLAN.md docs: PLAN.md + memory updates for conformance gap-closing batch 2026-06-04 15:28:30 -04:00
preprocess.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
project.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
README.md Phases 15-16: SCI bootstrap, Janet interop, eval, lazy-cat, CLJS ported tests 2026-06-03 23:44:49 -04:00
test-defprotocol.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
test-eval.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
test-form15.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
test-ivar.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
test-load-sci.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00
test-parse-utils.janet bootstrap: SCI core deps loading with 284/304 forms passing 2026-06-01 23:24:13 -04:00

Jolt

A Clojure interpreter running on Janet. Jolt reads Clojure source text, evaluates it using an interpreter written in pure Janet, and exposes a Clojure-compatible standard library. The goal is a Janet-hosted SCI runtime — minimal bootstrapping, with SCI as the standard library.

What's inside

Jolt implements the core of Clojure in a single-process Janet project:

Reader — A recursive descent parser for Clojure syntax: symbols, keywords, numbers, strings, characters, lists, vectors, maps, sets, quote forms, reader macros (#(), #_, #?), metadata, deref, and tagged literals.

Evaluator — A tree-walking interpreter with 22 special forms (quote, do, if, def, defmacro, fn*, let*, loop*/recur, throw, try, set!, var, locking, instance?, defmulti, defmethod, deftype, new, ., etc.), syntax-quote with unquote and unquote-splicing, a macro system with &env support, destructuring (:keys and sequential), and namespace forms (ns, require, in-ns).

Core library — 145+ bindings from clojure.core: predicates, math with Clojure arity semantics, comparison, collections, sequences, higher-order functions, string functions, I/O, atoms, macros (when, when-not, if-let, when-let, if-some, when-some, doto, fn, let, defn, defrecord, defprotocol), and SCI bootstrap stubs.

SCI bootstrap — All 317 forms from SCI's 9 core source files (macros, protocols, types, unrestrict, vars, lang, utils, namespaces, core) load with zero failures. 46 namespaces are populated with 900+ bindings. SCI's eval-string is replaced with a Jolt-native implementation.

Quick start

git clone https://github.com/yogthos/jolt.git
cd jolt
git submodule update --init   # pulls vendor/sci
jpm build                      # compiles build/jolt
build/jolt                     # drops into REPL

Build

jpm build

This compiles src/jolt/*.janet into a standalone build/jolt executable. Requires Janet ≥ 1.36 and jpm.

Run

build/jolt

Drops into a read-eval-print loop where you can type Clojure expressions:

user=> (+ 1 2)
3
user=> (map inc [1 2 3])
[2 3 4]
user=> (defn fib [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
#'user/fib
user=> (fib 10)
55

Test

jpm test

Runs all tests: API, bootstrap, core, evaluator, macro, namespace, reader, types, and SCI load.

Use as a library

(use jolt/api)

(def ctx (init))
(eval-string ctx "(+ 1 2)")       ;; → 3
(eval-string ctx "(map inc [1 2 3])") ;; → [2 3 4]
(eval-string ctx "(def x 42)")    ;; → #'user/x
(eval-string ctx "x")             ;; → 42

(init) returns a context with clojure.core loaded. Pass it to eval-string to evaluate Clojure source. Each context is isolated — use separate contexts for separate evaluation environments.

Janet-native interop

Jolt provides CLJS-style host interop through the . special form on any Janet table or struct:

;; Field access on tables and structs
user=> (def t {:a 1 :b 2})
user=> (. t :a)          ;; → 1
user=> (.-a t)           ;; → 1 (reader sugar)

;; Method calls — self is passed as first arg
user=> (def obj {:greet (fn [self name] (str "Hello " name))})
user=> (. obj greet "Alice")  ;; → "Hello Alice"

;; Multi-arg methods
user=> (def calc {:add (fn [_ a b] (+ a b))})
user=> (. calc add 3 4)       ;; → 7

Any table or struct field that holds a Janet function or C function can be called via . with implicit self dispatch. This pattern mirrors CLJS .method call semantics and unifies deftype protocol dispatch with plain Janet host interop.

Janet host functions — Janet's standard library (os/shell, net/request, etc.) is accessible through Jolt's jolt.interop namespace:

user=> (require '[jolt.interop :as j])
user=> (j/janet-eval "(+ 1 2)")            ;; → 3
user=> (j/janet-table-keys {:a 1 :b 2})    ;; → [:a :b]
user=> (j/janet-describe "hello")           ;; → Janet type info

The existing jolt.shell, jolt.http, and jolt.interop modules demonstrate the pattern: Clojure functions call Janet C functions through the Jolt bridge.

Project structure

src/jolt/
  types.janet       — Var, Namespace, Context, symbol helpers
  reader.janet      — recursive descent parser for Clojure syntax
  evaluator.janet   — tree-walking interpreter
  core.janet        — 145+ clojure.core bindings
  api.janet         — public API: init, eval-string, eval-string*
  main.janet        — REPL entry point
test/                — 8 test suites + SCI load test
vendor/sci/          — SCI submodule (git submodule)

License

Eclipse Public License 1.0