https://github.com/eignnx/misp
An M-expression-based Lisp descendant implemented on top of Python3.6 and SLY
https://github.com/eignnx/misp
lisp-interpreter m-expression python3 scheme-interpreter
Last synced: 9 months ago
JSON representation
An M-expression-based Lisp descendant implemented on top of Python3.6 and SLY
- Host: GitHub
- URL: https://github.com/eignnx/misp
- Owner: eignnx
- Created: 2018-08-15T00:08:03.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-11-10T03:49:26.000Z (about 7 years ago)
- Last Synced: 2025-01-21T17:35:45.475Z (11 months ago)
- Topics: lisp-interpreter, m-expression, python3, scheme-interpreter
- Language: Python
- Size: 18.6 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# misp
An M-expression-based Lisp descendant implemented on top of Python3.6 and SLY
## Code Example
Misp supports both the Lisp-like S-expression syntax as well as what I'm calling "M-expression syntax":
| M-expression Syntax | S-expression Syntax |
| :---------------------: | :---------------------: |
| `+[1 2 3]` | `(+ 1 2 3)` |
| `Def[x 100]` | `(Def x 100)` |
| `side-effects-please[]` | `(side-effects-please)` |
The following is an implementation of a function that recursively generates the n-th fibnonacci number:
```mathematica
Defn[fib[n]
If[Or[=[n 0] =[n 1]]
n
+[ fib[-[n 1]] fib[-[n 2]] ]
]
]
fib[20]
```
The program returns `6765`.
## Postfix Notation
An expression of the form
```mathematica
f[a b c d]
```
can also be written in postfix form by putting the function at the end of the list and separating it from the arguments with the double-pipe (`||`) delimiter:
```mathematica
[a b c d || f]
```
As an example, the following two expressions both return `10`:
```mathematica
+[1 2 3 4]
[1 2 3 4 || +]
```
## Special Values
* **Truthiness**
* `:F`
* A keyword representing the boolean false value
* `Nil`
* A symbol bound to the empty list
* Is also considered false
* `:T`
* A keyword representing the boolean true value
* Not uniquely "true" since anything that is not `:F` or `Nil` is considered true.
## Built-in Functions
* `+`, `-`, `*`,`/`
* Arithmetic operators. Each can take a variable number of arguments
* `=[x y z ...]`
* Returns `:T` if all arguments are equal
* `Head[list]`
* Like `car`. Returns the first element of the list argument
* `Body[list]`
* Like `cdr`. Returns a list of all but the first elements in a list
* `Fn[{x y z ...} body]`
* Replaces Lisp's `lambda`.
* Accepts a list of formal parameters, and a body.
* `Fn[{x} *[x x]][12]` returns `144`
* `Def[symbol value]`
* Declares and assigns to `symbol` the value of the expression `value`
* `Def[x 100]` binds the symbol `x` to the number `100` in the current environment (scope)
* Returns the `value`
* `Defn[f[x y z ...] body]`
* Equivalent to `Def[f Fn[{x y z ...} body]]`
* Returns the procedure that gets assigned to `f`
* `Set![x v]`
* Sets the previously-defined symbol `x` to the value of `v`
* Returns `v`
* `Do[e1 e2 e3 ... en]`
* Evaluates `e1`, `e2`, ... `en` in order
* Returns the value of `en`
* The following program returns `1` after setting `x` to `3` and `y` to `1`:
```mathematica
Do[
Def[x 1]
Def[y x]
Set![x 3]
y
]
```
* `Let[{x v1 y v2 ...} body]`
* Binds `x` to `v1`, `y` to `v2`, etc., then evaluates `body`
* The variable bindings are only valid during the execution of `body`
* Equivalent to the immediately invoked lambda expression: `Fn[{x y ...} body][v1 v2 ...]`
* `Eval[expr]`
* Evaluates a quoted expression
* `Eval[{+ 1 2 3}]` and `Eval['(+ 1 2 3)]` both return `6`
* `Apply[f {arg1 arg2 arg3 ...}]`
* Applies the callable function bound to `f` upon the argument list
* Eqivalent to `f[arg1 arg2 arg3 ...]`
* `Quote[expression]` or `'expression`
* Returns `expression` , unevaluated, as an abstract syntax tree
* `List[v1 v2 v3 ...]` or `{v1 v2 v3 ...}`
* Returns the abstract syntax tree representing a list which contains the specified values
* **Not** the same as `'(v1 v2 v3 ...)` or `Quote[(v1 v2 v3)]` since `List` evaluates each of its arguments `vi` *before* putting putting them in a quoted list
* `Quasiquote[expression]` or `~expression`
* Returns `expression` with every instance of `Unquote[subexpression]` replaced with the value of `subexpression`
* Note: A quasiquoted expression -- in general -- evaluates to an abstract syntax tree
* `Unquote[expression]` or `$expression`
* Cannot be evaluated outside of a quasiquote expression
* When inside of a quasiquote expression, `Unquote[expression]` will be replaced with the value `expression` evaluates to
* `If[condition e1 e2]`
* Returns the value of `e1` if `condition` is "truthy" (neither `:F` nor `Nil`), otherwise, returns the value of `e2`
* `Print[v1 v2 v3 ... vn]`
* Prints `v1`, `v2`, etc to stdout.
* Returns the value of `vn`