I’ve been messing around with a toy implementation (in Python) of a
variant of the old PostScript language that I call “GXScript”.
One of the features I added to it is continuations, à la Scheme and other Lisps. I added an operator called “cexec”, which invokes a procedure you pass to it but first pushes on the stack a continuation that, when
invoked, resumes execution from just after the cexec call.
Such continuations can be used in the all usual ways, for example to
implement looping:
{
/Count 5 ldef
/Top null ldef
{/Top exch lstore} cexec
{
/Break exch ldef
Count =
/Count Count 1 sub lstore
Count 0 eq {Break} if
Top
}
cexec
}
exec
Output:
5
4
3
2
1
Note that care has to be taken that no extra code inadvertently
occurs after the first cexec, since that would also be reexecuted when “Top” is invoked. For example, the lines
/Top null ldef
{/Top exch lstore} cexec
cannot be written in a form such as
/Top {} cexec exch ldef
since you do not want the “exch ldef” to be reexecuted after “Top” has been defined. Hence there is some slightly convoluted code to ensure
that 1) the “Top” variable is initially defined in the right block
scope, and 2) it gets assigned a continuation pointing at the right
point in the code.
Of course it would be fiddly to have to write this sort of thing out
every time you wanted to use continuations to implement a loop. Here
is a wrapper routine that is invoked with a procedure as argument:
that procedure is repeatedly invoked, each time passing it a
continuation that it can use to exit the loop.
/DoLoop
{
/Proc exch ldef
/Top null ldef
{/Top exch lstore} cexec
{Proc Top} cexec
}
ddef
DoLoop will take your loop-body procedure as argument, and execute it repeatedly, each time pushing a continuation that can be used to exit the
loop, until you invoke that continuation. Example use:
/Count 5 ddef
{
/Break exch ldef # always pop arg even if not used
Count =
/Count Count 1 sub lstore
Count 0 eq {Break} if
}
DoLoop
The output is the same as before.
Note that DoLoop is defined as a procedure, not a macro. PostScript never
had macros, and I’m not sure I need to add them to GXScript.
The source is here <
https://bitbucket.org/ldo17/gxscript/>.
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)