A Lisp to JavaScript Compiler in 100 Lines

JavaScript occassionally gets some air time on LtU and after the most recent discussion of using CSS selectors for hooking up event handlers, I decided it was time to pick up JS. It's immediately quite clear that JS and Lisp have strong ties at the semantics level, so as a first project I thought it would be fun to code a small Lisp to JS compiler, in JS.

It ended up being really small--about 100 lines of code for the core of the compiler. Not quite competitive with a SICP-style metacircular interpreter in lines of code but not too bad either. I thought you guys might get a kick out of it:

http://www.cryptopunk.com/?p=8

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Cool

Very nice, but could you please show the generated code as well? I mean, that is kind of the point of a compiler. If you just want to evalutate the lisp code, you could have just interpreted the code directly instead of building javascript code.

Show the generated code

Just change the

(print (fact 4))

to

(print fact)

How about Scheme?

...and adding TCO and call/cc? :-)
(define bad (lambda (x) (x x)))
(bad bad)

nothing new to js


bad = function(x) {
   x(x);
}
bad(bad);

Ah crap. I'm actually learning this stuff. :(

kind of neat but not really lisp

this is pretty cool, but it's more a lispish syntax on top of javascript. For example, no lisp I know of will allow (+ 4 "4") as being valid, but javascript (and your lisp) will happily return "44". (btw, this "feature" of javascript has bitten me in the past).
Other issues: '(x y) doesn't work as in lisp, and neither does eval. I'd say quote, symbols, code as lists, and eval are essential attributes of lisp. So, sorry, I just wouldn't call this a lisp.

Well...

Right now it's a very "naked" source-to-source translation with no attempts made at syntax checking or the like. Syntax checking is easy enough to add. To handle your above example correctly (adding integers and strings), it would suffice to wrap all Lisp values as "boxed" JavaScript values and implement their operators in a way compatible with the usual Lisp semantics. But I see all this as fairly routine and pedestrian--the main point of the exercise was to see how easy it was to write the "core" of the compiler.

Neat! Also check out ParenScript

I like. It's a neat hack, though I think you'll agree not really practical. ParenScript is a more geared for real use. I think it fixes JavaScripts scoping problems, which is my number one complaint about the language.

What scoping problems?

I couldn't find anything mentioned on the ParenScript page.

Scoping Issues

Dave explains the scoping issues in his post "Javascript Surprises" you can find at his blog

See also: The Little JavaScri