-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.rkt
140 lines (111 loc) · 3.49 KB
/
interpreter.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
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
#lang racket
(require "atom.rkt" "pairs.rkt" "table.rkt")
(define text-of second)
(define (initial-table name)
(car (quote ())))
(define (*const e table)
(cond
[(number? e) e]
[(eq? e #t) #t]
[(eq? e #f) #f]
[else (build-pair (quote primitive) e)]))
(define (*lambda e table)
(build-pair (quote non-primitive)
(cons table (cdr e))))
(define (*quote e table)
(text-of e))
(define cond-lines-of cdr)
(define (*cond e table)
(eval-cond (cond-lines-of e) table))
(define (*identifier e table)
(lookup-in-table e table initial-table))
(define function-of car)
(define arguments-of cdr)
(define (*application e table)
(apply
(meaning (function-of e) table)
(meaning (arguments-of e) table)))
(define table-of first)
(define formals-of second)
(define body-of third)
(define (expression-to-action e)
(cond
[(atom? e) (atom-to-action e)]
[else (list-to-action e)]))
(define (list-to-action e)
(cond
[(atom? (car e))
(cond
[(eq? (car e) (quote quote)) *quote]
[(eq? (car e) (quote lambda)) *lambda]
[(eq? (car e) (quote cond)) *cond]
[else *application])]
[else *application]))
(define (atom-to-action e)
(cond
[(number? e) *const]
[(eq? e #t) *const]
[(eq? e #f) *const]
[(eq? e (quote cons)) *const]
[(eq? e (quote car)) *const]
[(eq? e (quote cdr)) *const]
[(eq? e (quote null?)) *const]
[(eq? e (quote eq?)) *const]
[(eq? e (quote atom?)) *const]
[(eq? e (quote atom?)) *const]
[(eq? e (quote zero?)) *const]
[(eq? e (quote add1)) *const]
[(eq? e (quote sub1)) *const]
[(eq? e (quote number?)) *const]
[else *identifier]))
(define condition first)
(define action second)
(define (else? x)
(and (atom? x) (eq? x (quote else))))
(define (eval-cond lines table)
(cond
[(else? (condition (car lines)))
(meaning (action (car lines)) table)]
[(meaning (condition (car lines) table))
(meaning (action (car lines) table))]
[else (eval-cond (cdr lines) table)]))
(define (eval-list args table)
(cond
[(null? args) (quote ())]
[else (cons (meaning (car args) table) (eval-list (cdr args) table))]))
(define (primitive? l)
(eq? (first l) (quote primitive)))
(define (non-primitive? l)
(eq? (first l) (quote non-primitive)))
(define (:atom? arg)
(cond
[(atom? arg) #t]
[(null? arg #f)]
[(or (eq? arg (quote primitive)) (eq? (quote non-primitive)))]))
(define (apply-primitive funcs vals)
(cond
[(eq? funcs (quote cons)) (cons (first vals) (second vals))]
[(eq? funcs (quote cdr)) (cdr (first vals))]
[(eq? funcs (quote car)) (car (first vals))]
[(eq? funcs (quote null?)) (null? (first vals))]
[(eq? funcs (quote eq?)) (eq? (first vals) (second vals))]
[(eq? funcs (quote zero?)) (zero? (first vals))]
[(eq? funcs (quote add1)) (add1 (first vals))]
[(eq? funcs (quote sub1)) (sub1 (first vals))]
[(eq? funcs (quote atom?)) (:atom? (first vals))]
[(eq? funcs (quote number?)) (number? (first vals))]))
(define (apply-closure closure vals)
(meaning (body-of closure)
(extend-table
(new-entry
(formals-of closure)
vals)
(table-of closure))))
(define (apply f x)
(cond
[(primitive? f) (apply-primitive (second f) x)]
[(non-primitive? f) (apply-closure (second f) x)]))
(define (meaning e table)
((expression-to-action e) e table))
(define (value e)
(meaning e (quote ())))