Hi Jason,
Thank you very much for raising the preamble issue.
It seems like it is fixable, see below. The idea of a “preamble” will probably be removed.
Fix still needs to be implemented by me.
The blog post has been amended to document this bug. Search for “TODO BUG #2”.
;; TODO BUG #2 2023-02-28
(parenscript:ps*
'(defun bar () (tagbody (go x) (alert "hi") x)))
#|
returns
"defun(bar, null, (function () {
go(x);
alert('hi');
var switchVar295 = 1;
while (true) {
switch (switchVar295) {
case 1:
'tagbody-go-tag: X';
};
__PS_MV_REG = [];
return;
};
})());”
|#
This output is incorrect.
There should be no "go(x);" under any relevant circumstances
as by the CLHS definition of (tagbody ...) and (go ...) .
The problem seems to be that the search for the
"preamble" only checks for go-tags and not for
(go ...) forms. This seems to be easily fixable
by amending the preamble search to terminate upon
encountering a top-level (go ...) form.
Problem: (tagbody (funcall (lambda () (go x))) (alert "hi") x)
still has the same behaviour, *without* involving
a (go ...) form at the top level of the (tagbody ...).
Alternative proposal:
Do away with the preamble and instead add a
dummy gensymmed jump tag at the beginning
of the (tagbody ...). That jump-tag should,
conceptually, be unreachable. All (go ...)
forms are then affected by the (macrolet ((go ...)) ...)
wrappers being placed already.
Then the preamble analysis becomes dead code and can
be removed.
See Jason Miller's first bug reported on 2023-01-27
for current problems with wrapping (go ...) forms
inside of (lambda ...) forms.
Cheers,
Andrew
(parenscript:ps (defun bar () (tagbody (go x) (alert "hi") x)))