https://github.com/vimpunk/ill
:heart: I LIKE LISPS :heart: my toy LISP dialect
https://github.com/vimpunk/ill
Last synced: about 1 year ago
JSON representation
:heart: I LIKE LISPS :heart: my toy LISP dialect
- Host: GitHub
- URL: https://github.com/vimpunk/ill
- Owner: vimpunk
- Created: 2018-06-21T21:25:45.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-07-10T23:20:56.000Z (almost 8 years ago)
- Last Synced: 2025-02-16T16:58:06.300Z (over 1 year ago)
- Language: Python
- Homepage:
- Size: 49.8 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ILL - I LIKE LISPS
This is a small toy LISP dialect I've written for purely (self) educational purposes. It's not meant to be a language used
in the wild--heck, it's written in Python! An interpreter inside an interpreter, performance must be pretty abysmal!
I'd lie if I claimed that I'm an expert at LISPS and its numerous dialects, so it's probably safest for me the say that
ILL is not a real LISP (hence the name). It currently doesn't even support macros (and perhaps it never will as I never really
understood or used them (in that order)), tail call optimization, nor a whole host of builtin functions! But hey, it's
a work-in-progress.
## Whirlwind tour of the language
The basics are just as you'd expect:
```
(+ 1 (* 2 3))
```
Types:
- bool: `true` or `false`
- number: `2` or `2.02`
- string: `"a utf8 string"`
- vector: `[1 2 3 "four"]`
- map: `{"key": "value"}`
Variable binding:
```
(let greeting "hello world")
(let name (/ 8 2))
(let vec [1 23 (+ 2 34) (+ "hello" "world")])
(let map {"key1":1 2:2 (+ 2 3):3})
```
Conditional branching:
```
(if (= 2 2 2)
2
"not 2")
```
Function definition:
```
(fn fib (n)
(if (<= n 2)
1
(fib (- n 1) (- n 2))))
(fn greeter () "hello!")
(fn adder (a b) (+ a b))
```
You can loop with recursion, but since tail call optimization is not yet implemented (and I prefer explicit loop
constructs anyway), a while keyword is provided:
```
(let i 0)
(while (< i 10)
(do (print i)
(let i (+ i 1))))
```
Looping through collection elements is also supported:
```
(let list [1 2 3 4 5])
(each (list element)
(print element))
```
or if the iterable is a map:
```
(let answers {
"The Answer to the Ultimate Question of Life, the Universe, and Everything": 42})
(each (answers key val)
(print key ": " val))
```
You can also use multiple statements within if branches and function bodies with the `do` function, which evaluates all
its arguments and returns the last one:
```
(fn function-name (param1 param2)
(do (let tmp param1)
(+ tmp param1)))
```
Since everything is an expression and thus evaluates to a value, you can use function definitions within expressions
as anonymus functions, like so:
```
((fn adder (a b) (+ a b)) 3 4)
```
## Running it
Just execute `./ill/repl.py` for the repl and `./ill/ill.py $filename` to run source code. Yes, it's not very
ergonomic. Yet.
## Useful things that have been built with ILL: