-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path4.1.7-ch4-analyzingmceval.scm
122 lines (101 loc) · 4.12 KB
/
4.1.7-ch4-analyzingmceval.scm
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
;;;;METACIRCULAR EVALUATOR THAT SEPARATES ANALYSIS FROM EXECUTION
;;;; FROM SECTION 4.1.7 OF STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS
;;;;Matches code in ch4.scm
;;;;This file can be loaded into Scheme as a whole.
;;;;**NOTE**This file loads the metacircular evaluator of
;;;; sections 4.1.1-4.1.4, since it uses the expression representation,
;;;; environment representation, etc.
;;;; You may need to change the (load ...) expression to work in your
;;;; version of Scheme.
;;;;**WARNING: Don't load mceval twice (or you'll lose the primitives
;;;; interface, due to renamings of apply).
;;;;Then you can initialize and start the evaluator by evaluating
;;;; the two lines at the end of the file ch4-mceval.scm
;;;; (setting up the global environment and starting the driver loop).
;;**implementation-dependent loading of evaluator file
;;Note: It is loaded first so that the section 4.1.7 definition
;; of eval overrides the definition from 4.1.1
(load "ch4-mceval.scm")
;;;SECTION 4.1.7
(define (eval expr env)
((analyze expr) env))
(define (analyze expr)
(cond ((self-evaluating? expr)
(analyze-self-evaluating expr))
((quoted? expr) (analyze-quoted expr))
((variable? expr) (analyze-variable expr))
((assignment? expr) (analyze-assignment expr))
((definition? expr) (analyze-definition expr))
((if? expr) (analyze-if expr))
((lambda? expr) (analyze-lambda expr))
((begin? expr) (analyze-sequence (begin-actions expr)))
((cond? expr) (analyze (cond->if expr)))
; Exercise 4.22 - will use Exercise 4.6 code in ch4-mceval.scm.
; this is IT! behold the power of derived expressions
((let? expr) (analyze (let->combination expr)))
((application? expr) (analyze-application expr))
(else
(error "Unknown expression type -- ANALYZE" expr))))
(define (analyze-self-evaluating expr)
(lambda (env) expr))
(define (analyze-quoted expr)
(let ((qval (text-of-quotation expr)))
(lambda (env) qval)))
(define (analyze-variable expr)
(lambda (env) (lookup-variable-value expr env)))
(define (analyze-assignment expr)
(let ((var (assignment-variable expr))
(vproc (analyze (assignment-value expr))))
(lambda (env)
(set-variable-value! var (vproc env) env)
'ok)))
(define (analyze-definition expr)
(let ((var (definition-variable expr))
(vproc (analyze (definition-value expr))))
(lambda (env)
(define-variable! var (vproc env) env)
'ok)))
(define (analyze-if expr)
(let ((pproc (analyze (if-predicate expr)))
(cproc (analyze (if-consequent expr)))
(aproc (analyze (if-alternative expr))))
(lambda (env)
(if (true? (pproc env))
(cproc env)
(aproc env)))))
(define (analyze-lambda expr)
(let ((vars (lambda-parameters expr))
(bproc (analyze-sequence (lambda-body expr))))
(lambda (env) (make-procedure vars bproc env))))
(define (analyze-sequence exps)
(define (sequentially proc1 proc2)
(lambda (env) (proc1 env) (proc2 env)))
(define (loop first-proc rest-procs)
(if (null? rest-procs)
first-proc
(loop (sequentially first-proc (car rest-procs))
(cdr rest-procs))))
(let ((procs (map analyze exps)))
(if (null? procs)
(error "Empty sequence -- ANALYZE"))
(loop (car procs) (cdr procs))))
(define (analyze-application expr)
(let ((fproc (analyze (operator expr)))
(aprocs (map analyze (operands expr))))
(lambda (env)
(execute-application (fproc env)
(map (lambda (aproc) (aproc env))
aprocs)))))
(define (execute-application proc args)
(cond ((primitive-procedure? proc)
(apply-primitive-procedure proc args))
((compound-procedure? proc)
((procedure-body proc)
(extend-environment (procedure-parameters proc)
args
(procedure-environment proc))))
(else
(error
"Unknown procedure type -- EXECUTE-APPLICATION"
proc))))
'ANALYZING-METACIRCULAR-EVALUATOR-LOADED