Closed gtnoble closed 1 year ago
Here is another example: The example should print:
"should be printed first"
"should be printed second"
It now prints:
"should be printed second"
"should be printed first"
(defun unwind-protect-test-case-2 ()
(unwind-protect
(progn
(catch 'tag
(throw 'tag "thrown"))
(print "should be printed first"))
(print "should be printed second")))
the throw
and catch
forms do not cause the program to exit the unwind-protect
form, so the cleanup form should be evaluated last.
Thank you.
I improved catch-function. second example is OK. but first example is bad.
Easy-ISLisp Ver2.93
> (load "tests/bug.lsp")
T
> (unwind1)
"should be printed second"
"should be printed first"
"should be printed third"
NIL
> (unwind2)
"should be printed first"
"should be printed second"
NIL
>
I pondered. In the first example, throw moves control to catch. "second" seems to run first.
I improved catch-function. second example is OK. but first example is bad.
Easy-ISLisp Ver2.93 > (load "tests/bug.lsp") T > (unwind1) "should be printed second" "should be printed first" "should be printed third" NIL > (unwind2) "should be printed first" "should be printed second" NIL >
I pondered. In the first example, throw moves control to catch. "second" seems to run first.
Are you saying that you think
"should be printed second"
"should be printed first"
"should be printed third"
is the correct ordering for unwind1
?
I think so. But I'm not sure.
The fix didn't work. Try again.
I think so. But I'm not sure.
For
https://github.com/sasagawa888/eisl/blob/ac48472cd9a6e60e06d7d00197a7a026d86b979b/tests/bug.lsp#L1-L9
(throw 'tag "thrown")
transfers control to catch
, which is outside the inner unwind-protect
form. This should cause the cleanup form (print "should be printed first")
to be evaluated immediately. So, I think "should be printed first"
should appear first.
I checked with OKI-ISLisp.
I will radically rethink the design.
Fixed. Is it working?
Problem remains with block & return-from .
Fixed block & return-from for unwind-protect too.
I think this now works for the interpreter. I will close the issue. Thank you for your continued effort Mr. Sasagawa!
I have a deep understanding of the ISLisp specification. thank you.
This example should print:
It now prints:
There is a non-local exit for the inner
unwind-protect
block only. The outerunwind-protect
exits normally, so the outercleanup-form
should be evaluated last.It looks like every call to
unwind-protect
adds the cleanup forms to a global stack:https://github.com/sasagawa888/eisl/blob/126691908980ebcd70164f923774f4d95efb2e92/syntax.c#L1255-L1265
When
catch
is called, all cleanup forms in the global stack are evaluated. This includes cleanup forms that correspond to outer forms that have not exited yet.https://github.com/sasagawa888/eisl/blob/126691908980ebcd70164f923774f4d95efb2e92/syntax.c#L1132-L1138