Small Clojure Interpreter
source link: https://www.tuicool.com/articles/2MnaArF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Small Clojure Interpreter
A tiny implementation of Clojure in Clojure.
Quickstart
Use from Clojure(Script)
(require '[sci.core :as sci]) (sci/eval-string "(inc 1)") => ;; 2 (sci/eval-string "(inc x)" {:bindings {'x 2}}) ;;=> 3
Use from JavaScript
> const { evalString } = require('@borkdude/sci'); > const opts = {bindings: {f: function() { console.log('hello'); }}}; > evalString("(dotimes [i 2] (f))", opts); hello hello
Rationale
You want to evaluate code from user input, but eval
isn't safe or simply doesn't work.
This library works 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:
Usage
Currently the only API function is sci.core/eval-string
which takes a string to evaluate and an optional options map.
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
Feature parity
Currently the following special forms/macros are supported: def
, fn
, function literals ( #(inc %)
), defn
, quote
, do
, if
, if-not
, when
, when-not
, cond
, let
, and
, or
, ->
, ->>
, as->
, comment
, loop
, lazy-seq
, for
, doseq
, case
, try/catch/finally
. It also supports user defined macros.
More examples of what is currently possible can be found at babashka .
If you miss something, feel free to post an issue.
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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK