Skip to content

daneelsan/tinylisp

Repository files navigation

tinylisp

Play with tinylisp at: https://daneelsan.github.io/tinylisp/

tinylisp is a minimal Lisp interpreter implemented in Zig, using NaN boxing for efficient memory representation. It supports core Lisp features like atoms, lists, conditionals, arithmetic, and closures, along with an interactive REPL and debugging tools for inspecting the heap, stack, and environment.

TINYLISP

Read my thoughts at https://daneelsan.github.io/2025/03/20/tinylisp.html

Documentation

Atoms

#t (True):

λ #t
#t

ERR (Error):

λ (cdr 42)
ERR

Arithmetic

+ (Addition):

λ (+ 1 2 3 4)
10

- (Subtraction):

λ (- 10 2 3)
5

* (Multiplication):

λ (* 2 3 4)
24

/ (Division):

λ (/ 3.4 4)
0.85

Structural

car:

λ (car '(1 2 3))
1

cdr:

λ (cdr '(1 2 3))
(2 3)

cons:

λ (cons 1 2)
(1 . 2)
λ (cons 1 '(2 3))
(1 2 3)

Quoting and Evaluation

' (Quoting):

λ '(+ 1 2 3)
(+ 1 2 3)

eval (Evaluation):

λ (eval '(+ 1 2 3))
6

Conditionals and Logic

if:

λ (if (< 1 2) 'true 'false)
true

and:

λ (and (< 1 2) (< 2 3))
#t
λ (and (< 2 1) (< 2 3))
()

or:

λ (or (< 1 2) (< 3 2))
#t

not:

λ (not (< 1 2))
()

= (Equality):

λ (= 1.0 1)
#t
λ (= 1.1 1)
()

Lambdas and Closures

lambda:

λ ((lambda (x) (* x x)) 5)
25

define:

λ (define square (lambda (x) (* x x)))
square
λ (square 5)
25
λ (define x 42)
x
λ (+ x x)
84

Debugging and Introspection

echo:

λ (+ (echo (* 3 4) 5))
    >> 12
12

echo-eval:

λ (echo-eval (+ (* 3 4) 5))
    >> ((+ (* 3 4) 5))
    << 17
17

print-env:

λ (print-env)
(
	(echo-eval . «echo-eval»)
	(echo . «echo»)
	(print-env . «print-env»)
	(print-stack . «print-stack»)
	(print-heap . «print-heap»)
	(define . «define»)
	(lambda . «lambda»)
	(if . «if»)
	(and . «and»)
	(or . «or»)
	(not . «not»)
	(= . «=»)
	(> . «>»)
	(< . «<»)
	(/ . «/»)
	(* . «*»)
	(- . «-»)
	(+ . «+»)
	(int . «int»)
	(cdr . «cdr»)
	(car . «car»)
	(cons . «cons»)
	(quote . «quote»)
	(eval . «eval»)
	(#t . #t)
)
()

print-heap:

λ (print-heap)
------------------- HEAP -------------------
|  #  |  address |  symbol                 |
|-----|----------|-------------------------|
|   0 |  0x0000  |  ERR                    |
|   1 |  0x0004  |  #t                     |
|   2 |  0x0007  |  eval                   |
|   3 |  0x000C  |  quote                  |
|   4 |  0x0012  |  cons                   |
|   5 |  0x0017  |  car                    |
|   6 |  0x001B  |  cdr                    |
|   7 |  0x001F  |  int                    |
|   8 |  0x0023  |  +                      |
|   9 |  0x0025  |  -                      |
|  10 |  0x0027  |  *                      |
|  11 |  0x0029  |  /                      |
|  12 |  0x002B  |  <                      |
|  13 |  0x002D  |  >                      |
|  14 |  0x002F  |  =                      |
|  15 |  0x0031  |  not                    |
|  16 |  0x0035  |  or                     |
|  17 |  0x0038  |  and                    |
|  18 |  0x003C  |  if                     |
|  19 |  0x003F  |  lambda                 |
|  20 |  0x0046  |  define                 |
|  21 |  0x004D  |  print-heap             |
|  22 |  0x0058  |  print-stack            |
|  23 |  0x0064  |  print-env              |
|  24 |  0x006E  |  echo                   |
|  25 |  0x0073  |  echo-evaluation        |
|                    ...                   |
--------------------------------------------
()

print-stack:

λ (print-stack)
------------- STACK ------------
|  pointer |   tag  |  ordinal |     Expr
|----------|--------|----------|--------------
|    1024  |  ATOM  |  0x0004  |  #t
|    1023  |  ATOM  |  0x0004  |  #t
|    1022  |  CONS  |    1022  |
|    1021  |  NIL   |       0  |  ()
|    1020  |  ATOM  |  0x0007  |  eval
|    1019  |  PRIM  |       0  |  «eval»
|    1018  |  CONS  |    1018  |
|    1017  |  CONS  |    1020  |
|    1016  |  ATOM  |  0x000C  |  quote
|    1015  |  PRIM  |       1  |  «quote»
|    1014  |  CONS  |    1014  |
|    1013  |  CONS  |    1016  |
|    1012  |  ATOM  |  0x0012  |  cons
|    1011  |  PRIM  |       2  |  «cons»
|    1010  |  CONS  |    1010  |
|    1009  |  CONS  |    1012  |
|    1008  |  ATOM  |  0x0017  |  car
|    1007  |  PRIM  |       3  |  «car»
|    1006  |  CONS  |    1006  |
|    1005  |  CONS  |    1008  |
|    1004  |  ATOM  |  0x001B  |  cdr
|    1003  |  PRIM  |       4  |  «cdr»
|    1002  |  CONS  |    1002  |
|    1001  |  CONS  |    1004  |
|    1000  |  ATOM  |  0x001F  |  int
|     999  |  PRIM  |       5  |  «int»
|     998  |  CONS  |     998  |
|     997  |  CONS  |    1000  |
|     996  |  ATOM  |  0x0023  |  +
|     995  |  PRIM  |       6  |  «+»
|     994  |  CONS  |     994  |
|     993  |  CONS  |     996  |
|     992  |  ATOM  |  0x0025  |  -
|     991  |  PRIM  |       7  |  «-»
|     990  |  CONS  |     990  |
|     989  |  CONS  |     992  |
|     988  |  ATOM  |  0x0027  |  *
|     987  |  PRIM  |       8  |  «*»
|     986  |  CONS  |     986  |
|     985  |  CONS  |     988  |
|     984  |  ATOM  |  0x0029  |  /
|     983  |  PRIM  |       9  |  «/»
|     982  |  CONS  |     982  |
|     981  |  CONS  |     984  |
|     980  |  ATOM  |  0x002B  |  <
|     979  |  PRIM  |      10  |  «<»
|     978  |  CONS  |     978  |
|     977  |  CONS  |     980  |
|     976  |  ATOM  |  0x002D  |  >
|     975  |  PRIM  |      11  |  «>»
|     974  |  CONS  |     974  |
|     973  |  CONS  |     976  |
|     972  |  ATOM  |  0x002F  |  =
|     971  |  PRIM  |      12  |  «=»
|     970  |  CONS  |     970  |
|     969  |  CONS  |     972  |
|     968  |  ATOM  |  0x0031  |  not
|     967  |  PRIM  |      13  |  «not»
|     966  |  CONS  |     966  |
|     965  |  CONS  |     968  |
|     964  |  ATOM  |  0x0035  |  or
|     963  |  PRIM  |      14  |  «or»
|     962  |  CONS  |     962  |
|     961  |  CONS  |     964  |
|     960  |  ATOM  |  0x0038  |  and
|     959  |  PRIM  |      15  |  «and»
|     958  |  CONS  |     958  |
|     957  |  CONS  |     960  |
|     956  |  ATOM  |  0x003C  |  if
|     955  |  PRIM  |      16  |  «if»
|     954  |  CONS  |     954  |
|     953  |  CONS  |     956  |
|     952  |  ATOM  |  0x003F  |  lambda
|     951  |  PRIM  |      17  |  «lambda»
|     950  |  CONS  |     950  |
|     949  |  CONS  |     952  |
|     948  |  ATOM  |  0x0046  |  define
|     947  |  PRIM  |      18  |  «define»
|     946  |  CONS  |     946  |
|     945  |  CONS  |     948  |
|     944  |  ATOM  |  0x004D  |  print-heap
|     943  |  PRIM  |      19  |  «print-heap»
|     942  |  CONS  |     942  |
|     941  |  CONS  |     944  |
|     940  |  ATOM  |  0x0058  |  print-stack
|     939  |  PRIM  |      20  |  «print-stack»
|     938  |  CONS  |     938  |
|     937  |  CONS  |     940  |
|     936  |  ATOM  |  0x0064  |  print-env
|     935  |  PRIM  |      21  |  «print-env»
|     934  |  CONS  |     934  |
|     933  |  CONS  |     936  |
|     932  |  ATOM  |  0x006E  |  echo
|     931  |  PRIM  |      22  |  «echo»
|     930  |  CONS  |     930  |
|     929  |  CONS  |     932  |
|     928  |  ATOM  |  0x0073  |  echo-eval
|     927  |  PRIM  |      23  |  «echo-eval»
|     926  |  CONS  |     926  |
|     925  |  CONS  |     928  |
|     924  |  ATOM  |  0x0058  |  print-stack
|     923  |  NIL   |       0  |  ()
|             ...              |
|------------------------------|
()

Build

Compiled using zig version:

$ zig version
0.14.0

Build the wasm executable using zig build:

$ zig build

$ ls zig-out/bin
tinylisp.wasm

Additionally, build the local executable using zig build local:

$ zig build local

$ ls zig-out/bin
tinylisp      tinylisp.wasm

Or run the local executable directly using zig build run:

$ zig build run
λ 

TODO:

General

  • Compile to .wasm and add a javascript REPL
  • Write a blogpost
  • Expand documentation with more examples

Zig

  • Add tests
  • Improve parsing to handle multiple expressions separed by new lines

Terminal

  • Ctrl+c to delete the current line
  • Multiline inputs don't work well with the history explorer (Up Arrow)
  • Syntax highlighting
  • Drop files
  • Click to copy input/output

Resources

About

A web-based Lisp interpreter with a "terminal" interface

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •