Commit ee545a02 authored by Vladimir Sedach's avatar Vladimir Sedach

Made sure returns from LABELS functions work properly.

Thanks to Daniel Gackle for the bug report.
parent c5a3b2b8
......@@ -180,6 +180,11 @@ Syntax of key spec:
(ps-gensym (string fn-name))
fn-name)))
(defun compile-named-local-function (name args body)
(multiple-value-bind (args1 body-block)
(compile-named-function-body name args body)
`(ps-js:lambda ,args1 ,body-block)))
(define-expression-operator flet (fn-defs &rest body)
(let* ((fn-renames (collect-function-names fn-defs))
;; the function definitions need to be compiled with previous lexical bindings
......@@ -190,9 +195,7 @@ Syntax of key spec:
*vars-needing-to-be-declared*))
(list (if compile-expression? 'ps-js:= 'ps-js:var)
(getf fn-renames fn-name)
(multiple-value-bind (args1 body-block)
(compile-named-function-body fn-name args body)
`(ps-js:lambda ,args1 ,body-block))))))
(compile-named-local-function fn-name args body)))))
;; the flet body needs to be compiled with the extended lexical environment
(*enclosing-lexicals*
(append fn-renames *enclosing-lexicals*))
......@@ -217,8 +220,7 @@ Syntax of key spec:
*vars-needing-to-be-declared*))
(list (if compile-expression? 'ps-js:= 'ps-js:var)
(getf *local-function-names* fn-name)
(let ((*function-block-names* (list fn-name)))
(compile-expression `(lambda ,args ,@body))))))
(compile-named-local-function fn-name args body))))
,@(compile-progn body))))
(define-expression-operator function (fn-name) ;; one of the things responsible for function namespace
......
......@@ -163,6 +163,53 @@
(funcall (aref foo 1))))
'(2 3))
(test-js-eval labels-return
((lambda ()
(labels ((bar (x)
(when (evenp x)
(return-from bar "even"))
1))
(bar 9))))
1)
(test-js-eval labels-return1
(progn (defun foo ()
(labels ((bar (x)
(when (evenp x)
(return-from foo "even"))
1))
(bar 8)
2))
(foo))
"even")
(test-js-eval labels-return2
(progn (defun foo ()
(labels ((bar (x)
(flet ((foo (y)
(when (evenp (+ x y))
(return-from bar "even"))))
(foo 4)
5)
1))
(bar 8)))
(foo))
"even")
(test-js-eval labels-return3
(progn (defun foo ()
(labels ((bar (x)
(flet ((baz (y)
(when (evenp (+ x y))
(return-from foo "even"))))
(baz 4)
5)
1))
(bar 8)
2))
(foo))
"even")
;;; broken
(test-js-eval block-dynamic-return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment