1
5
mirror of https://github.com/vinc/moros.git synced 2024-06-18 06:57:10 +00:00
moros/doc/lisp.md
Vincent Ollivier ab9b488a49
Update lisp doc and examples (#428)
* Update documentation

* Add macro?

* Rewrite and and or with macros

* Move string-join

* Update built-in autocompletion

* Use define instead of def in core and examples

* Add changelog to doc

* Move aliases to lib

* Add let macro

* Add caar cadr cdar cddr functions

* Add fixme

* Fix let macro
2022-11-01 11:02:50 +01:00

177 lines
4.1 KiB
Markdown

# MOROS Lisp
A minimalist Lisp interpreter is available in MOROS to extend the capabilities
of the Shell.
MOROS Lisp is a Lisp-1 dialect inspired by Scheme and Clojure.
## Changelog
### 0.1.0 (2021-07-21)
MOROS Lisp started from [Risp](https://github.com/stopachka/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.
### 0.2.0 (2021-12-04)
The whole implementation was refactored and the parser was rewritten to use
[Nom](https://github.com/Geal/nom). This allowed the addition of strings to the
language and reading from the filesystem.
### 0.3.0 (2022-12-12)
Rewrite the evaluation code, add new functions and a core library.
### 0.3.1 (2022-06-06)
Rewrite parts of the code and add new functions and examples.
### 0.3.2 (2022-07-02)
- Add new functions
### 0.3.2 (2022-08-25)
- Add new functions
### 0.4.0 (2022-08-25)
- Rewrite a lot of the code
- Add integer and big integer support
- Add tail call optimization (TCO)
- Add macro support
## Overview
### Types
- Basics: `bool`, `list`, `symbol`, `string`
- Numbers: `float`, `int`, `bigint`
### Built-in Operators
- `quote` (with the `'` syntax)
- `quasiquote` (with the `` ` ``)
- `unquote` (with the `,` syntax)
- `unquote-splicing` (with the `,@` syntax)
- `atom` (aliased to `atom?`)
- `eq` (aliased to `eq?`)
- `car` (aliased to `first`)
- `cdr` (aliased to `rest`)
- `cons`
- `if`
- `cond`
- `while`
- `set`
- `define` (aliased to `def` and `label`)
- `function` (aliased to `fun` and `lambda`)
- `macro` (aliased to `mac`)
- `define-function` (aliased to `def-fun`)
- `define-macro` (aliased to `def-mac`)
- `apply`
- `eval`
- `expand`
- `do` (aliased to `begin` and `progn`)
- `load`
### Primitive Operators
- `append`
- `type`
- `string`
- `string->number`
- `string->bytes` and `bytes->string`
- `number->bytes` and `bytes->number`
- `regex-find`
- `system`
- Arithmetic operations: `+`, `-`, `*`, `/`, `%`, `^`
- Trigonometric functions: `acos`, `asin`, `atan`, `cos`, `sin`, `tan`
- Comparisons: `>`, `<`, `>=`, `<=`, `=`
- String operations: `lines`
- File IO: `read-file`, `read-file-bytes`, `write-file-bytes`, `append-file-bytes`
### Core Library
- `nil`, `nil?`, `eq?`
- `atom?`, `string?`, `boolean?`, `symbol?`, `number?`, `list?`, `function?`, `macro?`
- `caar`, `cadr`, `cdar`, `cddr`, `first`, `second`, `third`, `rest`
- `map`, `reduce`, `reverse`, `range`
- `let`
- `string-join`
- `read-line`, `read-char`
- `print`, `println`
- `write-file`, `append-file`
- `uptime`, `realtime`
- `regex-match?`
- Boolean operations: `not`, `and`, `or`
## Usage
The interpreter can be invoked from the shell:
```
> lisp
MOROS Lisp v0.4.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:
```lisp
(load "/lib/lisp/core.lsp")
(define (fibonacci n)
(if (< n 2) n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(println
(if (nil? args) "Usage: fibonacci <num>"
(fibonacci (string->number (car args)))))
```
Would produce the following output:
```
> lisp /tmp/lisp/fibonacci.lsp 20
6755
```
## Examples
```lisp
(load "/lib/lisp/core.lsp")
(define foo 42) # Variable definition
(define double (fun (x) (* x 2))) # Function definition
(define (double x) (* x 2)) # Shortcut
(double foo) # => 84
(define (map f ls)
(if (nil? ls) nil
(cons
(f (first ls))
(map f (rest ls)))))
(define bar (quote (1 2 3)))
(define bar '(1 2 3)) # Shortcut
(map double bar) # => (2 4 6)
(map (fun (x) (+ x 1)) '(4 5 6)) # => (5 6 7)
(set foo 0) # Variable assignment
(= foo 10) # => false
(while (< foo 10)
(set foo (+ foo 1)))
(= foo 10) # => true
(define name "Alice")
(string "Hello, " name) # => "Hello, Alice"
(^ 2 128) # => 340282366920938463463374607431768211456
```