Sunday, August 31, 2008

Hopefully not much more on extra/lisp

I've been working on it for far too long, but I think I'm almost done the Factor side of extra/lisp. I've done a little more work since I last wrote and now the only thing remaining is, unfortunately, something of an open problem; Namely, the propagation of locals into literals (more specifically, cond within lambdas).

So, what have I done?

I've only really made three changes since I last wrote, which are as follows:

  1. Allowing multiple forms in the body of an expression.

    This was something that was really just due to my carelessness in the first place: When I wrote the s-exp to quotation translator, it would only take the first form. This first manifested itself as a problem when trying to write begin as a macro.

  2. Begin as a special form

    I originally had begin as a macro, but soon realized that this was untenable, since the stack needed to be cleared after each form: That is, we want (begin 1 2 3) to leave just a three on the stack, but if done as a macro, the stack would look like 1 2 3. So, begin is now a special form, which essentially just wraps with-datastack and a drop around each form in the begin.

  3. Changing macro-expansion time

    Oh boy. This one is embarrassing. Originally macros were expanded as the forms were being called. Given that macros being called at compile-, not run-time is really the whole point of macros, I have no excuse. But anyway, it's been fixed now.

So, what's left?

At this point, the only thing not working satisfactorily is locals and cond. Since I've defined if in terms of cond, this means that things like ((lambda (x) (if x ...))...) won't work, because the x isn't properly visible in the if. I'm not entirely sure how I'm going to fix this...but I'll figure it out soon!

Postscritpt: I guess I'm on Planet Factor now? Thanks Slava!

Update: As per Slava's comment, locals in cond now work in git, so everything is working now! Yay!

1 comment:

Slava Pestov said...

James, with the latest sources in git, this works:

:: foo ( a -- ) { { [ a 0 < ] [ "negative" ] } { [ a 0 > ] [ "positive" ] } } cond ;

So assuming you're not doing anything funny, the code lisp generates should work too.