TypeScript: setup initial environment
[jackhill/mal.git] / julia / step3_env.jl
1 #!/usr/bin/env julia
2
3 push!(LOAD_PATH, pwd(), "/usr/share/julia/base")
4 import readline_mod
5 import reader
6 import printer
7 using env
8
9 # READ
10 function READ(str)
11 reader.read_str(str)
12 end
13
14 # EVAL
15 function eval_ast(ast, env)
16 if typeof(ast) == Symbol
17 env_get(env,ast)
18 elseif isa(ast, Array) || isa(ast, Tuple)
19 map((x) -> EVAL(x,env), ast)
20 elseif isa(ast, Dict)
21 [EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
22 else
23 ast
24 end
25 end
26
27 function EVAL(ast, env)
28 if !isa(ast, Array) return eval_ast(ast, env) end
29 if isempty(ast) return ast end
30
31 # apply
32 if :def! == ast[1]
33 env_set(env, ast[2], EVAL(ast[3], env))
34 elseif symbol("let*") == ast[1]
35 let_env = Env(env)
36 for i = 1:2:length(ast[2])
37 env_set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
38 end
39 EVAL(ast[3], let_env)
40 else
41 el = eval_ast(ast, env)
42 f, args = el[1], el[2:end]
43 f(args...)
44 end
45 end
46
47 # PRINT
48 function PRINT(exp)
49 printer.pr_str(exp)
50 end
51
52 # REPL
53 repl_env = Env(nothing,
54 Dict{Any,Any}(:+ => +,
55 :- => -,
56 :* => *,
57 :/ => div))
58 function REP(str)
59 return PRINT(EVAL(READ(str), repl_env))
60 end
61
62 while true
63 line = readline_mod.do_readline("user> ")
64 if line === nothing break end
65 try
66 println(REP(line))
67 catch e
68 if isa(e, ErrorException)
69 println("Error: $(e.msg)")
70 else
71 println("Error: $(string(e))")
72 end
73 bt = catch_backtrace()
74 Base.show_backtrace(STDERR, bt)
75 println()
76 end
77 end