Simple and configurable generic script language.
npm install pocket-lisp-page
npm start
The following example shows how you can init Pocket lisp with the stdlib:
import { PocketLisp } from 'index.es.js'
import { literals, runtime, utils } from 'stdlib.es.js'
const pocketLisp = new PocketLisp(
{
globals: runtime,
stdout: value => writeOutput(value, false),
utils
},
literals
)
const run = async sourceCode => {
try {
await pocketLisp.execute(src)
} catch (e) {
for (let err of e.errors) {
const msg = e.type === 'Parser' ? `line: ${err.line} - ${err.message}` : err.message
writeOutput(msg, true)
}
}
}
run('(print (+ 1 2))')
new(options?: Partial<InterpreterOptions>, literals?: PLLiterals)
- create a new Pocket lisp interpreter instance.execute(source: string)
- execute the Pocket lisp source codeevalFn(fn: PLCallable, args: anyp[])
- evaluate fn
with the passed arguments in the current execution environment.On NPM: https://www.npmjs.com/package/pocket-lisp
It contains both ES5 and ES6 packages with typescript type definitions
index.js
and index.es.js
stdlib.js
and stdlib.es.js
The syntax very similar to the closure script language
[ 1 2 3 ]
equivalent with: [ 1, 2, 3 ]
;
;#
and #;
The identifier
=+-*\&%$_!<>?
=+-*\&%$_!<>?
Keywords are identifiers without value (symbols). They are very useful when you need a map key or other identifier without care about the actual value.
:
) and=+-*\&%$_!<>?
:keyword
:t1
:x
List a special structure which is very similar to an array, except the first item must be callable (lambda function, or function reference). The rest of the list will be the parameters of the function.
(print 1 2 3)
true
and false
42
42.5
1/2
numerator and denominator must be integer"Hello world"
Array like structure
[ 1 2 3 ]
HashMap is set of key value pairs where the key must be unique.
For example:{ key1 value1 key2 value2 }
Note: Hashmap must have even number of paramaters
print
Print value to the standard output. It accepts any amount of parameters.
(print "Hello world") ; print: "Hello world"
(print 42) ; print: 42
const
Wrap a constant value into a function
(print (map (const 1) [1 2 3])) ; print: [1 1 1]
(def _42 (const 42))
(print (_42)) ; print: 42
def
def
function can create a new variable in the current scope.
The function has 2 parameters:
Define the x
variable
(def x 42)
(print x) ; print: 42
fn
fn
define a lambda function. It has 2 parameters:
(fn [] 42) ; 0 parameter lamda function, returns with 42
(fn [] (+ 1 2)) ; 0 parameter lamda function, returns with 3
(fn [a b] (+ a b)) ;
; function closure
(def add (fn [a] ( fn [b] (+ a b) )))
(def addTo10 (add 10)) ; create reference for the function
(print (addTo10 1)) ; print: 11
#()
(def add #(+ %1 %2))
(def addTo10 (add 10))
(print (addTo10 1)) ; print: 11
defn
defn
function is a shortcut for the often used def
and fn
combination.
The fallowing two definitions are equivalent:
(def add (fn [a b] (+ a b)))
(defn add [a b] (+ a b))
(print (add 40 2)) ; print: 42
if
if
function has 3 parameters and if the first expression value is true
then evaluate and return with the second parameter otherwise does the same with the third parameter
(print (if true 1 2)) ; print: 1
case
case
function fist parameter is the condition value the rest of the parameters are the case branches.
Each breach is a list of two items:
:else
keyword as default branch(case 42
((>= 10) (print "Ok"))
((#(and (<= 11 %1) (> 50 %1))) (print "Warning"))
(:else (print "Error"))
)
; print: "Warning"
Note:
true
(even if it is :else
) will returncase
must have at least one branch with true
predicatedo
do
run sequentially all the passed parameters and return with the values of the last expression. It must be called with at least 1 parameter.
(print (do 1 2 42)) ; print: 42
(defn x [] (do (+ 1 2) 10))
side-effect
Wrap a non-pure function into another function
(print (map (side-effect random) [1 2 3])) ; print: [0.321, 0.987, 0.451]
It also accepts additional parameters which are passed to the function
(def effect (side-effect print "hello"))
(effect) ; print: "hello