-
Notifications
You must be signed in to change notification settings - Fork 0
/
4.scm
140 lines (104 loc) · 3.61 KB
/
4.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
(define (eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp)(lookup-variable-value exp env))
((quoted? exp)(text-of-quotation exp))
((assignment? exp)(eval-assignment exp env))
((definition? exp)(eval-definition exp env))
((if? exp)(eval-if exp env))
((lambda? exp)
(make-procedure (lambda-parameters exp)
(lambda-body exp)
env))
((begin? exp)
(eval-sequence (begin-actions exp) env))
((cond? exp)(eval (cond->if exp) env))
((application? exp)
(apply (eval (operator exp) env)
(list-of-values (operands exp) env)))
(else
(errors "Unknown expression type --EVAL" exp))))
(define (apply procedure arguments)
(cond ((primitive-procedure? procedure)
(apply-primitive-procedure procedure arguments))
((compound-procedure? procedure)
(eval-sequence
(procedure-body procedure)
(extend-enviroment
(procedure-paramenters procedure)
arguments
(procedure-enviroment procedure))))
(else
(error
"Unknown procedure type --APPLY" procedure))))
(define (list-of-values exps env)
(if (no-operands? exps)
'()
(cons (eval (first-operand exps) env)
(list-of-values (rest-operands exps) env))))
(define (eval-if exp env)
(if (true? (eval (if-predicate exp) env))
(eval (if-consequent exp) env)
(eval (if-alternative exp) env)))
(define (eval-sequence exps env)
(cond ((last-exp? exps) (eval (first-exp exps) env))
(else (eval (first-exp exps) env)
(eval-sequence (rest-exps exps) env))))
(define (eval-assignment exp env)
(set-variable-value! (assignment-variable exp)
(eval (assignment-value exp ) env)
env)
'ok)
(define (eval-definition exp env)
(define-variable! (definition-variable exp)
(eval (definition-value exp) env)
env)
'ok)
(define (self-evaluating? exp)
(cond ((number? exp) true)
((string? exp) true)
(else false)))
(define (variable? exp)(symbol? exp))
(define (quoted? exp)(tagged-list? exp 'quote))
(define (text-of-quoteation exp)(cadr exp))
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
false))
(define (assignment? exp)
(tagged-list? exp 'set!))
(define (assigment-variable exp)(cadr exp))
(define (assigment-value exp)(caddr exp))
(define (definition? exp)
(tagged-list? exp 'define))
(define (definition-variable exp)
(if (symbol? (cadr exp))
(cadr exp)
(caadr exp)))
(define (definition-value exp)
(if (symbol? (cadr exp))
(caddr exp)
(make-lambda (cdadr exp)
(cddr exp))))
(define (lambda? exp)(tagged-list? exp 'lambda))
(define (lambda-parameters exp)(cadr exp))
(define (lambda-body exp)(cddr exp))
(define (make-lambda parameters body)
(cons 'lambda (cons parameters body)))
(define (if? exp)(tagged-list? exp 'if))
(define (if-predicate exp)(cadr exp))
(define (if-consequent exp)(caddr exp))
(define (if-alternative exp)
(if (not (null? (cdddr exp)))
(cadddr exp)
'false))
(define (make-if predicate consequent alternative)
(list 'if prdicate consequent alternvative))
(define (begin? exp)(tagged-list? exp 'begin))
(define (begin-actions exp)(cdr exp))
(define (last-exp? seq)(null? (cdr seq)))
(define (first-ex seq)(car seq))
(define (sequence->exp seq)
(cond ((null? seq) seq)
((last-exp? seq)(first-exp seq))
(else (make-begin seq))))
(define (make-begin seq)(cons 'begin seq))