đŸ Archived View for dcreager.net âș concatenative âș compiling-quotations.gmi captured on 2023-11-04 at 11:36:15. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
2023-10-13
@max22- asked on Mastodon:
is it possible to compile quotations to assembly the same way as simple functions on this slide (at 35 minutes) ?
âCompiling stack programsâ slide from
my Strange Loop talk on concatenative programming
The short answer is âyes, but not as easilyâ. There are a few wrinkles you have to consider:
First off, in the talk, I mention that you can choose to break your program into pieces âanywhere you wantâ, but that's a bit of a white lie. When you have quotations, you have to choose whether program concatenation needs to be aware of syntax. That is, are you allowed to choose a cut-point in the middle of a quotation? Or does each quotation need to be âatomicâ â something that you can't break into pieces? The easier choice is that you can't break apart quotations when choosing your cut-points.
The next wrinkle is that you're going to have to compile the body of each quotation into a separate buffer, and what you'd push onto the stack is the location in memory of the resulting assembled code. So you'd generate a unique label to put at the start of the quotation's assembly buffer, and back in the âmainâ code, you'd add some assembly to push that label onto the stack:
mov %ax, LABEL push %ax
Then you have to figure out what assembly to generate for âapplyâ. In my talk, when I was stepping through executing a stack program âby handâ, we applied a quotation by moving its contents âback to the rightâ. But that won't work with the assembly programs that we've generated â there is no (easy, safe, worth the hassle) way to dynamically move the assembled machine code into place where our current instruction pointer is. Instead, you'd lean on the analogy that applying quotations is just like invoking functions, and do the same thing that you'd do in a compiled/assembled program for function invocation. You'd assume top-of-stack is a quotation â that is, the location in memory of the quotation's compiled code. And the assembly for âapplyâ would be
pop %ax jmp %ax
But now you have to figure out how to return to the main instruction stream when the quotation's code is done! That sounds an awful lot like a return stack â i.e., we should use âCALLâ instead of âJMPâ, so that we can use âRETâ to return back. Unfortunately, it's not quite as simple as just doing that, because it means you need *two* stacks: the value stack we've been discussing all along, and a new âcall stackâ to track the stack of quotation applications that we're in the middle of. We started with the idea of using the x86 stack to model the value stack, and we can't easily use it to model both the value and call stacks. It's a more natural fit for the call stack, so we'd have to put the value stack somewhere else in memory, track it with a different register than â%spâ, and update the assembly snippets for all of the instructions to use this new location/snippet for the value stack.
And at that point, yes, you'll have found a way to compile quotations too, in parallel.