mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +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 '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))
|
||||
|
||||
|
|
|
@ -651,7 +651,37 @@
|
|||
(define-primitive-expander! 'call-with-prompt
|
||||
(case-lambda
|
||||
((src 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)))
|
||||
|
||||
(define-primitive-expander! 'abort-to-prompt*
|
||||
|
|
|
@ -1223,13 +1223,21 @@
|
|||
(call-with-prompt tag
|
||||
(lambda () 1)
|
||||
handler)
|
||||
(let (handler) (_) ((toplevel handler))
|
||||
(if (primcall procedure? (lexical handler _))
|
||||
(prompt #f
|
||||
(toplevel tag)
|
||||
(lambda _
|
||||
(lambda-case
|
||||
((() #f #f #f () ())
|
||||
(const 1))))
|
||||
(toplevel handler)))
|
||||
(lambda _
|
||||
(lambda-case
|
||||
((() #f args #f () (_))
|
||||
(primcall apply
|
||||
(lexical handler _)
|
||||
(lexical args _))))))
|
||||
(primcall throw . _))))
|
||||
|
||||
(pass-if-peval
|
||||
;; `while' without `break' or `continue' has no prompts and gets its
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue