mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Ensure <prompt> handler is values handler
* module/language/tree-il/primitives.scm (call-with-prompt): Only pass "values handlers" as handler: lambdas with only req and rest args, and only one clause. * module/language/tree-il/compile-cps.scm (canonicalize): Remove eta-conversion pass here. * test-suite/tests/peval.test ("partial evaluation"): Adapt test.
This commit is contained in:
parent
d6b6daca37
commit
167350db21
3 changed files with 46 additions and 34 deletions
|
@ -2556,32 +2556,6 @@ integer."
|
||||||
(make-primcall src 'rsh (list a n)))
|
(make-primcall src 'rsh (list a n)))
|
||||||
(make-primcall src 'lsh (list a b)))))))
|
(make-primcall src 'lsh (list a b)))))))
|
||||||
|
|
||||||
;; Eta-convert prompts without inline handlers.
|
|
||||||
(($ <prompt> src escape-only? tag body handler)
|
|
||||||
(let ((h (gensym "h "))
|
|
||||||
(args (gensym "args ")))
|
|
||||||
(define-syntax-rule (primcall name . args)
|
|
||||||
(make-primcall src 'name (list . args)))
|
|
||||||
(define-syntax-rule (const val)
|
|
||||||
(make-const src val))
|
|
||||||
(with-lexicals src (handler)
|
|
||||||
(make-conditional
|
|
||||||
src
|
|
||||||
(primcall procedure? handler)
|
|
||||||
(make-prompt
|
|
||||||
src escape-only? tag body
|
|
||||||
(make-lambda
|
|
||||||
src '()
|
|
||||||
(make-lambda-case
|
|
||||||
src '() #f 'args #f '() (list args)
|
|
||||||
(primcall apply handler (make-lexical-ref #f 'args args))
|
|
||||||
#f)))
|
|
||||||
(primcall throw
|
|
||||||
(const 'wrong-type-arg)
|
|
||||||
(const "call-with-prompt")
|
|
||||||
(const "Wrong type (expecting procedure): ~S")
|
|
||||||
(primcall cons handler (const '()))
|
|
||||||
(primcall cons handler (const '())))))))
|
|
||||||
(_ exp)))
|
(_ exp)))
|
||||||
exp))
|
exp))
|
||||||
|
|
||||||
|
|
|
@ -651,7 +651,37 @@
|
||||||
(define-primitive-expander! 'call-with-prompt
|
(define-primitive-expander! 'call-with-prompt
|
||||||
(case-lambda
|
(case-lambda
|
||||||
((src tag thunk handler)
|
((src tag thunk handler)
|
||||||
(make-prompt src #f tag thunk handler))
|
(match handler
|
||||||
|
(($ <lambda> _ _ ($ <lambda-case> _ _ #f _ #f () _ _ #f))
|
||||||
|
(make-prompt src #f tag thunk handler))
|
||||||
|
(_
|
||||||
|
;; Eta-convert prompts without inline handlers.
|
||||||
|
(let ((h (gensym "h "))
|
||||||
|
(args (gensym "args ")))
|
||||||
|
(define-syntax-rule (primcall name . args)
|
||||||
|
(make-primcall src 'name (list . args)))
|
||||||
|
(define-syntax-rule (const val)
|
||||||
|
(make-const src val))
|
||||||
|
(make-let
|
||||||
|
src (list 'handler) (list h) (list handler)
|
||||||
|
(let ((handler (make-lexical-ref src 'handler h)))
|
||||||
|
(make-conditional
|
||||||
|
src
|
||||||
|
(primcall procedure? handler)
|
||||||
|
(make-prompt
|
||||||
|
src #f tag thunk
|
||||||
|
(make-lambda
|
||||||
|
src '()
|
||||||
|
(make-lambda-case
|
||||||
|
src '() #f 'args #f '() (list args)
|
||||||
|
(primcall apply handler (make-lexical-ref #f 'args args))
|
||||||
|
#f)))
|
||||||
|
(primcall throw
|
||||||
|
(const 'wrong-type-arg)
|
||||||
|
(const "call-with-prompt")
|
||||||
|
(const "Wrong type (expecting procedure): ~S")
|
||||||
|
(primcall list handler)
|
||||||
|
(primcall list handler)))))))))
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
|
||||||
(define-primitive-expander! 'abort-to-prompt*
|
(define-primitive-expander! 'abort-to-prompt*
|
||||||
|
|
|
@ -1223,13 +1223,21 @@
|
||||||
(call-with-prompt tag
|
(call-with-prompt tag
|
||||||
(lambda () 1)
|
(lambda () 1)
|
||||||
handler)
|
handler)
|
||||||
(prompt #f
|
(let (handler) (_) ((toplevel handler))
|
||||||
(toplevel tag)
|
(if (primcall procedure? (lexical handler _))
|
||||||
(lambda _
|
(prompt #f
|
||||||
(lambda-case
|
(toplevel tag)
|
||||||
((() #f #f #f () ())
|
(lambda _
|
||||||
(const 1))))
|
(lambda-case
|
||||||
(toplevel handler)))
|
((() #f #f #f () ())
|
||||||
|
(const 1))))
|
||||||
|
(lambda _
|
||||||
|
(lambda-case
|
||||||
|
((() #f args #f () (_))
|
||||||
|
(primcall apply
|
||||||
|
(lexical handler _)
|
||||||
|
(lexical args _))))))
|
||||||
|
(primcall throw . _))))
|
||||||
|
|
||||||
(pass-if-peval
|
(pass-if-peval
|
||||||
;; `while' without `break' or `continue' has no prompts and gets its
|
;; `while' without `break' or `continue' has no prompts and gets its
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue