crystal: add seq and string?
[jackhill/mal.git] / julia / step4_if_fn_do.jl
CommitLineData
3e60110d
JM
1#!/usr/bin/env julia
2
82484631 3push!(LOAD_PATH, pwd(), "/usr/share/julia/base")
85110962 4import readline_mod
3e60110d
JM
5import reader
6import printer
7using env
8import core
9
10# READ
11function READ(str)
12 reader.read_str(str)
13end
14
15# EVAL
16function eval_ast(ast, env)
17 if typeof(ast) == Symbol
82484631 18 env_get(env,ast)
3e60110d
JM
19 elseif isa(ast, Array) || isa(ast, Tuple)
20 map((x) -> EVAL(x,env), ast)
7e0bb668
JM
21 elseif isa(ast, Dict)
22 [EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
3e60110d
JM
23 else
24 ast
25 end
26end
27
28function EVAL(ast, env)
7e0bb668 29 if !isa(ast, Array) return eval_ast(ast, env) end
3e60110d
JM
30
31 # apply
32 if :def! == ast[1]
82484631 33 env_set(env, ast[2], EVAL(ast[3], env))
3e60110d 34 elseif symbol("let*") == ast[1]
7e0bb668 35 let_env = Env(env)
3e60110d 36 for i = 1:2:length(ast[2])
82484631 37 env_set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
3e60110d
JM
38 end
39 EVAL(ast[3], let_env)
40 elseif :do == ast[1]
41 eval_ast(ast[2:end], env)[end]
42 elseif :if == ast[1]
43 cond = EVAL(ast[2], env)
44 if cond === nothing || cond === false
45 if length(ast) >= 4
46 EVAL(ast[4], env)
47 else
48 nothing
49 end
50 else
51 EVAL(ast[3], env)
52 end
53 elseif symbol("fn*") == ast[1]
f98e3ea9 54 (args...) -> EVAL(ast[3], Env(env, ast[2], Any[args...]))
3e60110d
JM
55 else
56 el = eval_ast(ast, env)
57 f, args = el[1], el[2:end]
58 f(args...)
59 end
60end
61
62# PRINT
63function PRINT(exp)
64 printer.pr_str(exp)
65end
66
67# REPL
68repl_env = nothing
69function REP(str)
70 return PRINT(EVAL(READ(str), repl_env))
71end
72
73# core.jl: defined using Julia
74repl_env = Env(nothing, core.ns)
75
76# core.mal: defined using the language itself
77REP("(def! not (fn* (a) (if a false true)))")
78
79while true
85110962
JM
80 line = readline_mod.do_readline("user> ")
81 if line === nothing break end
3e60110d
JM
82 try
83 println(REP(line))
84 catch e
85 if isa(e, ErrorException)
86 println("Error: $(e.msg)")
87 else
88 println("Error: $(string(e))")
89 end
82484631
JM
90 if !isa(e, StackOverflowError)
91 bt = catch_backtrace()
92 Base.show_backtrace(STDERR, bt)
93 end
3e60110d
JM
94 println()
95 end
96end