{"id":20333332,"url":"https://github.com/daneelsan/tinylisp","last_synced_at":"2025-10-12T20:48:05.195Z","repository":{"id":133848830,"uuid":"587368415","full_name":"daneelsan/tinylisp","owner":"daneelsan","description":"A web-based Lisp interpreter with a \"terminal\" interface","archived":false,"fork":false,"pushed_at":"2025-03-21T14:53:58.000Z","size":813,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-17T21:35:10.846Z","etag":null,"topics":["html","javascript","lisp","wasm","zig"],"latest_commit_sha":null,"homepage":"https://daneelsan.github.io/tinylisp/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daneelsan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-01-10T15:35:42.000Z","updated_at":"2025-03-21T14:54:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"6df48a52-77cb-4802-b479-5755f9c78042","html_url":"https://github.com/daneelsan/tinylisp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/daneelsan/tinylisp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Ftinylisp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Ftinylisp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Ftinylisp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Ftinylisp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daneelsan","download_url":"https://codeload.github.com/daneelsan/tinylisp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Ftinylisp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279012804,"owners_count":26085190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","javascript","lisp","wasm","zig"],"created_at":"2024-11-14T20:30:50.348Z","updated_at":"2025-10-12T20:48:05.166Z","avatar_url":"https://github.com/daneelsan.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tinylisp\n\nPlay with tinylisp at: https://daneelsan.github.io/tinylisp/\n\ntinylisp 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.\n\n![TINYLISP](./screenshot.png)\n\nRead my thoughts at https://daneelsan.github.io/2025/03/20/tinylisp.html\n\n## Documentation\n\n### Atoms\n\n`#t` (True):\n```lisp\nλ #t\n#t\n```\n\n`ERR` (Error):\n```lisp\nλ (cdr 42)\nERR\n```\n\n### Arithmetic\n\n`+` (Addition):\n```lisp\nλ (+ 1 2 3 4)\n10\n```\n\n`-` (Subtraction):\n```lisp\nλ (- 10 2 3)\n5\n```\n\n`*` (Multiplication):\n```lisp\nλ (* 2 3 4)\n24\n```\n\n`/` (Division):\n```lisp\nλ (/ 3.4 4)\n0.85\n```\n\n### Structural\n\n`car`:\n```lisp\nλ (car '(1 2 3))\n1\n```\n\n`cdr`:\n```lisp\nλ (cdr '(1 2 3))\n(2 3)\n```\n\n`cons`:\n```lisp\nλ (cons 1 2)\n(1 . 2)\n```\n```lisp\nλ (cons 1 '(2 3))\n(1 2 3)\n```\n\n### Quoting and Evaluation\n\n`'` (Quoting):\n```lisp\nλ '(+ 1 2 3)\n(+ 1 2 3)\n```\n\n`eval` (Evaluation):\n```lisp\nλ (eval '(+ 1 2 3))\n6\n```\n\n\n### Conditionals and Logic\n\n`if`:\n```lisp\nλ (if (\u003c 1 2) 'true 'false)\ntrue\n```\n\n`and`:\n```lisp\nλ (and (\u003c 1 2) (\u003c 2 3))\n#t\n```\n```lisp\nλ (and (\u003c 2 1) (\u003c 2 3))\n()\n```\n\n`or`:\n```lisp\nλ (or (\u003c 1 2) (\u003c 3 2))\n#t\n```\n\n`not`:\n```lisp\nλ (not (\u003c 1 2))\n()\n```\n\n`=` (Equality):\n```lisp\nλ (= 1.0 1)\n#t\n```\n```lisp\nλ (= 1.1 1)\n()\n```\n\n### Lambdas and Closures\n\n`lambda`:\n```lisp\nλ ((lambda (x) (* x x)) 5)\n25\n```\n\n`define`:\n```lisp\nλ (define square (lambda (x) (* x x)))\nsquare\n```\n```lisp\nλ (square 5)\n25\n```\n\n```lisp\nλ (define x 42)\nx\n```\n```lisp\nλ (+ x x)\n84\n```\n\n### Debugging and Introspection\n\n`echo`:\n```lisp\nλ (+ (echo (* 3 4) 5))\n    \u003e\u003e 12\n12\n```\n\n`echo-eval`:\n```lisp\nλ (echo-eval (+ (* 3 4) 5))\n    \u003e\u003e ((+ (* 3 4) 5))\n    \u003c\u003c 17\n17\n```\n\n`print-env`:\n```lisp\nλ (print-env)\n(\n\t(echo-eval . «echo-eval»)\n\t(echo . «echo»)\n\t(print-env . «print-env»)\n\t(print-stack . «print-stack»)\n\t(print-heap . «print-heap»)\n\t(define . «define»)\n\t(lambda . «lambda»)\n\t(if . «if»)\n\t(and . «and»)\n\t(or . «or»)\n\t(not . «not»)\n\t(= . «=»)\n\t(\u003e . «\u003e»)\n\t(\u003c . «\u003c»)\n\t(/ . «/»)\n\t(* . «*»)\n\t(- . «-»)\n\t(+ . «+»)\n\t(int . «int»)\n\t(cdr . «cdr»)\n\t(car . «car»)\n\t(cons . «cons»)\n\t(quote . «quote»)\n\t(eval . «eval»)\n\t(#t . #t)\n)\n()\n```\n\n`print-heap`:\n```lisp\nλ (print-heap)\n------------------- HEAP -------------------\n|  #  |  address |  symbol                 |\n|-----|----------|-------------------------|\n|   0 |  0x0000  |  ERR                    |\n|   1 |  0x0004  |  #t                     |\n|   2 |  0x0007  |  eval                   |\n|   3 |  0x000C  |  quote                  |\n|   4 |  0x0012  |  cons                   |\n|   5 |  0x0017  |  car                    |\n|   6 |  0x001B  |  cdr                    |\n|   7 |  0x001F  |  int                    |\n|   8 |  0x0023  |  +                      |\n|   9 |  0x0025  |  -                      |\n|  10 |  0x0027  |  *                      |\n|  11 |  0x0029  |  /                      |\n|  12 |  0x002B  |  \u003c                      |\n|  13 |  0x002D  |  \u003e                      |\n|  14 |  0x002F  |  =                      |\n|  15 |  0x0031  |  not                    |\n|  16 |  0x0035  |  or                     |\n|  17 |  0x0038  |  and                    |\n|  18 |  0x003C  |  if                     |\n|  19 |  0x003F  |  lambda                 |\n|  20 |  0x0046  |  define                 |\n|  21 |  0x004D  |  print-heap             |\n|  22 |  0x0058  |  print-stack            |\n|  23 |  0x0064  |  print-env              |\n|  24 |  0x006E  |  echo                   |\n|  25 |  0x0073  |  echo-evaluation        |\n|                    ...                   |\n--------------------------------------------\n()\n```\n\n`print-stack`:\n```lisp\nλ (print-stack)\n------------- STACK ------------\n|  pointer |   tag  |  ordinal |     Expr\n|----------|--------|----------|--------------\n|    1024  |  ATOM  |  0x0004  |  #t\n|    1023  |  ATOM  |  0x0004  |  #t\n|    1022  |  CONS  |    1022  |\n|    1021  |  NIL   |       0  |  ()\n|    1020  |  ATOM  |  0x0007  |  eval\n|    1019  |  PRIM  |       0  |  «eval»\n|    1018  |  CONS  |    1018  |\n|    1017  |  CONS  |    1020  |\n|    1016  |  ATOM  |  0x000C  |  quote\n|    1015  |  PRIM  |       1  |  «quote»\n|    1014  |  CONS  |    1014  |\n|    1013  |  CONS  |    1016  |\n|    1012  |  ATOM  |  0x0012  |  cons\n|    1011  |  PRIM  |       2  |  «cons»\n|    1010  |  CONS  |    1010  |\n|    1009  |  CONS  |    1012  |\n|    1008  |  ATOM  |  0x0017  |  car\n|    1007  |  PRIM  |       3  |  «car»\n|    1006  |  CONS  |    1006  |\n|    1005  |  CONS  |    1008  |\n|    1004  |  ATOM  |  0x001B  |  cdr\n|    1003  |  PRIM  |       4  |  «cdr»\n|    1002  |  CONS  |    1002  |\n|    1001  |  CONS  |    1004  |\n|    1000  |  ATOM  |  0x001F  |  int\n|     999  |  PRIM  |       5  |  «int»\n|     998  |  CONS  |     998  |\n|     997  |  CONS  |    1000  |\n|     996  |  ATOM  |  0x0023  |  +\n|     995  |  PRIM  |       6  |  «+»\n|     994  |  CONS  |     994  |\n|     993  |  CONS  |     996  |\n|     992  |  ATOM  |  0x0025  |  -\n|     991  |  PRIM  |       7  |  «-»\n|     990  |  CONS  |     990  |\n|     989  |  CONS  |     992  |\n|     988  |  ATOM  |  0x0027  |  *\n|     987  |  PRIM  |       8  |  «*»\n|     986  |  CONS  |     986  |\n|     985  |  CONS  |     988  |\n|     984  |  ATOM  |  0x0029  |  /\n|     983  |  PRIM  |       9  |  «/»\n|     982  |  CONS  |     982  |\n|     981  |  CONS  |     984  |\n|     980  |  ATOM  |  0x002B  |  \u003c\n|     979  |  PRIM  |      10  |  «\u003c»\n|     978  |  CONS  |     978  |\n|     977  |  CONS  |     980  |\n|     976  |  ATOM  |  0x002D  |  \u003e\n|     975  |  PRIM  |      11  |  «\u003e»\n|     974  |  CONS  |     974  |\n|     973  |  CONS  |     976  |\n|     972  |  ATOM  |  0x002F  |  =\n|     971  |  PRIM  |      12  |  «=»\n|     970  |  CONS  |     970  |\n|     969  |  CONS  |     972  |\n|     968  |  ATOM  |  0x0031  |  not\n|     967  |  PRIM  |      13  |  «not»\n|     966  |  CONS  |     966  |\n|     965  |  CONS  |     968  |\n|     964  |  ATOM  |  0x0035  |  or\n|     963  |  PRIM  |      14  |  «or»\n|     962  |  CONS  |     962  |\n|     961  |  CONS  |     964  |\n|     960  |  ATOM  |  0x0038  |  and\n|     959  |  PRIM  |      15  |  «and»\n|     958  |  CONS  |     958  |\n|     957  |  CONS  |     960  |\n|     956  |  ATOM  |  0x003C  |  if\n|     955  |  PRIM  |      16  |  «if»\n|     954  |  CONS  |     954  |\n|     953  |  CONS  |     956  |\n|     952  |  ATOM  |  0x003F  |  lambda\n|     951  |  PRIM  |      17  |  «lambda»\n|     950  |  CONS  |     950  |\n|     949  |  CONS  |     952  |\n|     948  |  ATOM  |  0x0046  |  define\n|     947  |  PRIM  |      18  |  «define»\n|     946  |  CONS  |     946  |\n|     945  |  CONS  |     948  |\n|     944  |  ATOM  |  0x004D  |  print-heap\n|     943  |  PRIM  |      19  |  «print-heap»\n|     942  |  CONS  |     942  |\n|     941  |  CONS  |     944  |\n|     940  |  ATOM  |  0x0058  |  print-stack\n|     939  |  PRIM  |      20  |  «print-stack»\n|     938  |  CONS  |     938  |\n|     937  |  CONS  |     940  |\n|     936  |  ATOM  |  0x0064  |  print-env\n|     935  |  PRIM  |      21  |  «print-env»\n|     934  |  CONS  |     934  |\n|     933  |  CONS  |     936  |\n|     932  |  ATOM  |  0x006E  |  echo\n|     931  |  PRIM  |      22  |  «echo»\n|     930  |  CONS  |     930  |\n|     929  |  CONS  |     932  |\n|     928  |  ATOM  |  0x0073  |  echo-eval\n|     927  |  PRIM  |      23  |  «echo-eval»\n|     926  |  CONS  |     926  |\n|     925  |  CONS  |     928  |\n|     924  |  ATOM  |  0x0058  |  print-stack\n|     923  |  NIL   |       0  |  ()\n|             ...              |\n|------------------------------|\n()\n```\n\n## Build\n\nCompiled using zig version:\n```shell\n$ zig version\n0.14.0\n```\n\nBuild the wasm executable using `zig build`:\n```shell\n$ zig build\n\n$ ls zig-out/bin\ntinylisp.wasm\n```\n\nAdditionally, build the local executable using `zig build local`:\n```shell\n$ zig build local\n\n$ ls zig-out/bin\ntinylisp      tinylisp.wasm\n```\n\nOr run the local executable directly using `zig build run`:\n```shell\n$ zig build run\nλ \n```\n\n## TODO:\n\n### General\n- [X] Compile to .wasm and add a javascript REPL\n- [X] Write a blogpost\n- [ ] Expand documentation with more examples\n\n### Zig\n- [ ] Add tests\n- [ ] Improve parsing to handle multiple expressions separed by new lines\n\n### Terminal\n- [X] `Ctrl+c` to delete the current line\n- [ ] Multiline inputs don't work well with the history explorer (`Up Arrow`)\n- [ ] Syntax highlighting\n- [ ] Drop files\n- [ ] Click to copy input/output\n\n## Resources\n- [Lisp in 99 lines of C and how to write one yourself - Robert-van-Engelen](https://github.com/Robert-van-Engelen/tinylisp#lisp-in-99-lines-of-c-and-how-to-write-one-yourself)\n\n- [Passing strings to and from WebAssembly using C](https://log.schemescape.com/posts/webassembly/passing-strings-to-c.html)\n\n- [TINYLISP: A Minimal Lisp Interpreter in Zig and WebAssembly](https://daneelsan.github.io/2025/03/20/tinylisp.html)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneelsan%2Ftinylisp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaneelsan%2Ftinylisp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneelsan%2Ftinylisp/lists"}