forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstep2_eval.io
52 lines (44 loc) · 1.22 KB
/
step2_eval.io
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
MalTypes
MalReader
READ := method(str, MalReader read_str(str))
eval_ast := method(ast, env,
(ast type) switch(
"MalSymbol", env at(ast val) ifNil(Exception raise("'" .. (ast val) "' not found")),
"MalList", MalList with(ast map(a, EVAL(a, env))),
"MalVector", MalVector with(ast map(a, EVAL(a, env))),
"MalMap",
m := MalMap clone
ast foreach(k, v,
keyObj := MalMap keyToObj(k)
m atPut(MalMap objToKey(EVAL(keyObj, env)), EVAL(v, env))
)
m,
ast
)
)
EVAL := method(ast, env,
if(ast type != "MalList", return(eval_ast(ast, env)))
if(ast isEmpty, return ast)
el := eval_ast(ast, env)
f := el at(0)
args := el rest
f callWithArgList(args)
)
PRINT := method(exp, exp malPrint(true))
repl_env := Map with(
"+", block(a, b, a + b),
"-", block(a, b, a - b),
"*", block(a, b, a * b),
"/", block(a, b, a / b)
)
RE := method(str, EVAL(READ(str), repl_env))
REP := method(str, PRINT(RE(str)))
loop(
line := MalReadline readLine("user> ")
if(line isNil, break)
if(line isEmpty, continue)
e := try(REP(line) println)
e catch(Exception,
("Error: " .. (e error)) println
)
)