Yay! I've now got my Scheme Interpreter running on an abstract machine implemented in perl, doing tail optimization with partial continuations and stuff. It's, um, scary. And it's one more step closer to a parrot implementation (or a scheme to parrot compiler, whichever comes first).
But right now I'm not sure which scares me more. The code, the fact that I understand it, or the fact that I've not had to change any of my top level environment bindings to get it working. I 'just' subclassed my 'generic' Scheme::SchemeEvaluator and redid it as an abstract machine. I've had to add a couple of methods to my datatypes, but nothing dramatic...
It is, of course, dog slow. Maintaining your own call stacks etc and doing perl OO dispatch is never going to make for blinding speed. But hey, Parrot will solve that. He stated, blithely.
I'm really enjoying reading about this. I tried to write a scheme interpreter in perl three years ago during my programming languages concepts class, but got hung up on the parsing. (Hadn't taken a compilers course, yet.)
Congrats, and keep coding!
At least, I *think* it should work. Unless there's two different stacks, but that would be nasty.# tail call:
branch foo_tail
# none tail call
bsr foo
foo: restore I1 # Gets the return address off the stack and saves it on the cont register
foo_tail:
...
save I1
ret # returns to appropriate partial continuation
Re:Parsing's easy
pdcawley on 2002-04-19T06:09:32
Ghod, I'm being dim. Of course there's two different kinds of stack. Hoom...Re:Parsing's easy
Elian on 2002-04-25T14:59:35
Three kinds, actually. (Well, OK, either six or seven. Or four, depending on how you're counting) There's the call stack, the user stack, and the 4 register stacks. (You may or may not count them separately)
We're probably going to get a generic integer stack soonish, for regexes. (Faster than the generic stack by rather a bit, and that's important for regexes)
Re:tail optimisation
pdcawley on 2002-04-25T13:35:14
Ooh... I'd not thought of that. I really don't know, but it might be conceptually neater. I'm not entirely happy about the current trick of unwinding the stack using redo, it works but if feels, well, naughty. Replacing $self->method(...) with die Call->new('method') or something isn't exactly a 'nice' thing to do either.
I think I'm going to have to release the code with a TODO list sketching out an 'ExeptionMachine' implementation and welcome patches. I really want to be concentrating on implementing the whole thing in parrot...Re:tail optimisation
Matts on 2002-04-25T14:57:25
Well you can wrap the die() inside a method. And you probably also need to do my "unblessed" exceptions trick in a __DIE__ handler.