mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
ensure non-escape-only prompts have a thunk application as their body
* module/language/tree-il/inline.scm (inline!): Fix indenting for lambda-case. In an amusing turn of events, use the inliner to de-inline prompt bodies, if the prompt is not escape-only.
This commit is contained in:
parent
cee1d22c3c
commit
ac644098bf
1 changed files with 47 additions and 21 deletions
|
@ -111,28 +111,54 @@
|
||||||
(if (null? vars) body x))
|
(if (null? vars) body x))
|
||||||
|
|
||||||
((<lambda-case> req opt rest kw vars body alternate)
|
((<lambda-case> req opt rest kw vars body alternate)
|
||||||
(let ()
|
(define (args-compatible? args vars)
|
||||||
(define (args-compatible? args vars)
|
(let lp ((args args) (vars vars))
|
||||||
(let lp ((args args) (vars vars))
|
(cond
|
||||||
(cond
|
((null? args) (null? vars))
|
||||||
((null? args) (null? vars))
|
((null? vars) #f)
|
||||||
((null? vars) #f)
|
((and (lexical-ref? (car args))
|
||||||
((and (lexical-ref? (car args))
|
(eq? (lexical-ref-gensym (car args)) (car vars)))
|
||||||
(eq? (lexical-ref-gensym (car args)) (car vars)))
|
(lp (cdr args) (cdr vars)))
|
||||||
(lp (cdr args) (cdr vars)))
|
(else #f))))
|
||||||
(else #f))))
|
|
||||||
|
|
||||||
(and (not opt) (not kw) (not alternate)
|
(and (not opt) (not kw) (not alternate)
|
||||||
(record-case body
|
(record-case body
|
||||||
((<application> proc args)
|
((<application> proc args)
|
||||||
;; (lambda args (apply (lambda ...) args)) => (lambda ...)
|
;; (lambda args (apply (lambda ...) args)) => (lambda ...)
|
||||||
(and (primitive-ref? proc)
|
(and (primitive-ref? proc)
|
||||||
(eq? (primitive-ref-name proc) '@apply)
|
(eq? (primitive-ref-name proc) '@apply)
|
||||||
(pair? args)
|
(pair? args)
|
||||||
(lambda? (car args))
|
(lambda? (car args))
|
||||||
(args-compatible? (cdr args) vars)
|
(args-compatible? (cdr args) vars)
|
||||||
(lambda-body (car args))))
|
(lambda-body (car args))))
|
||||||
(else #f)))))
|
(else #f))))
|
||||||
|
|
||||||
|
;; Actually the opposite of inlining -- if the prompt cannot be proven to
|
||||||
|
;; be escape-only, ensure that its body is the application of a thunk.
|
||||||
|
((<prompt> src tag body handler)
|
||||||
|
(define (escape-only? handler)
|
||||||
|
(and (pair? (lambda-case-req handler))
|
||||||
|
(let ((cont (car (lambda-case-vars handler))))
|
||||||
|
(tree-il-fold (lambda (leaf escape-only?)
|
||||||
|
(and escape-only?
|
||||||
|
(not
|
||||||
|
(and (lexical-ref? leaf)
|
||||||
|
(eq? (lexical-ref-gensym leaf) cont)))))
|
||||||
|
(lambda (down escape-only?) escape-only?)
|
||||||
|
(lambda (up escape-only?) escape-only?)
|
||||||
|
#t
|
||||||
|
(lambda-case-body handler)))))
|
||||||
|
(define (make-thunk body)
|
||||||
|
(make-lambda #f '() (make-lambda-case #f '() #f #f #f '() '() body #f)))
|
||||||
|
|
||||||
|
(if (or (and (application? body)
|
||||||
|
(lambda? (application-proc body))
|
||||||
|
(null? (application-args body)))
|
||||||
|
(escape-only? handler))
|
||||||
|
x
|
||||||
|
(make-prompt src tag
|
||||||
|
(make-application #f (make-thunk body) '())
|
||||||
|
handler)))
|
||||||
|
|
||||||
(else #f)))
|
(else #f)))
|
||||||
(post-order! inline1 x))
|
(post-order! inline1 x))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue