Groups | Search | Server Info | Login | Register
Groups > comp.lang.postscript > #4008
| Path | csiph.com!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail |
|---|---|
| From | Lawrence D'Oliveiro <ldo@nz.invalid> |
| Newsgroups | comp.lang.postscript |
| Subject | Continuations |
| Date | Wed, 5 Jun 2024 07:05:44 -0000 (UTC) |
| Organization | A noiseless patient Spider |
| Lines | 64 |
| Message-ID | <v3p2o7$s5n4$1@dont-email.me> (permalink) |
| MIME-Version | 1.0 |
| Content-Type | text/plain; charset=UTF-8 |
| Content-Transfer-Encoding | 8bit |
| Injection-Date | Wed, 05 Jun 2024 09:05:44 +0200 (CEST) |
| Injection-Info | dont-email.me; posting-host="4516e25990465832a6742c15b1bf965a"; logging-data="923364"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX195ZBkHQZuSuV7ckl6Ano9g" |
| User-Agent | Pan/0.158 (Avdiivka; ) |
| Cancel-Lock | sha1:FXB84S9Twaecs8JfCNWdsJaLm9U= |
| Xref | csiph.com comp.lang.postscript:4008 |
Show key headers only | View raw
Continuations are a generalization of control constructs: from a common
primitive, you can build such things as loops (with exits), exceptions,
and even coroutines.
The way I have implemented this in GXScript is with the “cexec” operator:
this takes a procedure as an argument, like “exec”, but before calling it,
it pushes a continuation object on the stack. Invoking this object will
transfer control to the point immediately following the cexec call that
created it.
Example:
{
/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
But that’s a clunky way to have to write a loop every time. So why not
package up the creation of the continuations in a reusable procedure:
/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.
The source is here <https://bitbucket.org/ldo17/gxscript/> if you want to
have a play.
Back to comp.lang.postscript | Previous | Next | Find similar
Continuations Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-06-05 07:05 +0000
csiph-web