[Apologies if some if this is obvious to many of you - kjx]
As some of you may know, I'm trying to write a program visualisation
system in Self for a doctoral thesis. This is based upon an mechanism
for generating events whenever something interesting happens in a Self
program (the events are fed to other Self objects to produce the
visualisations - papers available on request :-). Events can be easily
generated when messages are received by an object, when methods return
normally. Currently, I can't handle non-local method completion, (that
is the "^" operator) - these message completions are ignored. This has
only been a theoretical problem so far, however, gradually scaling up
the size of programs I'm trying to visualise, I seem to have reached a
point where I need to be able to handle non-local returns in the event
Now several other languages incorporating non-local exits (Smalltalk,
Lisp and even VAX Pascal) include an "unwind protect" construct which
would trap non-local returns, allowing some action to be taken "on the
way up the stack" so to speak. Something like this would allow me to
generate the appropriate events and hopefully visualise the programs
currently giving me trouble.
So while I try to find ways to avoid the non-local exits in the code
in question, this is another plaintive cry asking if anyone has ideas
about incorporating unwind-protect into Self. Given that the VM source
code is now available, I suppose I could try that - does anyone have
any idea how difficult it would be? (in passing - how have people
outside the Self group found the VM code to work with). Another
alternative would be to move the whole event mechanism inside the VM -
but I'm sure that would be even more work.
Another related question, (discovered when poking around these things)
is what happens to blocks that perform a non-local return where the
method returned to is not in the running process. (Yes, I was
attempting a work-around where the protected code would be run in
another Self process). However, a non-local return in this case seems
to terminate the process without a return value.
Some example code is appended below.
"what's happening here"
lobby _AddSlots: (| foo = (|
parent* = traits oddball.
a = ( 'foo a called' printLine.
'foo a stores magic block' printLine.
blk: [ 'blk called' printLine.
'foo a stores process number' printLine.
prc: process this.
'foo a suspends' printLine.
process this suspend.
'foo a invokes block' printLine.
'foo a returns' printLine.).
blk. "holds block"
prc. "holds process"
"Now, run these commands from the prompt"
[foo blk value. ^'where does this go?'] value
foo prc resume