Tony Onodi

A Lisp Interpreter in JavaScript

4th November 2015

View Source on GitHub.

What can it do?

Have a go at writing some basic programs, one line at a time. You can do arithmetic:

(+ 1 1)

nest expressions:

(* 2 (+ 5 5))

branch conditionally

(if (= 1 1) true false)

save variables:

(def x 5)

and even define functions that call themselves recursively!:

(def factorial (fn (n) (if (= n 0) 1 (* n (factorial (- n 1))))))

To call that last one try

(factorial 5)

Where did this come from?

This was originally meant to be a JS1K entry (hence the now outdated name). But I quickly decided it was a pretty poor fit for the competition - being greeted with a blinking REPL cursor when you open the page isn't nearly whizz-bang enough - and began writing a raytracer instead. And failed at that too.

Prior to that I'd been wanting to write a Lisp interpreter since reading Peter Norvig's essay on writing one in Python and Michael Nielsen's sort-of follow up essay on Lisp as the Maxwell's equations of software.

I say I read them, I actually started reading them both and promptly stopped so I could try to work out how to write one for myself... Then I went back to Peter Norvig's essay to peak at the parser and implement a copy in JavaScript (parsers are hard).

Anyway, the rest is my best guess (and therefore questionable implementation) of how a Lisp interpreter should work. The project structure is a real mess at the moment and you can only feed it commands one line at a time... and if you try to do them over more than one line it might crash your browser.

Anyway, enjoy!

To Do List

This to do list could easily be infinite but these are a few things I see on the horizon.

  • Full write up on how this works.
  • A proper stack.
  • Automated builds with ES6 compilation.
  • Support for closures.
  • Strings!
  • Error handling.
  • Tail call optimisation.
  • Implementation of cons/car/cdr.
  • Some nice (ideally immutable) data structures. One day...