-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.scm~
499 lines (427 loc) · 25.8 KB
/
interpreter.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
(require "classParser.scm")
;--------------------------------------------------------------------------------------------------------
;---------------------------Interpreter Implementation---------------------------------------------------
(define getFunctions cdddr)
; defining a function that takes an input file to be executed and returns a value
(define interpret
(lambda (filename classname)
(cond
((not (string? filename)) (error "File name must be a string!"))
(else (lookupvar 'M_state_return
(call/cc (lambda (return) (M_state_funcall '(funcall main) classname (run (parser filename) classname M_state_nullState '() '() '() '()) return '() '() '()))))))))
; abstractions
(define getFirst car)
(define getAfterFirst cdr)
(define getSecond cadr)
(define getAfterSecond cddr)
(define getThird caddr)
(define getAfterThird cdddr)
(define getFourth cadddr)
(define add cons)
(define addlayer cons)
(define emptyLayer '())
(define poplayer cdr)
(define topLayer car)
(define key car)
(define value getSecond)
(define M_state_nullState '(()))
(define addBinding cons)
(define bind list)
; defining a function for variable declaration so that it returns the state after the declaration statement
(define M_state_declaration
(lambda (dec type state return whileReturn throwReturn breakReturn)
(cond
((null? (getAfterSecond dec)) (M_state_Declaration_updateBinding (bind (getSecond dec) (box null)) state))
(else (M_state_Declaration_updateBinding (bind (getSecond dec) (box (M_value (getThird dec) type state return whileReturn throwReturn breakReturn))) state)))))
(define bind cons)
(define getInstance getSecond)
(define getVar getThird)
(define getInstanceFields getThird)
; defining a function that returns the value of an expression
(define M_value
(lambda (exp type state return whileReturn throwReturn breakReturn)
;(display exp) (newline)
(cond
((number? exp) exp)
((eq? exp '#t) 'true)
((eq? exp '#f) 'false)
((eq? exp 'true) 'true)
((eq? exp 'false) 'false)
((symbol? exp) (lookupvar exp state))
((eq? (getFirst exp) 'new) (bind 'instance (instanceClosure (getSecond exp) state)))
((eq? (getFirst exp) 'dot) (lookupvar (getVar exp) (list (getThird (getDotInstance (getInstance exp) state)))))
((and (null? (getAfterSecond exp)) (eq? (getFirst exp) '-)) (- 0 (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) '+) (+ (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn) (M_value (getThird exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) '-) (- (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn) (M_value (getThird exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) '*) (* (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn) (M_value (getThird exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) '/) (quotient (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn) (M_value (getThird exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) '%) (modulo (M_value (getSecond exp) type state return whileReturn throwReturn breakReturn) (M_value (getThird exp) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst exp) 'funcall) (lookupvar 'M_state_return (call/cc (lambda (return) (M_state_funcall exp type state return whileReturn throwReturn breakReturn)))))
((or (eq? (getFirst exp) '==)
(or (eq? (getFirst exp) '<)
(or (eq? (getFirst exp) '>)
(or (eq? (getFirst exp) '<=)
(or (eq? (getFirst exp) '>=)
(or (eq? (getFirst exp) '!=)
(or (eq? (getFirst exp) '&&)
(or (eq? (getFirst exp) '||)
(or (eq? (getFirst exp) '!)))))))))) (M_value (M_bool exp state return whileReturn throwReturn breakReturn) state))
(else (error "unknown operator")))))
; define a function that takes the instance component of a dot statement and return the instance closure
(define getDotInstance
(lambda (instance state)
(cond
((not (list? instance)) (lookupinstance instance state))
((and (list? instance) (eq? (getFirst instance) 'new)) (bind 'instance (instanceClosure (getSecond instance) state)))
(else (error "Invalid instance declaration statement")))))
(define getType cadr)
; define a function that looks up an instance in the state and return its instance closure
(define lookupinstance
(lambda (instance state)
(cond
((null? state) (error "Instance not found!"))
(else (lookupvar instance state)))))
; defining a function for assignment so that it returns a state after the assignment
; used box, defined (var (box)) as a binding
(define M_state_assignment
(lambda (asg type state return whileReturn throwReturn breakReturn)
(M_state_Assignment_updateBinding (bind (getSecond asg) (box (M_value (getThird asg) type state return whileReturn throwReturn breakReturn))) state)))
; defining a function for the return whileReturn throwReturn statement that returns the value of the expression being returned
(define M_state_return
(lambda (stmt type state return whileReturn throwReturn breakReturn)
(cond
((null? (getSecond stmt)) (error "Nothing to M_state_return"))
(else (M_state_Declaration_updateBinding (bind 'M_state_return (box (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn))) (poplayer state))))))
; defining a function for throw so that returns a state after throw
(define M_state_throw
(lambda (stmt state return whileReturn throwReturn breakReturn)
(cond
((null? (getSecond stmt)) (error "Nothing to M_state_throw"))
(else (M_state_Assignment_updateBinding (bind 'throw (box (M_value (getSecond stmt) state return whileReturn throwReturn breakReturn))) state)))))
; defining a function that returns a boolean based on the input statement
(define M_bool
(lambda (stmt type state return whileReturn throwReturn breakReturn)
(cond
((null? stmt) (error "Conditional statement needed!"))
((eq? stmt 'true) '#t)
((eq? stmt 'false) '#f)
((eq? stmt '#t) '#t)
((eq? stmt '#f) '#f)
((symbol? stmt) (M_bool (lookupvar stmt state) state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) '==) (= (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '<) (< (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '>) (> (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '>=) (>= (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '<=) (<= (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '!=) (not (= (M_value (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_value (getThird stmt) type state return whileReturn throwReturn breakReturn))))
((eq? (getFirst stmt) '&&) (and (M_bool (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_bool (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '||) (or (M_bool (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_bool (getThird stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) '!) (not (M_bool (getSecond stmt) type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) 'funcall) (lookupvar 'M_state_return (M_state_funcall stmt type state return whileReturn throwReturn breakReturn)))
(else (error "Invalid conditional statement!")))))
; defining a function that returns a state after an if statement
(define M_state_if
(lambda (stmt type state return whileReturn throwReturn breakReturn)
(cond
((M_bool (getSecond stmt) type state return whileReturn throwReturn breakReturn) (M_state (getThird stmt) state return whileReturn throwReturn breakReturn))
((null? (getAfterThird stmt)) state)
(else (M_state (getFourth stmt) type state return whileReturn throwReturn breakReturn)))))
; defining a function that takes an initial state and a list of statements and returns the final state after runing the statements in the list
(define run-cps
(lambda (stmtlis type state return whileReturn throwReturn breakReturn cpsreturn)
(cond
((null? stmtlis) (cpsreturn state))
((null? (getAfterFirst stmtlis)) (cpsreturn (M_state (getFirst stmtlis) type state return whileReturn throwReturn breakReturn)))
(else (cpsreturn (run-cps (getAfterFirst stmtlis) type (M_state (getFirst stmtlis) type state return whileReturn throwReturn breakReturn) return whileReturn throwReturn breakReturn cpsreturn))))))
; defining a wrapper for run-cps
(define run
(lambda (stmtlis type state return whileReturn throwReturn breakReturn)
(run-cps stmtlis type state return whileReturn throwReturn breakReturn (lambda (v) v))))
;defining a function that returns a state after a while statement
(define M_state_while-cps
(lambda (stmt state return whileReturn throwReturn breakReturn cpsreturn)
(cond
((definedInTopBinding (bind 'gotype 'break) state) (cpsreturn state))
((M_bool (getSecond stmt) state return whileReturn throwReturn breakReturn) (cpsreturn (M_state_while-cps stmt (run (getAfterSecond stmt) state return whileReturn throwReturn breakReturn) return whileReturn throwReturn breakReturn cpsreturn)))
(else (cpsreturn state)))))
; defining a function that returns boolean indicating whether the binding defined in top layer
(define definedInTopBinding
(lambda (binding state)
(equal? (assq (key binding) (topLayer state)) binding)))
;defining a wrapper for while-cps
(define M_state_while
(lambda (stmt state return whileReturn throwReturn breakReturn)
(M_state_while-cps stmt state return whileReturn throwReturn breakReturn (lambda (v) v))))
; defining a function that returns the state after storing a function
(define M_state_function
(lambda (func state)
(M_state_Declaration_function func state)))
; defining a function that returns the state after running a function
(define M_state_funcall
(lambda (funcallstat type state return whileReturn throwReturn breakReturn)
;(display funcallstat) (newline)
(cond
((null? (cdr state)) (run (getFourth (lookupfunc (getSecond funcallstat) (getFunctions (lookupclass type state)) type)) type (bindSuper (getSecond funcallstat) (bindThis (getSecond funcallstat) (createFuncLayer (getThird (lookupfunc (getSecond funcallstat) (getFunctions (lookupclass type state)))) (getAfterSecond funcallstat) (addlayer '() state)))) return whileReturn throwReturn breakReturn))
((null? (getAfterSecond funcallstat)) (run (getFourth (lookupfunc (getSecond funcallstat) state)) type (bindSuper (getSecond funcallstat) (bindThis (getSecond funcallstat) (addlayer '() state))) return whileReturn throwReturn breakReturn))
(else (run (getFourth (lookupfunc (getSecond funcallstat) state)) type (cons (getFirst (bindSuper (getSecond funcallstat) (bindThis (getSecond funcallstat) (createFuncLayer (getThird (lookupfunc (getSecond funcallstat) state)) (getAfterSecond funcallstat) (addlayer '() state))))) state) return whileReturn throwReturn breakReturn)))))
; defining a function that returns a function if defined or an error msg if not
(define lookupfunc
(lambda (name state type)
(display name) (display "--------") (display state) (newline)
(cond
((null? state) (error "Function not defined!"))
((list? name) (lookupfunc (getThird name) (getFunctions (lookupclass (getSecond (getDotInstance (getSecond name) state)) state))))
((and (assq 'function (topLayer state)) (equal? (getSecond (assq 'function (topLayer state))) name))
(assq 'function (topLayer state)))
((assq 'function (topLayer state)) (lookupfunc name (list (getAfterFirst (topLayer state)))))
(else (lookupfunc name (getAfterFirst state))))))
(define getInstanceName getSecond)
; defining a function that binds this to the instance
(define bindThis
(lambda (name state)
(cond
((and (list? name) (findvar 'this state)) state)
((and (list? name) (not (findvar 'this state))) (add (add (add 'this (getDotInstance (getInstanceName name) state)) (topLayer state)) (getAfterFirst state)))
(else state))))
; defining a function that binds super to the instance
(define bindSuper
(lambda (name state)
;(display name) (newline)
(cond
((and (list? name) (hasSuperclass name state)) (add (add (add 'super (bind 'instance (instanceClosure (getSuperclass name state) state))) (topLayer state)) (getAfterFirst state)))
(else state))))
; define a function that checks if the instance class has a superclass
(define hasSuperclass
(lambda (name state)
;(display (lookupclass (getInstanceName (getDotInstance (getInstanceName name) state)) state)) (newline)
(not (null? (getSecond (lookupclass (getInstanceName (getDotInstance (getInstanceName name) state)) state))))))
(define getSuperclassTerm getSecond)
(define getSuperclassName getSecond)
(define getSuperclass
(lambda (name state)
(getSuperclassName (getSuperclassTerm (lookupclass (getInstanceName (getDotInstance (getInstanceName name) state)) state)))))
(define returnit (lambda(v) v))
;defining a function that returns a state after a statement
(define M_state
(lambda (stmt type state return whileReturn throwReturn breakReturn)
;(display state) (newline) (newline)
(cond
((null? stmt) state)
((eq? (getFirst stmt) 'class) (M_state_Declaration_class (classClosure stmt state) state))
((eq? (getFirst stmt) 'var) (M_state_declaration stmt type state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) '=) (M_state_assignment stmt type state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) 'return) (return (M_state_return stmt type state return whileReturn throwReturn breakReturn)))
((eq? (getFirst stmt) 'throw) (if (null? throwReturn) (error "Error: throw not in try block") (throwReturn (M_state_throw stmt state return whileReturn throwReturn breakReturn))))
((eq? (getFirst stmt) 'if) (M_state_if stmt type state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) 'while) (returnit (call/cc (lambda (breakReturn) (M_state_while stmt (M_state_Declaration_updateBinding (bind 'gotype 0) state) return whileReturn throwReturn breakReturn)))))
((eq? (getFirst stmt) 'begin) (poplayer (call/cc (lambda (whileReturn) (run (getAfterFirst stmt) type (addlayer emptyLayer state) return whileReturn throwReturn breakReturn)))))
((eq? (getFirst stmt) 'continue) (whileReturn (M_state_Assignment_updateBinding (bind 'gotype 'continue) state)))
((eq? (getFirst stmt) 'break) (breakReturn (poplayer (M_state_Assignment_updateBinding (bind 'gotype 'break) state))))
((eq? (getFirst stmt) 'try) (M_state_try stmt type state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) 'function) (M_state_function stmt state))
((and (eq? (getFirst stmt) 'funcall) (eq? (getSecond stmt) 'main)) (M_state_funcall stmt type state return whileReturn throwReturn breakReturn))
((eq? (getFirst stmt) 'funcall) (call/cc (lambda (funcreturn) (M_state_funcall stmt type state funcreturn whileReturn throwReturn breakReturn))))
((eq? (getFirst stmt) 'static-function) (M_state_function (cons 'function (getAfterFirst stmt)) state))
(else (error "Invalid statements")))))
; Creates a proper layer of the function call
(define createFuncLayer
(lambda (paramlis inputlis state)
(cond
((paramMismatch paramlis inputlis) (error "Arity mismatch!"))
((null? paramlis) state)
((null? (getAfterFirst paramlis)) (M_state_Declaration_updateBinding (createBinding (getFirst paramlis) (getFirst inputlis) state) state))
(else (createFuncLayer (getAfterFirst paramlis) (getAfterFirst inputlis) (M_state_Declaration_updateBinding (createBinding (getFirst paramlis) (getFirst inputlis) state) state))))))
; Check if the parameter list and input list mismatch
(define paramMismatch
(lambda (l1 l2)
(cond
((not (eq? (listLength l1) (listLength l2))) #t)
(else #f))))
; Returns the length of a given list (number of elemnets)
(define listLength
(lambda (l)
(if (null? l)
0
(+ 1 (listLength (cdr l))))))
; Creates a binding for each parameter with respective input value
(define createBinding
(lambda (param input state)
(cond
((eq? input 'true) (add param (box 'true)))
((eq? input 'false) (add param (box 'false)))
(else (add param (box (M_value input null (poplayer state) '() '() '() '())))))))
; abstraction
(define tryBody getSecond)
(define catchBody getThird)
(define finalBody cadddr)
; defining a function for catch so that returns a state after catch
(define M_state_catch
(lambda (stmt state return whileReturn throwReturn breakReturn)
(if (null? stmt) state
(if (equal? (lookupvar 'throw state) 'none)
state
(run (catchBody stmt)
(M_state_Declaration_updateBinding (bind (catchVar stmt) (lookupvar 'throw state)) (cdr state))
return whileReturn throwReturn breakReturn)))))
; abstraction
(define finalStmt getSecond)
(define catchVar caadr)
(define catchStmt getThird)
; defining a function for finally so that returns a state after finally
(define M_state_final
(lambda (stmt state return whileReturn throwReturn breakReturn)
(if (null? stmt) state
(run (finalStmt stmt) state return whileReturn throwReturn breakReturn))))
; defining a function for try statement so that it returns a state after try statement
(define M_state_try
(lambda (stmt type state return whileReturn throwReturn breakReturn)
(M_state_final (finalBody stmt)
(M_state_catch (catchBody stmt) (call/cc (lambda (throwReturn)
(run (tryBody stmt) type (M_state_Declaration_updateBinding (bind 'throw (box 'none)) state) return whileReturn throwReturn breakReturn)))
return whileReturn throwReturn breakReturn)
return whileReturn throwReturn breakReturn)))
;----------------------------------------------------------------------------------------------------
;------------------------------------State Implementation--------------------------------------------
; the following are functions written to hide state implementation from the rest of interpreter
; This implementation of the state is a list of list of pairs, each list of pairs is a layer,
; each pair contains a variable name and its value
; defining a function that updates the bindings in a given state in a delaration statement
(define M_state_Declaration_updateBinding
(lambda (binding state)
(cond
((eq? (key binding) 'M_state_return) (cons (addBinding binding (topLayer state)) (getAfterFirst state)))
((assq (key binding) (topLayer state)) (error "Variable already declared"))
(else (cons (addBinding binding (topLayer state)) (getAfterFirst state))))))
; defining a function that declares functions
(define M_state_Declaration_function
(lambda (function state)
(add (add function (topLayer state)) (getAfterFirst state))))
; defining a class that declares classes
(define M_state_Declaration_class
(lambda (class state)
;(display state) (newline)
(add (add class (topLayer state)) (getAfterFirst state))))
(define key car)
(define getInstanceName getSecond)
(define getInstanceFieldName getThird)
(define getFields getFourth)
; defining a function that updates the bindings in a given state in a assignment statement
(define M_state_Assignment_updateBinding-cps
(lambda (binding state cpsreturn)
;(display binding) (newline)
(cond
((null? state) (cpsreturn (error "Variable not declared")))
; if the key of the binding is a dot component
((list? (key binding)) (cpsreturn (updateBox (assq (getInstanceFieldName (key binding)) (getFields (getDotInstance (getInstanceName (key binding)) state))) binding state)))
;if the variable is already declared, update the box
((assq (key binding) (topLayer state)) (cpsreturn (updateBox (assq (key binding) (topLayer state)) binding state)))
(else (M_state_Assignment_updateBinding-cps binding (getAfterFirst state) (lambda (v) (cpsreturn (cons (topLayer state) v))))))))
; if the box has been updated, return the state
(define updateBox
(lambda (oldbinding newbinding state)
;(display oldbinding) (newline)
(begin (set-box! (getAfterFirst oldbinding) (unbox (getAfterFirst newbinding))) state)))
; defining a wrapper for M_State_Assignment_updateBinding-cps
(define M_state_Assignment_updateBinding
(lambda (binding state)
(M_state_Assignment_updateBinding-cps binding state (lambda(v) v))))
; defining a function that returns a value of a variable if initialized or an error message if not
(define lookupvar
(lambda (var state)
;(display (and (findvar var state) (box? (getAfterFirst (findvar var state))))) (newline)
;(display var) (display " ----- ") (display state) (newline) (newline)
(cond
((and (findvar var state) (box? (getAfterFirst (findvar var state)))) (unbox (getAfterFirst (findvar var state))))
((findvar var state) (getAfterFirst (findvar var state)))
((findvar var (list (getThisFields state))) (unbox (getAfterFirst (findvar var (list (getThisFields state))))))
((error "Variable not declared!")))))
(define getThisFields
(lambda (state)
;(display (lookupvar 'this (topLayer state))) (newline)
(getThird (lookupvar 'this state))))
; defining a function that adds a binding if the top layer does not contain it and return error if it is already declared in the top layer
(define declareLocalVar
(lambda (binding state)
(cond
((assq (key binding) (topLayer state)) (error "Local variable already declared!"))
(else (M_state_Declaration_updateBinding binding state)))))
; defining a function that finds the binding of the variable in state
(define findvar-cps
(lambda (var state cpsreturn)
;(display state) (newline) (newline)
(cond
((null? state) (cpsreturn #f))
((assq var (topLayer state)) (cpsreturn (assq var (topLayer state))))
(else (cpsreturn (findvar-cps var (getAfterFirst state) cpsreturn))))))
; defining a wrapper for findvar-cps
(define findvar
(lambda (var state)
(findvar-cps var state (lambda(v) v))))
;---------------------------part4----------------------------------
;------------------------------------------------------------------
(define cadaddr
(lambda (lis)
(car (cdaddr lis))))
(define getName getSecond)
(define getSuperClass getThird)
(define getBody getFourth)
(define combine cons)
;define a function that returns the closure of a given class
;parent class, list of instance fields, list of methods/function names and closures
(define classClosure
(lambda (stmt state)
;(display stmt) (newline)
(list (getName stmt) (getSuperClass stmt) (parseFields (getBody stmt)) (parseFunctions (getBody stmt)))))
;define a function that parses the superclass
(define parseSuperClass
(lambda (superclass)
(cond
((null? superclass) '())
((eq? (getFirst superclass) 'extends) (getSecond superclass))
(else (error "Superclass format error!")))))
(define getType car)
(define add cons)
(define getTail cdr)
;define a function that parses all the fields in a class and returns a list of them
(define parseFields
(lambda (body)
(cond
((null? body) '())
((and (eq? (getType (getFirst body)) 'var) (null? (getAfterSecond (getFirst body)))) (add (add (getSecond (getFirst body)) null) (parseFields (getTail body))))
((eq? (getType (getFirst body)) 'var) (add (add (getSecond (getFirst body)) (getThird (getFirst body))) (parseFields (getTail body))))
(else (parseFields (getTail body))))))
;define a function that prases all the functions in a class and returns a list of them
(define parseFunctions
(lambda (body)
(cond
((null? body) '())
((or (eq? (getType (getFirst body)) 'function) (eq? (getType (getFirst body)) 'static-function))
(add (add 'function (getAfterFirst (getFirst body))) (parseFunctions (getTail body))))
(else (parseFunctions (getTail body))))))
(define getFields getThird)
(define combine list)
;define a function that returns the closure of a given instance of a class
;instance closure: instance's class and a list of instance field values
(define instanceClosure
(lambda (class state)
(combine class (boxFields (getFields (lookupclass class state))))))
; define a function that boxes all the instance fields
(define bind cons)
(define key car)
(define value cdr)
(define boxFields
(lambda (fieldLis)
(cond
((null? fieldLis) '())
(else (bind (bind (key (getFirst fieldLis)) (box (value (getFirst fieldLis)))) (boxFields (getAfterFirst fieldLis)))))))
(define getClassName caaar)
(define getClass caar)
(define getTailClasses cdr)
; defining a function that lookup a class and return the class closure
(define lookupclass
(lambda (name state)
;(display name) (newline)
(cond
((null? state) (error "Class not defined!"))
((assq name (topLayer state)) (assq name (topLayer state)))
(else (lookupclass name (getTailClasses state))))))