Skip to content
Small Clojure Interpreter
Clojure Shell
Branch: master
Clone or download
Latest commit a4ceda5 Aug 20, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci CircleCI Aug 15, 2019
.clj-kondo initial commit Aug 11, 2019
.github Create FUNDING.yml Aug 15, 2019
doc initial commit Aug 11, 2019
resources bump version Aug 16, 2019
script support fn and defn Aug 14, 2019
src/sci make pr-str-ed fn-literal work (3) Aug 19, 2019
test/sci performance benchmark Aug 20, 2019
.gitignore initial commit Aug 11, 2019
LICENSE initial commit Aug 11, 2019
README.md implement def (#20) Aug 15, 2019
deps.edn initial commit Aug 11, 2019
project.clj make pr-str-ed fn-literal work (#34) Aug 19, 2019
reflection.json initial commit Aug 11, 2019

README.md

Small Clojure Interpreter

CircleCI Clojars Project cljdoc badge

A tiny implementation of Clojure in Clojure.

Rationale

You want to evaluate code from user input, but eval isn't safe or simply doesn't work.

This library works with:

  • Clojure on the JVM
  • Clojure compiled with GraalVM native
  • ClojureScript, even when compiled with :advanced

It is used as the interpreter for babashka.

Status

Experimental. Breaking changes are expected to happen at this phase.

Installation

Use as a dependency:

[borkdude/sci "0.0.4"]

Usage

(require '[sci.core :as sci])
(sci/eval-string "(inc 1)") => ;; 2
(sci/eval-string "(inc x)" {:bindings {'x 2}}) ;;=> 3

Currently the following special forms/macros are supported: def, fn, function literals (#(inc %)), defn, quote, do,if, when, let, and, or, ->, ->>, as->.

In sci, defn does not mutate the outside world, only the evaluation context inside a call to sci/eval-string.

By default sci only enables access to the pure non-side-effecting functions in Clojure. More functions can be enabled, at your own risk, using :bindings:

user=> (sci/eval-string "(println \"hello\")" {:bindings {'println println}})
hello
nil

More examples of what is currently possible can be found at babashka.

Caveats

To make the rand-* functions behave well when compiling to a GraalVM native binary, use this setting:

--initialize-at-run-time=java.lang.Math\$RandomNumberGeneratorHolder

Test

Required: lein, the clojure CLI and GraalVM.

To succesfully run the GraalVM tests, you will have to compile the binary first with script/compile.

To run all tests:

script/test/all

For running individual tests, see the scripts in script/test.

License

Copyright © 2019 Michiel Borkent

Distributed under the Eclipse Public License 1.0. This project contains code from Clojure and ClojureScript which are also licensed under the EPL 1.0. See LICENSE.

You can’t perform that action at this time.