-
Notifications
You must be signed in to change notification settings - Fork 0
/
datatypes.ss
145 lines (137 loc) · 4.25 KB
/
datatypes.ss
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
141
142
143
144
145
;; Parsed expression datatypes
(define (void? x) (equal? x (void)))
(define (lit? x)
(lambda (x)
(ormap
(lambda (pred) (pred x))
(list number? vector? boolean? symbol? string? pair? null? void?))))
(define-datatype expression expression?
[var-exp ; variable references
(id symbol?)]
[lit-exp ; "Normal" data
(datum lit?)]
[lambda-exp
(re-params (list-of symbol?)) ;; required params
(op-params (lambda (p) (or (eq? #f p) (symbol? p)))) ;; optional params
(bodies (list-of expression?))]
[ref-lambda-exp
(params (list-of
(lambda (v) (or (symbol? v) (data-type? 'ref v)))))
(bodies (list-of expression?))]
[if-exp
(condition expression?)
(true-body expression?)
(false-body expression?)]
[define-exp
(id symbol?)
(val expression?)]
[set!-exp
(id symbol?)
(val expression?)]
[ref-exp
(id symbol?)]
[let-exp ; let, let*
(type symbol?)
(vars (list-of symbol?))
(values (list-of expression?))
(bodies (list-of expression?))]
[begin-exp
(bodies (list-of expression?))]
[and-exp
(conditions (list-of expression?))]
[or-exp
(conditions (list-of expression?))]
[case-exp
(key expression?)
(patterns (list-of list?))
(bodiess (list-of (list-of expression?)))]
[cond-exp
(conditions (list-of expression?))
(bodiess (list-of (list-of expression?)))]
[while-exp
(condition expression?)
(bodies (list-of expression?))]
[app-exp ; application
(rator expression?)
(rands (list-of expression?))])
;; environment type definitions
(define (scheme-value? x)
#t)
(define-datatype environment environment?
[empty-env-record]
[extended-env-record
(syms (list-of symbol?))
(vals (list-of scheme-value?))
(env environment?)])
;; datatype for procedures
(define-datatype proc-val proc-val?
[prim-proc
(name symbol?)]
[closure
(re-params (list-of symbol?))
(op-params (lambda (p) (or (eq? #f p) (symbol? p))))
(bodies (list-of expression?))
(env environment?)]
[ref-closure
(params (list-of (lambda (v) (or (symbol? v) (data-type? 'ref v)))))
(bodies (list-of expression?))
(env environment?)])
;; continuation datatype
(define-datatype continuation continuation?
[identity-k]
[if-k
(true-exp expression?)
(false-exp expression?)
(env environment?)
(k continuation?)]
[rator-k
(rands (list-of? expression?))
(env environment?)
(k continuation?)]
[rands-k
(proc-value scheme-value?)
(k continuation?)])
(define (apply-k k val)
(cases continuation k
[identity-k () val]
[if-k (true-exp false-exp env k)
(if val
(eval-exp true-exp env k)
(eval-exp false-exp env k))]
[rator-k (rands env k)
(eval-rands rands
env
(rands-k val k))]
[rands-k (proc-value k)
(apply-proc proc-value val k)]))
;; Check if datum is of a define datatype
(define (data-type? type datum)
(cond
[(expression? datum)
(cases expression datum
[lit-exp (datum) (eq? 'lit type)]
[var-exp (id) (eq? 'var type)]
[lambda-exp (re-params op-params bodies) (eq? 'lambda type)]
[ref-lambda-exp (params bodies) (eq? 'ref-lambda type)]
[if-exp (condition true-body false-body) (eq? 'if type)]
[define-exp (id val) (eq? 'define type)]
[set!-exp (id val) (eq? 'set! type)]
[ref-exp (id) (eq? 'ref type)]
[let-exp (type vars values bodies) (eq? 'let type)]
[begin-exp (bodies) (eq? 'begin type)]
[and-exp (conditions) (eq? 'and type)]
[or-exp (conditions) (eq? 'or type)]
[case-exp (key patterns bodiess) (eq? 'case type)]
[cond-exp (conditions bodiess) (eq? 'cond type)]
[while-exp (condition bodies) (eq? 'while type)]
[app-exp (rator rands) (eq? 'app type)]
[else
#f])]
[(proc-val? datum)
(cases proc-val datum
[prim-proc (name) (eq? 'prim-proc type)]
[closure (re-params op-params bodies env) (eq? 'closure type)]
[ref-closure (params bodies env) (eq? 'ref-closure type)]
[else
#f])]
[else #f]))