From b1a71d3b8a020bc2b8017503216d4a75ab48a36e Mon Sep 17 00:00:00 2001 From: Vladimir Sedach Date: Fri, 2 Nov 2018 20:50:01 -0700 Subject: [PATCH] Fix dynamic returns getting precedence over lexical ones --- src/special-operators.lisp | 62 ++++++----- tests/output-tests.lisp | 233 +++++++++++++++++++++++++++------------- tests/package-system-tests.lisp | 3 + 3 files changed, 198 insertions(+), 100 deletions(-) diff --git a/src/special-operators.lisp b/src/special-operators.lisp index 09c0fce..cd53e2f 100644 --- a/src/special-operators.lisp +++ b/src/special-operators.lisp @@ -181,7 +181,7 @@ `((and ,_ps_err (eql ',tag (getprop ,_ps_err :__ps_block_tag))) (return-from ,tag - (values-list (getprop ,_ps_err :__ps_values)))))) + (getprop ,_ps_err :__ps_value))))) `(ps-js:block (ps-js:try ,body @@ -225,33 +225,39 @@ ,firstval)))) (defun return-exp (tag &optional (value nil value?)) - (acond - ((eql tag *current-block-tag*) - (compile-statement - `(progn - ,@(when (and (not returning-values?) clear-multiple-values?) - '((setf __PS_MV_REG '()))) - ,@(when value? (list value)) - (break ,tag)))) - ((assoc tag *dynamic-return-tags*) - (setf (cdr it) t) - (ps-compile - `(progn - ,@(when (and (not returning-values?) clear-multiple-values?) - '((setf __PS_MV_REG '()))) - (throw (create - :__ps_block_tag ',tag - :__ps_values (multiple-value-list ,value)))))) - (t - (unless (or (eql '%function tag) - (member tag *function-block-names*)) - (warn "Returning from unknown block ~A" tag)) - (let ((X (when value? (list (compile-expression value))))) - (if (and (not returning-values?) clear-multiple-values?) - `(ps-js:block - (ps-js:= __PS_MV_REG []) - (ps-js:return ,@X)) - `(ps-js:return ,@X)))))) + (flet ((lexical-return () + (let ((X (when value? (list (compile-expression value))))) + (if (and (not returning-values?) clear-multiple-values?) + `(ps-js:block + (ps-js:= __PS_MV_REG []) + (ps-js:return ,@X)) + `(ps-js:return ,@X))))) + (acond + ((eql tag *current-block-tag*) + (compile-statement + `(progn + ,@(when (and (not returning-values?) clear-multiple-values?) + '((setf __PS_MV_REG '()))) + ,@(when value? (list value)) + (break ,tag)))) + + ((or (eql '%function tag) + (member tag *function-block-names*)) + (lexical-return)) + + ((assoc tag *dynamic-return-tags*) + (setf (cdr it) t) + (ps-compile + `(progn + ,@(when (and (not returning-values?) clear-multiple-values?) + '((setf __PS_MV_REG '()))) + (throw (create + :__ps_block_tag ',tag + :__ps_value ,value))))) + + (t + (warn "Returning from unknown block ~A" tag) + (lexical-return))))) (defun try-expressionizing-if? (exp &optional (score 0)) ;; poor man's codewalker "Heuristic that tries not to expressionize deeply nested if expressions." diff --git a/tests/output-tests.lisp b/tests/output-tests.lisp index b36c7e5..26764e2 100644 --- a/tests/output-tests.lisp +++ b/tests/output-tests.lisp @@ -219,6 +219,7 @@ "(function () { var _js1 = makeAnObject(); var _js2 = _js1.foo; + __PS_MV_REG = []; return _js2.apply(_js1, bar()); })();") @@ -437,8 +438,10 @@ return _js2.style.left = _js1; "function foo() { if (blorg.isCorrect()) { carryOn(); + __PS_MV_REG = []; return i; } else { + __PS_MV_REG = []; return alert('blorg is not correct!'); }; };") @@ -455,6 +458,7 @@ return _js2.style.left = _js1; "function foo() { if (blorg.isCorrect()) { carryOn(); + __PS_MV_REG = []; return i; }; };") @@ -584,6 +588,7 @@ for (var i = 0; i < arr.length; i += 1) { (incf res (1+ i)))))) "(function () { var res = 0; +__PS_MV_REG = []; return alert('Summation to 10 is ' + (function () { for (var i = 0; i < 10; i += 1) { res += i + 1; @@ -614,6 +619,7 @@ for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) { "(function () { var l = [1, 2, 4, 8, 16, 32]; var s = 0; +__PS_MV_REG = []; return alert('Sum of ' + l + ' is: ' + (function () { for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) { c = l[_js_idx1]; @@ -726,6 +732,7 @@ for (var _js1 in obj) { for (var k in obj) { map1[k] = foo(k); }; + __PS_MV_REG = []; return map1; })();") @@ -854,6 +861,7 @@ for (var _js1 = 0; _js1 < _js2; _js1 += 1) { var a = b[_js1]; collect3.push(foo(a)); }; + __PS_MV_REG = []; return collect3; })();") @@ -983,6 +991,7 @@ return element.innerHTML = ['