-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchap5.rkt
51 lines (43 loc) · 1.93 KB
/
chap5.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
#lang plai-typed
(define-type FunDefC
[fdC (name : symbol) (arg : symbol) (body : ExprC)])
(define-type ExprC
[numC (n : number)]
[idC (s : symbol)]
[appC (fun : symbol) (arg : ExprC)]
[plusC (l : ExprC) (r : ExprC)]
[multC (l : ExprC) (r : ExprC)])
(define (subst [what : number] [for : symbol] [in : ExprC]) : ExprC
(subst-helper (numC what) for in))
(define (subst-helper [what : ExprC] [for : symbol] [in : ExprC]) : ExprC
(type-case ExprC in
[numC (n) in]
[idC (s) (cond
[(symbol=? s for) what]
[else in])]
[appC (f a) (appC f (subst-helper what for a))]
[plusC (l r) (plusC (subst-helper what for l)
(subst-helper what for r))]
[multC (l r) (multC (subst-helper what for l)
(subst-helper what for r))]))
(define (get-fundef [n : symbol] [fds : (listof FunDefC)]) : FunDefC
(cond
[(empty? fds) (error 'get-fundef "reference to undefined function")]
[(cons? fds) (cond
[(equal? n (fdC-name (first fds))) (first fds)]
[else (get-fundef n (rest fds))])]))
(define (interp [e : ExprC] [fds : (listof FunDefC)]) : number
(type-case ExprC e
[numC (n) n]
[idC (_) (error 'interp "shouldn't get here")]
[appC (f a) (local ([define fd (get-fundef f fds)])
(interp (subst (interp a fds)
(fdC-arg fd)
(fdC-body fd))
fds))]
[plusC (l r) (+ (interp l fds) (interp r fds))]
[multC (l r) (* (interp l fds) (interp r fds))]))
(test (interp (appC 'quadruple (numC 5))
(list (fdC 'double 'x (plusC (idC 'x) (idC 'x)))
(fdC 'quadruple 'x (appC 'double (appC 'double (idC 'x))))))
20)