Dear parenscript-devel,
please find attached three patches to the implementation of looping constructs in Parenscript. The first provides a more complete support for CL-LOOP conditional clauses, so that it becomes possible to write, e. g.:
(loop for i :from 0 :to 5 for x := (foo i) when x collect x and if (oddp x) collect (1+ x) else collect (/ x 2) end and do (alert x))
The second patch implements WITH clauses with implicit initialization (though not with TYPE-SPECs), e. g.
(loop for i :from 0 :to 5 with x unless (foo i) do (return (setf x i)))
Formerly, this produced incorrect code, because PS-LOOP required explicit initialization of such variables, but failed to properly assert that the entity following the variable name is the keyword := .
The third patch implements NAMED and RETURN clauses. Also, it fixes the problem that PS-LOOP (contrary to CL-LOOP) did not establish an implicit BLOCK, which used to cause "Returning from unknown block nilBlock" warnings when RETURN forms were used inside LOOPs.
The fourth patch fixes fallacious generated returns in JavaScript code where RETURN or RETURN-FROM are used inside conditional expressions inside loops, as in:
(block nil (dotimes (i 10) (if (test i) (return i))) (return -1))
This produced the following JavaScript:
(function () { var loopResultVar1 = null; for (var i = 0; i < 10; i += 1) { if (test(i)) { loopResultVar1 = i; break; }; }; return loopResultVar1; return -1; })();
If test() fails for all values of i, this code evaluates to null. The meaning of the original code, however, is for the expression to evaluate to -1.
So it goes. Yours, — B. Smilga.