This is a LISP interpreter, with built-in support for arbitrary precision arithmetic, and immutable data structures.
const { run } = require('glisp');
run('(+ 1 2)') // 3
;; variables
(def one 1)
;; functions
(def id (fn [x] x))
;; let bindings
(let [one 1 two 2]
(+ one two)) ;; 3
;; quotes
(quote (1 2)) ;; (1 2)
;; unquotes
(let [one 1] (quote (unquote one))) ;; 1
;; do
(do
(+ 1 2)
(+ 3 4)) ;; 7
;; conditionals
(if (= 1 1) true false) ;; true
;; macros
(def defn (macro [name args body]
(quote
(def (unquote name) (fn (unquote args) (unquote body))))))
(defn double [x] (* x 2))
(double 2) ;; 4
;; throw errors!
(throw (js/Error "throw up!"))
GLISP uses Immutable.js to power its immutable data structures. GLISP recognizes Immutable.Stack
as an executable form.
;; Set
#{1 2 3 4 5}
;; Map
{1 2 3 4}
;; List
[1 2 3 4]
;; Stack
(quote (1 2 3))
Symbols prefixed with js/
will evaluate to the respective property on the global
object. Method calls can be made by prefixing the method name with a .
.
;; use window.console or global.console
(.log js/console 1 2 3 4 5)
;; push to a List
(.push [1 2 3] 10)
;; set properties on objects
(let [object (.toJS {})]
(aset object "name" "Ramanpreet Nara")
(aset object "age" 20)) ;; { name: "Ramanpreet Nara", age: 20 }
;; get properties on objects
(aget (.toJS {"age" 21}) "age") ;; 21
Within let
bindings and fn
declarations, destructure any collection that conforms to an iteration protocol understood by Iterall.
;; get all args
(def create-seq (fn [& args] args))
(create-seq 1 2 3 4 5) ;; [1 2 3 4 5]
;; get everything but the first element
(def rest (fn [[x & args]] args))
(rest [1 2 3 4 5]) ;; [2 3 4 5]
;; works in let bindings
(let [[x y] [1 2]]
(+ x y)) ;; 3
;; ooo... destructure any iterable
(let [[x y] (quote (1 2))]
[x y]) ;; [1 2]
GLISP supports JavaScript's 64 bit floating point numbers, BigNumbers, and Fractions.
;; Floating points!
(+ 0.1 0.2) ;; 0.30000000000000004
;; BigNumbers!
(+ 0.1M 0.2M) ;; 0.3
;; Fractions
(+ 1/3 2/3) ;; 1
;; Compare different number types!
(= 1/1 1 1M) ;; true
;; Beware of floating point errors!
(= (+ 0.1 0.2) 0.3M) ;; throws: Cannot convert a number with >15 significant digits to BigNumber!
(= (+ 0.1 0.2) 3/10) ;; throws: Cannot convert a number with >15 significant digits to Fraction!
Strings exist and can be created using double quotes.
"Produce side effects!"
"This is a multiline string!
Yay!"
"You can also \"quote\" within strings!")
# Run tests
> npm test
# Rebuild on file changes
> npm run build:watch
# Launch REPL
> npm run repl