-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsection-5.5.5.rkt
54 lines (41 loc) · 1.6 KB
/
section-5.5.5.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#lang sicp
;; ex 5.33
;; The difference is how they handle the else clause. In the exercise,
;; it saves the env and goes on to compute factorial-alt. Later, the
;; env is restored to get the n to perform the multiplication. In the
;; text, it saves the argl which contains the correct n. Later, the
;; argl is restored to perform the multiplication.
;; Performance-wise the two are equal, because they have the same
;; amount of saves and restores.
;; ex 5.34
;; The essential difference is that the recursive call in recursive
;; version isn't the tail call, but the recursive call in iterative
;; version is. Therefore, the former has an extra 'save continue'.
;; ex 5.35
;; (define (f x) (+ x (g (+ x 2)))
;; ex 5.36
;; The order is right-to-left; it's determined in construct-arglist. To
;; evaluate in a left-to-right order, don't reverse the arglist and use append
;; instead of cons to join the list.
;; TODO ex 5.37
;; ex 5.38
(define (spread-arguments operands compile-env)
(list
(compile (car operands) 'arg1 'next compile-env)
(if (> (length operands) 2)
(compile (cons '+ (cdr operands)) 'arg2 'next compile-env)
(compile (cadr operands) 'arg2 'next compile-env))))
(define (compile-plus exp target linkage compile-env)
(let ((operand-codes (spread-arguments (operands exp) compile-env)))
(end-with-linkage
linkage
(preserving
'(env)
(car operand-codes)
(preserving
'(env arg1)
(cadr operand-codes)
(make-instruction-sequence
'(arg1 arg2)
(list target)
`((assign ,target (op +) (reg arg1) (reg arg2)))))))))