can be used to add powerful scripting to any application
you may access C++ variables from the Lisp code:
double vec[4] = {665.l, 664.l, 663.l, 662.l};
auto eli = new ELI();
eli->var("extvec", &vec[0], 4);
eli->run("(set extvec (zipWith + (get extvec) (iota 4)))");
std::cout << vec[0] << ", " << vec[1] << ", " << vec[2] << ", " << vec[3] << "\n";
you also may call C++ functions from the Lisp code:
auto eli = new ELI();
eli->func("echo", [] (std::vector<std::string> params) {
for (auto p : params)
std::cout << p << "\n";
return std::vector<std::string>{};
});
eli->run("(call echo (iota 5))");
(seq x y ...)
- evaluate all arguments in order. Return the last evaluated argument.(val x y ...)
- return(x y ...)
as is without evaluating(def xi yi ...)
- definexi
to hold value ofyi
in global scope(let xi yi ... z)
- evaluatez
using namesxi
to hold values ofyi
(empty x)
- check ifx
is empty.()
,0
,0.0
and empty string are empty(list x)
- check ifx
is a list(atom x)
- check ifx
is an atom (that is a string or a number)(func x)
- check ifx
is a function (a lambda or a builtin)(if ci xi y)
- conditional (evaluate toxi
ifci
is true and finally toy
if allci
are false)(cons a b)
- construct a list of its heada
and tailb
(head x)
- evaluate to head ofx
(tail x)
- evaluate to tail ofx
(fn ai ... x)
- evaluate to lambda with parametersai
and bodyx
(+ a b)
- addition(* a b)
- multiplication(- a b)
- subtraction(/ a b)
- division(% a b)
- modulo(| a b)
- boolean or(& a b)
- boolean and(^ a b)
- boolean xor(! a)
- boolean not(= a b)
- equal(!= a b)
- not equal(> a b)
- greater(< a b)
- less(>= a b)
- greater or equal(<= a b)
- less or equal
(sqrt a)
- square root ofa
(pow a b)
-b
powered toa
(log a b)
- logarithm ofb
on basea
(sin a)
(cos a)
(sinCos a)
- return both sine and cosine ofa
(tan a)
(asin a)
(acos a)
(atan a)
(atan2 y x)
(abs a)
(floor a)
(ceil a)
(iota n)
- produce a list of numbers from0
ton - 1
(reverse a)
- reversea
(concat a b)
- concat two lists(take n a)
- produce a list containingn
first elements of a lista
(drop n a)
- dropn
first elements of a lista
, return the remaining elements(map f a)
- map a functionf
over a lista
(filter f a)
- produce a list containing only those elements ofa
for which the predicatef
returns true(takeWhile f a)
- take elements from the beginning of the list while the predicatef
holds(dropWhile f a)
- remove elements from the beginning of the list while the predicatef
holds(zipWith f a b)
- combine two lists with binary functionf
(foldl f a l)
- left fold a listl
with a functionf
and starting valuea
(foldl1 f l)
- left fold a listl
with a functionf
(foldr f a l)
- right fold a listl
with a functionf
and starting valuea
(foldr1 f l)
- right fold a listl
with a functionf
(get v)
- read external variablev
returning list of values(set v x)
- set external variablev
tox
(x
must be a list)(call f x)
- call external functionf
with argumentx
(wherex
is a list)
ELI::var
and ELI::func
are not explicitly thread safe.
ELI::run
and most lisp operations are implicitly thread-safe due to their local nature, except the following:
The def
operation is thread safe by itself but it modifies the global symbol table. The modified table is immediately visible to other threads which
may alter the desired results (see test.cpp
for an example).
The get
, set
and call
operations are not explicitly thread-safe.
The thread-safety will be improved in the future.