summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-08-15 22:42:18 +0200
committerAndy Wingo <wingo@pobox.com>2013-08-15 23:08:08 +0200
commitdadad2eb4a51cfd5f1c766c41fa1f2eb48280b7f (patch)
tree9a010bdf12fbb69375577bd9c851c757e9b183f8
parentfa798547e4bc6c687581f937ef6756f1c74f5bf3 (diff)
downloadguile-dadad2eb4a51cfd5f1c766c41fa1f2eb48280b7f.tar.gz
Move build-cps-term and friends to (language cps)
* module/language/cps.scm (let-gensyms): (build-cps-cont, build-cps-call, build-cps-term): New public interfaces, factored out of (language tree-il compile-cps). * module/language/tree-il/compile-cps.scm: Update.
-rw-r--r--module/language/cps.scm96
-rw-r--r--module/language/tree-il/compile-cps.scm513
2 files changed, 317 insertions, 292 deletions
diff --git a/module/language/cps.scm b/module/language/cps.scm
index 29c688a0c..35cf43d6b 100644
--- a/module/language/cps.scm
+++ b/module/language/cps.scm
@@ -70,7 +70,13 @@
make-$call make-$primcall make-$values make-$prompt
parse-cps
- unparse-cps))
+ unparse-cps
+
+ ;; Building macros.
+ let-gensyms
+ build-cps-term
+ build-cps-call
+ build-cps-cont))
;; FIXME: Use SRFI-99, when Guile adds it.
(define-syntax define-record-type*
@@ -226,3 +232,91 @@
`(prompt ,escape? ,tag ,handler))
(_
(error "unexpected cps" exp))))
+
+;; FIXME: Figure out how to evaluate this automatically when Emacs
+;; visits this buffer.
+;;
+;; (put 'let-gensyms 'scheme-indent-function 1)
+;; (put 'build-cps-term 'scheme-indent-function 0)
+;; (put 'build-cps-call 'scheme-indent-function 0)
+;; (put 'build-cps-cont 'scheme-indent-function 0)
+;; (put '$letk 'scheme-indent-function 1)
+;; (put '$letk* 'scheme-indent-function 1)
+;; (put '$letconst 'scheme-indent-function 1)
+;; (put '$continue 'scheme-indent-function 1)
+;; (put '$kargs 'scheme-indent-function 2)
+
+(define-syntax let-gensyms
+ (syntax-rules ()
+ ((_ (sym ...) body body* ...)
+ (let ((sym (gensym (symbol->string 'sym))) ...)
+ body body* ...))))
+
+(define-syntax build-arity
+ (syntax-rules (unquote)
+ ((_ (unquote exp)) exp)
+ ((_ (req opt rest kw allow-other-keys?))
+ (make-$arity req opt rest kw allow-other-keys?))))
+
+(define-syntax build-cont-body
+ (syntax-rules (unquote $kif $ktrunc $kargs $kentry)
+ ((_ (unquote exp))
+ exp)
+ ((_ ($kif kt kf))
+ (make-$kif kt kf))
+ ((_ ($ktrunc req rest kargs))
+ (make-$ktrunc (make-$arity req '() rest '() #f) kargs))
+ ((_ ($kargs (name ...) (sym ...) body))
+ (make-$kargs (list name ...) (list sym ...) (build-cps-term body)))
+ ((_ ($kargs names syms body))
+ (make-$kargs names syms (build-cps-term body)))
+ ((_ ($kentry arity cont))
+ (make-$kentry (build-arity arity) (build-cps-cont cont)))))
+
+(define-syntax build-cps-cont
+ (syntax-rules (unquote)
+ ((_ (unquote exp)) exp)
+ ((_ (k src cont)) (make-$cont src k (build-cont-body cont)))))
+
+(define-syntax build-cps-call
+ (syntax-rules (unquote
+ $var $void $const $prim $fun $call $primcall $values $prompt)
+ ((_ (unquote exp)) exp)
+ ((_ ($var sym)) (make-$var sym))
+ ((_ ($void)) (make-$void))
+ ((_ ($const val)) (make-$const val))
+ ((_ ($prim name)) (make-$prim name))
+ ((_ ($fun meta self free (unquote entries)))
+ (make-$fun meta self free entries))
+ ((_ ($fun meta self free (entry ...)))
+ (make-$fun meta self free (list (build-cps-cont entry) ...)))
+ ((_ ($call proc (arg ...))) (make-$call proc (list arg ...)))
+ ((_ ($call proc args)) (make-$call proc args))
+ ((_ ($primcall name (arg ...))) (make-$primcall name (list arg ...)))
+ ((_ ($primcall name args)) (make-$primcall name args))
+ ((_ ($values (arg ...))) (make-$values (list arg ...)))
+ ((_ ($values args)) (make-$values args))
+ ((_ ($prompt escape? tag handler)) (make-$prompt escape? tag handler))))
+
+(define-syntax build-cps-term
+ (syntax-rules (unquote $letk $letk* $letconst $letrec $continue)
+ ((_ (unquote exp))
+ exp)
+ ((_ ($letk (cont ...) body))
+ (make-$letk (list (build-cps-cont cont) ...)
+ (build-cps-term body)))
+ ((_ ($letk* () body))
+ (build-cps-term body))
+ ((_ ($letk* (cont conts ...) body))
+ (build-cps-term ($letk (cont) ($letk* (conts ...) body))))
+ ((_ ($letconst () body))
+ (build-cps-term body))
+ ((_ ($letconst ((name sym val) tail ...) body))
+ (let-gensyms (kconst)
+ (build-cps-term
+ ($letk ((kconst #f ($kargs (name) (sym) ($letconst (tail ...) body))))
+ ($continue kconst ($const val))))))
+ ((_ ($letrec names gensyms funs body))
+ (make-$letrec names gensyms funs (build-cps-term body)))
+ ((_ ($continue k exp))
+ (make-$continue k (build-cps-call exp)))))
diff --git a/module/language/tree-il/compile-cps.scm b/module/language/tree-il/compile-cps.scm
index d77b9d4a5..236d46a04 100644
--- a/module/language/tree-il/compile-cps.scm
+++ b/module/language/tree-il/compile-cps.scm
@@ -47,98 +47,9 @@
tree-il-fold))
#:export (compile-cps))
-;; (put 'build-cps 'scheme-indent-function 0)
-;; (put 'build-cps* 'scheme-indent-function 1)
-;; (put '$letk 'scheme-indent-function 1)
-;; (put '$letk* 'scheme-indent-function 1)
-;; (put '$letconst 'scheme-indent-function 1)
-;; (put '$continue 'scheme-indent-function 1)
-;; (put '$kargs 'scheme-indent-function 2)
;; (put 'convert-arg 'scheme-indent-function 1)
;; (put 'convert-args 'scheme-indent-function 1)
-(define-syntax build-cont
- (syntax-rules (unquote $kif $ktrunc $kargs)
- ((_ (unquote exp))
- exp)
- ((_ ($kif kt kf))
- (make-$kif kt kf))
- ((_ ($ktrunc req rest kargs))
- (make-$ktrunc (make-$arity req '() rest '() #f) kargs))
- ((_ ($kargs (name ...) (sym ...) body))
- (make-$kargs (list name ...) (list sym ...) (build-cps body)))
- ((_ ($kargs names syms body))
- (make-$kargs names syms (build-cps body)))))
-
-(define-syntax build-cont-decl
- (syntax-rules (unquote)
- ((_ (unquote exp)) exp)
- ((_ (k src cont)) (make-$cont src k (build-cont cont)))))
-
-(define-syntax build-arity
- (syntax-rules (unquote)
- ((_ (unquote exp)) exp)
- ((_ (req opt rest kw allow-other-keys?))
- (make-$arity req opt rest kw allow-other-keys?))))
-
-(define-syntax build-fun-entry
- (syntax-rules (unquote)
- ((_ (unquote exp)) exp)
- ((_ ($kentry k src arity cont-decl))
- (make-$cont src k (make-$kentry (build-arity arity)
- (build-cont-decl cont-decl))))))
-
-(define-syntax build-fun
- (syntax-rules (unquote)
- ((_ ($fun meta self free (unquote body)))
- (make-$fun meta self free body))
- ((_ ($fun meta self free (entry ...)))
- (make-$fun meta self free (list (build-fun-entry entry) ...)))))
-
-(define-syntax build-call
- (syntax-rules (unquote
- $var $void $const $prim $fun $call $primcall $values $prompt)
- ((_ (unquote exp)) exp)
- ((_ ($var sym)) (make-$var sym))
- ((_ ($void)) (make-$void))
- ((_ ($const val)) (make-$const val))
- ((_ ($prim name)) (make-$prim name))
- ((_ ($fun . args)) (build-fun ($fun . args)))
- ((_ ($call proc (arg ...))) (make-$call proc (list arg ...)))
- ((_ ($call proc args)) (make-$call proc args))
- ((_ ($primcall name (arg ...))) (make-$primcall name (list arg ...)))
- ((_ ($primcall name args)) (make-$primcall name args))
- ((_ ($values (arg ...))) (make-$values (list arg ...)))
- ((_ ($values args)) (make-$values args))
- ((_ ($prompt escape? tag handler)) (make-$prompt escape? tag handler))))
-
-(define-syntax build-cps
- (syntax-rules (unquote $letk $letk* $letconst $letrec $continue)
- ((_ (unquote exp))
- exp)
- ((_ ($letk (cont-decl ...) body))
- (make-$letk (list (build-cont-decl cont-decl) ...)
- (build-cps body)))
- ((_ ($letk* () body))
- (build-cps body))
- ((_ ($letk* (cont-decl cont-decls ...) body))
- (build-cps ($letk (cont-decl) ($letk* (cont-decls ...) body))))
- ((_ ($letconst () body))
- (build-cps body))
- ((_ ($letconst ((name sym val) tail ...) body))
- (build-cps* (kconst)
- ($letk ((kconst #f ($kargs (name) (sym) ($letconst (tail ...) body))))
- ($continue kconst ($const val)))))
- ((_ ($letrec names gensyms funs body))
- (make-$letrec names gensyms funs (build-cps body)))
- ((_ ($continue k exp)) (make-$continue k (build-call exp)))))
-
-(define-syntax build-cps*
- (syntax-rules ()
- ((_ (sym ...) form)
- (let ((sym (gensym (symbol->string 'sym))) ...)
- (build-cps form)))))
-
;; Guile's semantics are that a toplevel lambda captures a reference on
;; the current module, and that all contained lambdas use that module to
;; resolve toplevel variables. This parameter tracks whether or not we
@@ -155,43 +66,47 @@
(define current-topbox-scope (make-parameter #f))
(define (toplevel-box src name bound? val-proc)
- (build-cps* (name-sym bound?-sym kbox box)
- ($letconst (('name name-sym name)
- ('bound? bound?-sym bound?))
- ($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
- ,(match (current-topbox-scope)
- (#f
- (build-cps
- ($continue kbox
- ($primcall 'resolve
- (name-sym bound?-sym)))))
- (scope
- (build-cps* (scope-sym)
- ($letconst (('scope scope-sym scope))
+ (let-gensyms (name-sym bound?-sym kbox box)
+ (build-cps-term
+ ($letconst (('name name-sym name)
+ ('bound? bound?-sym bound?))
+ ($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
+ ,(match (current-topbox-scope)
+ (#f
+ (build-cps-term
($continue kbox
- ($primcall 'cached-toplevel-box
- (scope-sym name-sym bound?-sym)))))))))))
+ ($primcall 'resolve
+ (name-sym bound?-sym)))))
+ (scope
+ (let-gensyms (scope-sym)
+ (build-cps-term
+ ($letconst (('scope scope-sym scope))
+ ($continue kbox
+ ($primcall 'cached-toplevel-box
+ (scope-sym name-sym bound?-sym)))))))))))))
(define (module-box src module name public? bound? val-proc)
- (build-cps* (module-sym name-sym public?-sym bound?-sym kbox box)
- ($letconst (('module module-sym module)
- ('name name-sym name)
- ('public? public?-sym public?)
- ('bound? bound?-sym bound?))
- ($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
- ($continue kbox
- ($primcall 'cached-module-box
- (module-sym name-sym public?-sym bound?-sym)))))))
+ (let-gensyms (module-sym name-sym public?-sym bound?-sym kbox box)
+ (build-cps-term
+ ($letconst (('module module-sym module)
+ ('name name-sym name)
+ ('public? public?-sym public?)
+ ('bound? bound?-sym bound?))
+ ($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
+ ($continue kbox
+ ($primcall 'cached-module-box
+ (module-sym name-sym public?-sym bound?-sym))))))))
(define (capture-toplevel-scope src scope k)
- (build-cps* (module scope-sym kmodule)
- ($letconst (('scope scope-sym scope))
- ($letk ((kmodule src ($kargs ('module) (module)
- ($continue k
- ($primcall 'cache-current-module!
- (module scope-sym))))))
- ($continue kmodule
- ($primcall 'current-module ()))))))
+ (let-gensyms (module scope-sym kmodule)
+ (build-cps-term
+ ($letconst (('scope scope-sym scope))
+ ($letk ((kmodule src ($kargs ('module) (module)
+ ($continue k
+ ($primcall 'cache-current-module!
+ (module scope-sym))))))
+ ($continue kmodule
+ ($primcall 'current-module ())))))))
(define (fold-formals proc seed arity gensyms inits)
(match arity
@@ -233,11 +148,12 @@
(define tc8-iflag 4)
(define unbound-val 9)
(define unbound-bits (logior (ash unbound-val 8) tc8-iflag))
- (build-cps* (unbound ktest)
- ($letconst (('unbound unbound (pointer->scm (make-pointer unbound-bits))))
- ($letk ((ktest src ($kif kt kf)))
- ($continue ktest
- ($primcall 'eq? (sym unbound)))))))
+ (let-gensyms (unbound ktest)
+ (build-cps-term
+ ($letconst (('unbound unbound (pointer->scm (make-pointer unbound-bits))))
+ ($letk ((ktest src ($kif kt kf)))
+ ($continue ktest
+ ($primcall 'eq? (sym unbound))))))))
(define (init-default-value name sym subst init body)
(match (assq-ref subst sym)
@@ -245,20 +161,22 @@
(let ((src (tree-il-src init)))
(define (maybe-box k make-body)
(if box?
- (build-cps* (kbox phi)
- ($letk ((kbox src ($kargs (name) (phi)
- ($continue k ($primcall 'box (phi))))))
- ,(make-body kbox)))
+ (let-gensyms (kbox phi)
+ (build-cps-term
+ ($letk ((kbox src ($kargs (name) (phi)
+ ($continue k ($primcall 'box (phi))))))
+ ,(make-body kbox))))
(make-body k)))
- (build-cps* (knext kbound kunbound)
- ($letk ((knext src ($kargs (name) (subst-sym) ,body)))
- ,(maybe-box
- knext
- (lambda (k)
- (build-cps
- ($letk ((kbound src ($kargs () () ($continue k ($var sym))))
- (kunbound src ($kargs () () ,(convert init k subst))))
- ,(unbound? src sym kunbound kbound)))))))))))
+ (let-gensyms (knext kbound kunbound)
+ (build-cps-term
+ ($letk ((knext src ($kargs (name) (subst-sym) ,body)))
+ ,(maybe-box
+ knext
+ (lambda (k)
+ (build-cps-term
+ ($letk ((kbound src ($kargs () () ($continue k ($var sym))))
+ (kunbound src ($kargs () () ,(convert init k subst))))
+ ,(unbound? src sym kunbound kbound))))))))))))
;; exp k-name alist -> term
(define (convert exp k subst)
@@ -268,16 +186,18 @@
(($ <lexical-ref> src name sym)
(match (assq-ref subst sym)
((box #t)
- (build-cps* (kunboxed unboxed)
- ($letk ((kunboxed src ($kargs ('unboxed) (unboxed) ,(k unboxed))))
- ($continue kunboxed ($primcall 'box-ref (box))))))
+ (let-gensyms (kunboxed unboxed)
+ (build-cps-term
+ ($letk ((kunboxed src ($kargs ('unboxed) (unboxed) ,(k unboxed))))
+ ($continue kunboxed ($primcall 'box-ref (box)))))))
((subst #f) (k subst))
(#f (k sym))))
(else
(let ((src (tree-il-src exp)))
- (build-cps* (karg arg)
- ($letk ((karg src ($kargs ('arg) (arg) ,(k arg))))
- ,(convert exp karg subst)))))))
+ (let-gensyms (karg arg)
+ (build-cps-term
+ ($letk ((karg src ($kargs ('arg) (arg) ,(k arg))))
+ ,(convert exp karg subst))))))))
;; (exp ...) ((v-name ...) -> term) -> term
(define (convert-args exps k)
(match exps
@@ -291,26 +211,27 @@
(define (box-bound-var name sym body)
(match (assq-ref subst sym)
((box #t)
- (build-cps* (k)
- ($letk ((k #f ($kargs (name) (sym) ,body)))
- ($continue k ($primcall 'box (sym))))))
+ (let-gensyms (k)
+ (build-cps-term
+ ($letk ((k #f ($kargs (name) (sym) ,body)))
+ ($continue k ($primcall 'box (sym)))))))
(else body)))
(match exp
(($ <lexical-ref> src name sym)
(match (assq-ref subst sym)
- ((box #t) (build-cps ($continue k ($primcall 'box-ref (box)))))
- ((subst #f) (build-cps ($continue k ($var subst))))
- (#f (build-cps ($continue k ($var sym))))))
+ ((box #t) (build-cps-term ($continue k ($primcall 'box-ref (box)))))
+ ((subst #f) (build-cps-term ($continue k ($var subst))))
+ (#f (build-cps-term ($continue k ($var sym))))))
(($ <void> src)
- (build-cps ($continue k ($void))))
+ (build-cps-term ($continue k ($void))))
(($ <const> src exp)
- (build-cps ($continue k ($const exp))))
+ (build-cps-term ($continue k ($const exp))))
(($ <primitive-ref> src name)
- (build-cps ($continue k ($prim name))))
+ (build-cps-term ($continue k ($prim name))))
(($ <lambda> src meta body)
;; FIXME: add src field to fun, add tail field also
@@ -325,36 +246,40 @@
'()
arity gensyms inits)))
(cons
- (build-cps* (kentry kargs)
- ,(build-fun-entry
- ($kentry
- kentry src ,arity
- (kargs
- src
- ($kargs names gensyms
- ,(fold-formals
- (lambda (name sym init body)
- (if init
- (init-default-value name sym subst init body)
- (box-bound-var name sym body)))
- (convert body 'ktail subst)
- arity gensyms inits))))))
+ (let-gensyms (kentry kargs)
+ (build-cps-cont
+ (kentry
+ src
+ ($kentry
+ ,arity
+ (kargs
+ src
+ ($kargs names gensyms
+ ,(fold-formals
+ (lambda (name sym init body)
+ (if init
+ (init-default-value name sym subst init body)
+ (box-bound-var name sym body)))
+ (convert body 'ktail subst)
+ arity gensyms inits)))))))
(if alternate (convert-entries alternate) '()))))))
(if (current-topbox-scope)
- (build-cps* (self)
- ($continue k
- ($fun meta self '() ,(convert-entries body))))
- (build-cps* (scope kscope)
- ($letk ((kscope src ($kargs () ()
- ,(parameterize ((current-topbox-scope scope))
- (convert exp k subst)))))
- ,(capture-toplevel-scope src scope kscope))))))
+ (let-gensyms (self)
+ (build-cps-term
+ ($continue k
+ ($fun meta self '() ,(convert-entries body)))))
+ (let-gensyms (scope kscope)
+ (build-cps-term
+ ($letk ((kscope src ($kargs () ()
+ ,(parameterize ((current-topbox-scope scope))
+ (convert exp k subst)))))
+ ,(capture-toplevel-scope src scope kscope)))))))
(($ <module-ref> src mod name public?)
(module-box
src mod name public? #t
(lambda (box)
- (build-cps ($continue k ($primcall 'box-ref (box)))))))
+ (build-cps-term ($continue k ($primcall 'box-ref (box)))))))
(($ <module-set> src mod name public? exp)
(convert-arg exp
@@ -362,13 +287,13 @@
(module-box
src mod name public? #f
(lambda (box)
- (build-cps ($continue k ($primcall 'box-set! (box val)))))))))
+ (build-cps-term ($continue k ($primcall 'box-set! (box val)))))))))
(($ <toplevel-ref> src name)
(toplevel-box
src name #t
(lambda (box)
- (build-cps ($continue k ($primcall 'box-ref (box)))))))
+ (build-cps-term ($continue k ($primcall 'box-ref (box)))))))
(($ <toplevel-set> src name exp)
(convert-arg exp
@@ -376,20 +301,21 @@
(toplevel-box
src name #f
(lambda (box)
- (build-cps ($continue k ($primcall 'box-set! (box val)))))))))
+ (build-cps-term ($continue k ($primcall 'box-set! (box val)))))))))
(($ <toplevel-define> src name exp)
(convert-arg exp
(lambda (val)
- (build-cps* (kname name-sym)
- ($letconst (('name name-sym name))
- ($continue k ($primcall 'define! (name-sym val))))))))
+ (let-gensyms (kname name-sym)
+ (build-cps-term
+ ($letconst (('name name-sym name))
+ ($continue k ($primcall 'define! (name-sym val)))))))))
(($ <call> src proc args)
(convert-args (cons proc args)
(match-lambda
((proc . args)
- (build-cps ($continue k ($call proc args)))))))
+ (build-cps-term ($continue k ($call proc args)))))))
(($ <primcall> src name args)
(if (branching-primitive? name)
@@ -398,7 +324,7 @@
k subst)
(convert-args args
(lambda (args)
- (build-cps ($continue k ($primcall name args)))))))
+ (build-cps-term ($continue k ($primcall name args)))))))
;; Prompts with inline handlers.
(($ <prompt> src escape-only? tag body
@@ -416,133 +342,137 @@
;;
;; Escape prompts evaluate the body with the continuation of krest.
;; Otherwise we do a no-inline call to body, continuing to krest.
- (convert-arg
- tag
- (lambda (tag)
- (let ((hnames (append hreq (if hrest (list hrest) '()))))
- (build-cps* (khargs khbody kret kprim prim kpop krest vals kbody)
- ($letk* ((khbody hsrc ($kargs hnames hsyms
- ,(fold box-bound-var
- (convert hbody k subst)
- hnames hsyms)))
- (khargs hsrc ($ktrunc hreq hrest khbody))
- (kpop src
- ($kargs ('rest) (vals)
- ($letk ((kret
- src
- ($kargs () ()
- ($letk ((kprim
- src
- ($kargs ('prim) (prim)
- ($continue k
- ($primcall 'apply
- (prim vals))))))
- ($continue kprim
- ($prim 'values))))))
- ($continue kret
- ($primcall 'pop-prompt ())))))
- (krest src ($ktrunc '() 'rest kpop)))
- ,(if escape-only?
- (build-cps
- ($letk ((kbody (tree-il-src body)
- ($kargs () ()
- ,(convert body krest subst))))
- ($continue kbody ($prompt #t tag khargs))))
- (convert-arg body
- (lambda (thunk)
- (build-cps
- ($letk ((kbody (tree-il-src body)
- ($kargs () ()
- ($continue krest
- ($primcall 'call-thunk/no-inline
- (thunk))))))
- ($continue kbody
- ($prompt #f tag khargs)))))))))))))
+ (convert-arg tag
+ (lambda (tag)
+ (let ((hnames (append hreq (if hrest (list hrest) '()))))
+ (let-gensyms (khargs khbody kret kprim prim kpop krest vals kbody)
+ (build-cps-term
+ ($letk* ((khbody hsrc ($kargs hnames hsyms
+ ,(fold box-bound-var
+ (convert hbody k subst)
+ hnames hsyms)))
+ (khargs hsrc ($ktrunc hreq hrest khbody))
+ (kpop src
+ ($kargs ('rest) (vals)
+ ($letk ((kret
+ src
+ ($kargs () ()
+ ($letk ((kprim
+ src
+ ($kargs ('prim) (prim)
+ ($continue k
+ ($primcall 'apply
+ (prim vals))))))
+ ($continue kprim
+ ($prim 'values))))))
+ ($continue kret
+ ($primcall 'pop-prompt ())))))
+ (krest src ($ktrunc '() 'rest kpop)))
+ ,(if escape-only?
+ (build-cps-term
+ ($letk ((kbody (tree-il-src body)
+ ($kargs () ()
+ ,(convert body krest subst))))
+ ($continue kbody ($prompt #t tag khargs))))
+ (convert-arg body
+ (lambda (thunk)
+ (build-cps-term
+ ($letk ((kbody (tree-il-src body)
+ ($kargs () ()
+ ($continue krest
+ ($primcall 'call-thunk/no-inline
+ (thunk))))))
+ ($continue kbody
+ ($prompt #f tag khargs))))))))))))))
;; Eta-convert prompts without inline handlers.
(($ <prompt> src escape-only? tag body handler)
- (convert-args
- (list tag body handler)
- (lambda (args)
- (build-cps
- ($continue k ($primcall 'call-with-prompt args))))))
+ (convert-args (list tag body handler)
+ (lambda (args)
+ (build-cps-term
+ ($continue k ($primcall 'call-with-prompt args))))))
(($ <abort> src tag args tail)
(convert-args (append (list tag) args (list tail))
- (lambda (args*)
- (build-cps ($continue k ($primcall 'abort args*))))))
+ (lambda (args*)
+ (build-cps-term ($continue k ($primcall 'abort args*))))))
(($ <conditional> src test consequent alternate)
- (build-cps* (kif kt kf)
- ($letk* ((kt (tree-il-src consequent) ($kargs () ()
- ,(convert consequent k subst)))
- (kf (tree-il-src alternate) ($kargs () ()
- ,(convert alternate k subst)))
- (kif src ($kif kt kf)))
- ,(match test
- (($ <primcall> src (? branching-primitive? name) args)
- (convert-args args
- (lambda (args)
- (build-cps ($continue kif ($primcall name args))))))
- (_ (convert-arg test
- (lambda (test)
- (build-cps ($continue kif ($var test))))))))))
+ (let-gensyms (kif kt kf)
+ (build-cps-term
+ ($letk* ((kt (tree-il-src consequent) ($kargs () ()
+ ,(convert consequent k subst)))
+ (kf (tree-il-src alternate) ($kargs () ()
+ ,(convert alternate k subst)))
+ (kif src ($kif kt kf)))
+ ,(match test
+ (($ <primcall> src (? branching-primitive? name) args)
+ (convert-args args
+ (lambda (args)
+ (build-cps-term ($continue kif ($primcall name args))))))
+ (_ (convert-arg test
+ (lambda (test)
+ (build-cps-term ($continue kif ($var test)))))))))))
(($ <lexical-set> src name gensym exp)
- (convert-arg
- exp
- (lambda (exp)
- (match (assq-ref subst gensym)
- ((box #t)
- (build-cps
- ($continue k ($primcall 'box-set! (box exp)))))))))
+ (convert-arg exp
+ (lambda (exp)
+ (match (assq-ref subst gensym)
+ ((box #t)
+ (build-cps-term
+ ($continue k ($primcall 'box-set! (box exp)))))))))
(($ <seq> src head tail)
- (build-cps* (ktrunc kseq)
- ($letk* ((kseq (tree-il-src tail) ($kargs () ()
- ,(convert tail k subst)))
- (ktrunc src ($ktrunc '() #f kseq)))
- ,(convert head ktrunc subst))))
+ (let-gensyms (ktrunc kseq)
+ (build-cps-term
+ ($letk* ((kseq (tree-il-src tail) ($kargs () ()
+ ,(convert tail k subst)))
+ (ktrunc src ($ktrunc '() #f kseq)))
+ ,(convert head ktrunc subst)))))
(($ <let> src names syms vals body)
(let lp ((names names) (syms syms) (vals vals))
(match (list names syms vals)
((() () ()) (convert body k subst))
(((name . names) (sym . syms) (val . vals))
- (build-cps* (klet)
- ($letk ((klet src ($kargs (name) (sym)
- ,(box-bound-var name sym
- (lp names syms vals)))))
- ,(convert val klet subst)))))))
+ (let-gensyms (klet)
+ (build-cps-term
+ ($letk ((klet src ($kargs (name) (sym)
+ ,(box-bound-var name sym
+ (lp names syms vals)))))
+ ,(convert val klet subst))))))))
(($ <fix> src names gensyms funs body)
;; Some letrecs can be contified; that happens later.
(if (current-topbox-scope)
- (build-cps* (self)
- ($letrec names
- gensyms
- (map (lambda (fun)
- (match (convert fun k subst)
- (($ $continue _ (and fun ($ $fun)))
- fun)))
- funs)
- ,(convert body k subst)))
- (build-cps* (scope kscope)
- ($letk ((kscope src ($kargs () ()
- ,(parameterize ((current-topbox-scope scope))
- (convert exp k subst)))))
- ,(capture-toplevel-scope src scope kscope)))))
+ (let-gensyms (self)
+ (build-cps-term
+ ($letrec names
+ gensyms
+ (map (lambda (fun)
+ (match (convert fun k subst)
+ (($ $continue _ (and fun ($ $fun)))
+ fun)))
+ funs)
+ ,(convert body k subst))))
+ (let-gensyms (scope kscope)
+ (build-cps-term
+ ($letk ((kscope src ($kargs () ()
+ ,(parameterize ((current-topbox-scope scope))
+ (convert exp k subst)))))
+ ,(capture-toplevel-scope src scope kscope))))))
(($ <let-values> src exp
($ <lambda-case> lsrc req () rest #f () syms body #f))
(let ((names (append req (if rest (list rest) '()))))
- (build-cps* (ktrunc kargs)
- ($letk* ((kargs src ($kargs names syms
- ,(fold box-bound-var
- (convert body k subst)
- names syms)))
- (ktrunc src ($ktrunc req rest kargs)))
- ,(convert exp ktrunc subst)))))))
+ (let-gensyms (ktrunc kargs)
+ (build-cps-term
+ ($letk* ((kargs src ($kargs names syms
+ ,(fold box-bound-var
+ (convert body k subst)
+ names syms)))
+ (ktrunc src ($ktrunc req rest kargs)))
+ ,(convert exp ktrunc subst))))))))
(define (build-subst exp)
"Compute a mapping from lexical gensyms to substituted gensyms. The
@@ -582,12 +512,13 @@ indicates that the replacement variable is in a box."
(define (cps-convert/thunk exp)
(let ((src (tree-il-src exp)))
- (build-cps* (init kentry kinit)
- ,(build-fun
+ (let-gensyms (init kentry kinit)
+ (build-cps-call
($fun '() init '()
- (($kentry kentry src ('() '() #f '() #f)
- (kinit src ($kargs () ()
- ,(cps-convert exp))))))))))
+ ((kentry src
+ ($kentry ('() '() #f '() #f)
+ (kinit src ($kargs () ()
+ ,(cps-convert exp)))))))))))
(define *comp-module* (make-fluid))