227 lines
4.4 KiB
Plaintext
227 lines
4.4 KiB
Plaintext
; Function of multiple moderately-complex arguments:
|
|
(define (g x y z) ...)
|
|
(lambda (x f y h z) (g x (f y) (h z)))
|
|
|
|
; Same thing in functional continuation-passing form:
|
|
(define (g x y z) ...)
|
|
(lambda (k x f y h z)
|
|
(let [(g1 (lambda (_ fy)
|
|
(let [(g2 (lambda (_ hz)
|
|
(g k x fy hz)))]
|
|
(h g2 z))]
|
|
(f g1 y)))
|
|
|
|
; Internal form:
|
|
#S(lambda
|
|
; globals
|
|
#(
|
|
#S(template ; g1
|
|
; globals
|
|
#(
|
|
#S(template ; g1
|
|
#(#S(lambda ...)) ; globals (g1=g)
|
|
#B(i0 i1 f0) ; instance vars (i0-i2)
|
|
1 ; frame vars (f0)
|
|
#B( ; code
|
|
(set! f0 (car argv))
|
|
(set! f0 (cons f0 nil))
|
|
(set! f0 (cons i2 f0))
|
|
(set! f0 (cons i1 f0)) ; (list x fy hz)
|
|
)
|
|
g1 ; tail-call
|
|
f0 ; arguments
|
|
ctx ; dynamic context
|
|
i0 ; continuation
|
|
)
|
|
)
|
|
#(k f0 f3 f4) ; instance vars (i0-i3)
|
|
3 ; frame vars (f0-f2)
|
|
#B( ; code
|
|
(set! f0 (car argv))
|
|
(set! f1 (cons i3 nil)) ; (list z)
|
|
(set! f2 (lambda g1))
|
|
)
|
|
i2 ; tail-call
|
|
f1 ; arguments
|
|
ctx ; dynamic context
|
|
f2 ; continuation
|
|
)
|
|
)
|
|
#() ; instance vars
|
|
7 ; frame vars (f0-f6)
|
|
#B( ; code
|
|
(set! f0 (car argv)) ; x
|
|
(set! f5 (cdr argv))
|
|
(set! f1 (car f5)) ; f
|
|
(set! f5 (cdr f5))
|
|
(set! f2 (car f5)) ; y
|
|
(set! f5 (cdr f5))
|
|
(set! f3 (car f5)) ; h
|
|
(set! f5 (cdr f5))
|
|
(set! f4 (car f5)) ; z
|
|
(set! f5 (cons f2 nil)) ; (list y)
|
|
(set! f6 (lambda g1))
|
|
)
|
|
f1 ; tail-call
|
|
f5 ; arguments
|
|
ctx ; dynamic context
|
|
f6 ; continuation
|
|
)
|
|
|
|
=================================================
|
|
|
|
; Function w/ conditional behavior
|
|
(let [(add1 (lambda (x) (+ 1 x)))]
|
|
(lambda (x y)
|
|
(if x
|
|
(add1 x)
|
|
y))
|
|
|
|
; CPS
|
|
(let [(add1 (lambda (k x) (k (+ 1 x))))]
|
|
(lambda (k x y)
|
|
(let [(f0 (if' x
|
|
(lambda (k') (add1 k' x))
|
|
(lambda (k') (k' y))))]
|
|
(f0 k))))
|
|
|
|
; Internal form
|
|
#S(lambda
|
|
#(
|
|
#S(template ; g1
|
|
#(
|
|
#S(lambda ; g1 = add1
|
|
#(1)
|
|
#()
|
|
1
|
|
#B(
|
|
(set! f0 (car argv))
|
|
(set! f0 (fix+ f0 g1))
|
|
(set! f0 (cons f0 nil))
|
|
)
|
|
k
|
|
f0
|
|
ctx
|
|
nil
|
|
)
|
|
)
|
|
#B(f0)
|
|
1 ; f0
|
|
#B(
|
|
(set! f0 (cons i0 nil))
|
|
)
|
|
g1
|
|
f0
|
|
ctx
|
|
k
|
|
)
|
|
#S(template ; g2
|
|
#(#f)
|
|
#B(f0)
|
|
1 ; f0
|
|
#B(
|
|
(set! f0 (cons i0 nil))
|
|
)
|
|
k
|
|
f0
|
|
g1
|
|
g1
|
|
)
|
|
)
|
|
#()
|
|
3 ; f0-f2
|
|
#B(
|
|
(set! f0 (car argv))
|
|
(set! f1 (cdr argv))
|
|
(set! f1 (car f1))
|
|
(set! f2 (if f0 g1 g2))
|
|
(set! f2 (lambda f2))
|
|
)
|
|
f2
|
|
nil
|
|
ctx
|
|
k
|
|
)
|
|
|
|
=================================================
|
|
|
|
; Recursive function
|
|
(define fact
|
|
(lambda (n)
|
|
(if (< n 1)
|
|
1
|
|
(* n (fact (- n 1))))))
|
|
|
|
; CPS
|
|
(letrec [(fact (lambda (k n)
|
|
((if' (< n 1)
|
|
(lambda (k') (k' 1))
|
|
(lambda (k')
|
|
(let (k'' (lambda (_ m)
|
|
(k' (* n m))))
|
|
(fact k'' (- n 1)))))
|
|
k)))])
|
|
|
|
; Internal
|
|
#0=#S(lambda
|
|
#(
|
|
#S(lambda ; g1 = (lambda (k) (k 1))
|
|
#(1 #f) ; g1 = 1; g2 = #f
|
|
#() ; instance
|
|
1 ; frame (f0)
|
|
#B(
|
|
(set! f0 (cons g1 nil))
|
|
)
|
|
k ; tail-call
|
|
f0 ; arguments
|
|
g2 ; dynamic context
|
|
g2 ; continuation
|
|
)
|
|
#S(template ; g2 = (lambda (k) ...)
|
|
#(
|
|
#=0 ; g1 = fact
|
|
#S(template ; g2 = (lambda (_ m) (k (* n m)))
|
|
#(#f) ; globals
|
|
#B(i0 k) ; instance (i0=n, i1=k)
|
|
1 ; frame (f0)
|
|
#B(
|
|
(set! f0 (car argv))
|
|
(set! f0 (fix* i0 f0))
|
|
(set! f0 (cons f0 nil))
|
|
)
|
|
i1
|
|
f0
|
|
g1
|
|
g1
|
|
)
|
|
1 ; g3 = 1
|
|
)
|
|
#B(f0) ; instance (i0 = parent->f0 = n)
|
|
1 ; frame (f0)
|
|
#B(
|
|
(set! f0 (fix- i0 g3))
|
|
(set! f0 (cons f0 nil))
|
|
)
|
|
g1
|
|
f0
|
|
ctx
|
|
g2
|
|
)
|
|
1 ; g3 = 1
|
|
)
|
|
#() ; instance
|
|
2 ; frame (f0-f1)
|
|
#B(
|
|
(set! f0 (car argv))
|
|
(set! f1 (fix< f0 g3))
|
|
(set! f1 (if f1 g1 g2))
|
|
(set! f1 (lambda f1))
|
|
)
|
|
f1
|
|
nil
|
|
ctx
|
|
k
|
|
)
|
|
|
|
# vim:set sw=2 expandtab:
|