Tuesday, May 13, 2008

Factor + Lisp = It Doesn't Get Much Better

So, I've started work on my first real Factor project: Writing a implementation of Lisp in Factor (which is referred to as "extra/lisp", as that is where it lives in the Factor repo). I'm having some weird problems with local variables and transformations, but it's going pretty well, and I am having tons of fun with it.

So, how does it work?

The structure of the Lisp compiler is fairly simple: First, it parses the Lisp code from a string into a Factor data structure using Chris Double's (a.k.a. doublec) awesome peg.ebnf, which allows you to just write out the EBNF for your grammar. The really neat thing about this is that, rather than your typical parser generator, this creates a "packrat" parser, which supports both direct and indirect left recursion. Very cool!

After the string is parsed, I then run a simple recursive transform on the code. Such is the beauty of Lisp, that I only need about five special cases (currently lambda, quote, if,begin, and cond - and yes, I know I don't need both cond and if, but it's easier this way). In general, the transformation turns (foo bar baz) into [ bar baz foo ] , albeit with some funny tricks to deal with variadic functions.

Current Status

Well, right now, it's failing when calling lambdas. Apparently, in the lambda-quotation [| x | x ], the two x's are not eq?. Not quite sure why, but I'm working on it. Once I get that working, all I really have left to do is do macros (which shouldn't be too hard, as I can just piggy-back off Factor's MACRO: (or so I hope)), and then I can start bootstraping it in Lisp. Should be fun!


By the way, if you're interested, you can take a look at what I've done so far at git://factorcode.org/git/jamesnvc, or take a look in the main Factor repo (under "extra/lisp") as Slava pulls it in.