-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path2-lookup-in-environment.rkt
103 lines (80 loc) · 1.64 KB
/
2-lookup-in-environment.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
#lang racket
(define (lookup env s)
(match env
[(list (cons name val) rest ...)
(if (equal? name s)
val
(lookup rest s))]
[(list)
(error 'unknown (~a s))]))
(define primitives
(list (cons '+ +)
(cons '- -)
(cons '/ /)
(cons '* *)))
(define (eval-application env fun args)
(apply (eval-exp env fun)
(map (λ (x) (eval-exp env x)) args)))
(define (eval-exp env exp)
(match exp
[(? symbol?) (lookup env exp)]
[(? number?) exp]
[(list fun args ...) (eval-application env fun args)]
[_ (error 'wat (~a exp))]))
(define (evaluate input)
(eval-exp primitives input))
(define (repl)
(printf "> ")
(define input (read))
(unless (eof-object? input)
(define output (evaluate input))
(printf "~a~n" output)
(repl)))
(module+ test
(require rackunit)
(check-equal?
(evaluate '(+ 1 2))
3)
(check-equal?
(evaluate '(+ 1 2 3))
6)
(check-equal?
(evaluate '(- 2 1))
1)
(check-equal?
(evaluate '(* 2 4))
8)
(check-equal?
(evaluate '(/ 8 2))
4)
(check-equal?
(evaluate '(* 2 (+ 1 (- 4 2))))
6)
(check-exn
exn:fail?
(λ ()
(eval '(foo 1 2))))
(check-equal?
(lookup (list (cons 'a 1)
(cons 'b 2))
'a)
1)
(check-equal?
(lookup (list (cons 'a 1)
(cons 'b 2))
'b)
2)
(check-equal?
(lookup (list (cons 'a 0)
(cons 'a 1)
(cons 'b 2))
'a)
0)
(check-exn
exn:fail?
(λ ()
(lookup (list (cons 'a 1)
(cons 'b 2))
'c))
0)
)