forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstep3_env.jl
executable file
·77 lines (69 loc) · 1.64 KB
/
step3_env.jl
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
#!/usr/bin/env julia
push!(LOAD_PATH, pwd(), "/usr/share/julia/base")
import readline_mod
import reader
import printer
using env
# READ
function READ(str)
reader.read_str(str)
end
# EVAL
function eval_ast(ast, env)
if typeof(ast) == Symbol
env_get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end
end
function EVAL(ast, env)
if !isa(ast, Array) return eval_ast(ast, env) end
if isempty(ast) return ast end
# apply
if :def! == ast[1]
env_set(env, ast[2], EVAL(ast[3], env))
elseif symbol("let*") == ast[1]
let_env = Env(env)
for i = 1:2:length(ast[2])
env_set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
end
EVAL(ast[3], let_env)
else
el = eval_ast(ast, env)
f, args = el[1], el[2:end]
f(args...)
end
end
# PRINT
function PRINT(exp)
printer.pr_str(exp)
end
# REPL
repl_env = Env(nothing,
Dict{Any,Any}(:+ => +,
:- => -,
:* => *,
:/ => div))
function REP(str)
return PRINT(EVAL(READ(str), repl_env))
end
while true
line = readline_mod.do_readline("user> ")
if line === nothing break end
try
println(REP(line))
catch e
if isa(e, ErrorException)
println("Error: $(e.msg)")
else
println("Error: $(string(e))")
end
bt = catch_backtrace()
Base.show_backtrace(STDERR, bt)
println()
end
end