## 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.