-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterp.rkt
110 lines (102 loc) · 2.54 KB
/
interp.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
#lang racket
(provide interp interp-env interp-prim1)
(require "ast.rkt"
"env.rkt"
"interp-prims.rkt")
;; type Answer = Value | 'err
;; type Value =
;; | Integer
;; | Boolean
;; | Character
;; | (Fun f)
;; | Eof
;; | Void
;; | '()
;; | (cons Value Value)
;; | (box Value)
;; type REnv = (Listof (List Id Value))
;; type Defns = (Listof Defn)
;; Prog Defns -> Answer
(define (interp p)
(match p
[(Prog ds e)
(interp-env e '() ds)]))
;; Expr Env Defns -> Answer
(define (interp-env e r ds)
(match e
[(Int i) i]
[(Bool b) b]
[(Char c) c]
[(Eof) eof]
[(Empty) '()]
[(Var x) (lookup r x)]
[(Prim0 'void) (void)]
[(Prim0 'read-byte) (read-byte)]
[(Prim0 'peek-byte) (peek-byte)]
[(Prim1 p e)
(match (interp-env e r ds)
['err 'err]
[v (interp-prim1 p v)])]
[(Prim2 p e1 e2)
(match (interp-env e1 r ds)
['err 'err]
[v1 (match (interp-env e2 r ds)
['err 'err]
[v2 (interp-prim2 p v1 v2)])])]
[(If p e1 e2)
(match (interp-env p r ds)
['err 'err]
[v
(if v
(interp-env e1 r ds)
(interp-env e2 r ds))])]
[(Begin e1 e2)
(match (interp-env e1 r ds)
['err 'err]
[_ (interp-env e2 r ds)])]
[(Let x e1 e2)
(match (interp-env e1 r ds)
['err 'err]
[v (interp-env e2 (ext r x v) ds)])]
[(App f es)
(match (interp-env* es r ds)
[(list vs ...)
(match (defns-lookup ds f)
[(Defn f xs body)
; arity check
(if (= (length vs) (length xs))
(interp-env body (zip xs vs) ds)
'err)])])]
[(Fun f)
(match (defns-lookup ds f)
[(Defn f xs body)
(lambda (es r)
(match (interp-env* es r ds)
[(list vs ...)
(if (= (length vs) (length xs))
(interp-env body (zip xs vs) ds)
'err)]))]
[_ 'err])]
[(FCall f es)
(match (interp-env f r ds)
[(? procedure? f) (f es r)]
[_ 'err])]
[_ 'err]))
;; (Listof Expr) REnv Defns -> (Listof Value) | 'err
(define (interp-env* es r ds)
(match es
['() '()]
[(cons e es)
(match (interp-env e r ds)
['err 'err]
[v (cons v (interp-env* es r ds))])]))
;; Defns Symbol -> Defn
(define (defns-lookup ds f)
(findf (match-lambda [(Defn g _ _) (eq? f g)])
ds))
(define (zip xs ys)
(match* (xs ys)
[('() '()) '()]
[((cons x xs) (cons y ys))
(cons (list x y)
(zip xs ys))]))