A Lisp interpreter is available in MOROS to extend the capabilities of the shell.
MOROS Lisp is a Lisp-1 dialect inspired by Scheme, Clojure, and Ruby!
Check the documentation for more information.
bool, list, sym, strfloat, int, bigint2.5, -25, 255, 0xFF, 0xDEAD_C0DE, 0b101010"Hello, World!"\b, \e, \n, \r, \t, \", \\quote (abbreviated with ')quasiquote (abbreviated with `)unquote (abbreviated with ,)unquote-splice (abbreviated with ,@)splice (abbreviated with @)atom?eq? (aliased to =)consifcondcasemacfunvarvar?mutdef (equivalent to def-fun)def-fundef-macapplyfoldwhiledodocevalexpandloadtype, parsestrstr->num, num->strstr->bin, bin->strnum->bin, bin->numregex/findsh, sh->bindate, sleepnum/type, num/int, num/eq?bit/not, bit/and, bit/or, bit/xor, bit/shl, bit/shr (aliased to ~, &, |, ^, <<, >>)add, sub, mul, div, exp, rem (aliased to +, -, *, /, **, %)acos, asin, atan, cos, sin, tangt?, lt?, gte?, lte? (aliased to >, <, >=, <=)len, put, get, slice, contains?str/trim, str/splitlist, concat, chunks, sort, uniqdict, dict/pairsfile/exists?, file/size, file/open, file/close, file/read, file/writehost, socket/connect, socket/listen, socket/acceptnil, nil?, list?, empty?bool?, str?, sym?, num?fun?, mac?abs, mod, min, maxfirst (aliased to head), second, third, last, rest (aliased to tail), pushmap, reduce, rev, range, filter, reject, intersectionnot, and, orset, letstr/join, lines, words, charssh->strregex/match?dirname, filenameread, write, appendread-bin, write-bin, append-binread-line, read-charclock/boot, clock/epochp, print, eprint, errorfloor, ceil, rounddict/keys, dict/valuesatom, eq, label, lambda, progn, begincar, cdr, caar, cadr, cdar, cddrThe interpreter can be invoked from the shell:
> lisp
MOROS Lisp v0.9.0
> (+ 1 2 3)
6
> (quit)
And it can execute a file. For example a file located in /tmp/lisp/fibonacci.lsp
with the following content:
(load "/lib/lisp/core.lsp")
(def (fibonacci n)
(if (< n 2) n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(print
(if (nil? args) "Usage: fibonacci <num>"
(fibonacci (str->num (head args)))))
Would produce the following output:
> lisp /tmp/lisp/fibonacci.lsp 20
6755
(load "/lib/lisp/core.lsp")
(print "Hello, World!")
(set foo 10) # Variable binding
(set foo (+ foo 10)) # Variable rebinding
(set double (fun (x) (* x 2))) # Function definition
(def (double x) (* x 2)) # Shortcut
(double foo) # => 84
(def-mac (++ x) # Macro definition
`(set ,x (+ ,x 1)))
(set i 0)
(while (< i 10)
(++ i))
(= i 10) # => true
(def (map f ls)
"Apply function to list"
(if (nil? ls) nil
(cons
(f (first ls))
(map f (rest ls)))))
(doc map) # => "Apply function to list"
(set bar (quote (1 2 3)))
(set bar '(1 2 3)) # Shortcut
(map double bar) # => (2 4 6)
(map (fun (x) (+ x 1)) '(4 5 6)) # => (5 6 7)
(set name "Alice")
(str "Hello, " name) # => "Hello, Alice"
(** 2 64) # => 18446744073709551616
fold special formapplydict/pairs functionsocket/accept to return () instead of an errorstring, variable, define, ...) by short names (str, var, def, ...)and and or to accept more than 2 args= into equal? (aliased to eq? and =) and add a stricter number/equal?+, -, *, /, and % to add, sub, mul, div, and rem (aliased to their previous names)>, <, >=, and <= to gt?, lt?, gte? and lte? (aliased to their previous names)trunc to number/int (aliased to num/int and its previous name)bit/and, bit/or, and bit/xor bit operators (aliased to &, |, and ^)^ exp operator to exp (aliased to **)case functionshell->binary function (aliased to sh->bin)shell->string function (aliased to sh->str)head, tail, length, empty?, and mappush! as the mutating counterpart of push for listsput! as the mutating counterpart of put for dictsdict/keys, and dict/values to dictsset to mutate (aliased to mut)set macro that does either var or mutvar? functionsleep functiondirname, filename, eprint, and error functionsuptime to clk/boot and realtime to clk/epochfloor, ceil, and round functionsfalse nor nil) in conditions of if and whilenth to getempty?, reject, put, push, and host functionsdict type/ instead of . as namespace separatornumber->string (aliased to num->str) with an optional radix argumentThe whole implementation was refactored and the parser was rewritten to use Nom. This allowed the addition of strings to the language and reading from the filesystem.
MOROS Lisp started from Risp and was extended to include the seven primitive operators and the two special forms of John McCarthy's paper "Recursive Functions of Symbolic Expressions and Their Computation by Machine" (1960) and "The Roots of Lisp" (2002) by Paul Graham.