This repository has been archived by the owner on May 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
evaluator.py
76 lines (54 loc) · 1.45 KB
/
evaluator.py
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
import sys
from environment import Env
from environment import add_globals
def check_string(x):
if isinstance(x, str):
return x[0] == x[-1] == '"' or not '"' in x[1:-2]
else:
return False
def my_eval(x, env):
# Check symbol ?
if isinstance(x, str):
return env.find(x)[x]
# Check atom ?
elif not isinstance(x, list):
return x
# (quote exp)
elif x[0] == 'quote':
(_, exp) = x
return exp
# (if test conseq alt)
elif x[0] == 'if':
(_, test, conseq, alt) = x
if my_eval(test, env):
return my_eval(conseq, env)
else:
return my_eval(alt, env)
# (set! var exp)
elif x[0] == 'set!':
(_, var, exp) = x
env.find(var)[var] = my_eval(exp, env)
# (define var exp)
elif x[0] == 'define':
(_, var, exp) = x
if check_string(exp):
env[var] = exp
else:
env[var] = my_eval(exp, env)
# (lambda (var*) exp)
elif x[0] == 'lambda':
(_, vars, exp) = x
return lambda *args: my_eval(exp, Env(vars, args, env))
# (exit)
elif x[0] == 'exit':
sys.exit("bye")
# (begin exp*)
elif x[0] == 'begin':
for exp in x[1:]:
val = my_eval(exp, env)
return val
# (proc exp*)
else:
exps = [my_eval(exp, env) for exp in x]
proc = exps.pop(0)
return proc(*exps)