1 require_relative
"mal_readline"
2 require_relative
"types"
3 require_relative
"reader"
4 require_relative
"printer"
6 require_relative
"core"
15 return sequential
?(x
) && x
.size
> 0
20 return List
.new
[:quote, ast
]
21 elsif ast
[0] == :unquote
23 elsif pair
?(ast
[0]) && ast
[0][0] == :"splice-unquote"
24 return List
.new
[:concat, ast
[0][1], quasiquote(ast
.drop(1))]
26 return List
.new
[:cons, quasiquote(ast
[0]), quasiquote(ast
.drop(1))]
30 def macro_call
?(ast
, env)
31 return (ast
.is_a
?(List
) &&
32 ast
[0].is_a
?(Symbol
) &&
34 env.get(ast
[0]).is_a
?(Function
) &&
35 env.get(ast
[0]).is_macro
)
38 def macroexpand(ast
, env)
39 while macro_call
?(ast
, env)
41 ast
= mac
[*ast
.drop(1)]
46 def eval_ast(ast
, env)
51 List
.new ast
.map
{|a
| EVAL(a
, env)}
53 Vector
.new ast
.map
{|a
| EVAL(a
, env)}
56 ast
.each
{|k
,v
| new_hm
[EVAL(k
,env)] = EVAL(v
, env)}
66 #puts "EVAL: #{_pr_str(ast, true)}"
69 return eval_ast(ast
, env)
73 ast
= macroexpand(ast
, env)
75 return eval_ast(ast
, env)
84 return env.set(a1
, EVAL(a2
, env))
86 let_env
= Env
.new(env)
87 a1
.each_slice(2) do |a
,e
|
88 let_env
.set(a
, EVAL(e
, let_env
))
91 ast
= a2
# Continue loop (TCO)
95 ast
= quasiquote(a1
); # Continue loop (TCO)
99 return env.set(a1
, func
)
101 return macroexpand(a1
, env)
103 eval_ast(ast
[1..-2], env)
104 ast
= ast
.last
# Continue loop (TCO)
108 return nil if a3
== nil
109 ast
= a3
# Continue loop (TCO)
111 ast
= a2
# Continue loop (TCO)
114 return Function
.new(a2
, env, a1
) {|*args
|
115 EVAL(a2
, Env
.new(env, a1
, List
.new(args
)))
118 el
= eval_ast(ast
, env)
120 if f
.class == Function
122 env = f
.gen_env(el
.drop(1)) # Continue loop (TCO)
124 return f
[*el
.drop(1)]
133 return _pr_str(exp
, true)
138 RE
= lambda
{|str
| EVAL(READ(str
), repl_env
) }
139 REP
= lambda
{|str
| PRINT(EVAL(READ(str
), repl_env
)) }
141 # core.rb: defined using ruby
142 $core_ns.each
do |k
,v
| repl_env
.set(k
,v
) end
143 repl_env
.set(:eval, lambda
{|ast
| EVAL(ast
, repl_env
)})
144 repl_env
.set(:"*ARGV*", List
.new(ARGV.slice(1,ARGV.length
) || []))
146 # core.mal: defined using the language itself
147 RE
["(def! not (fn* (a) (if a false true)))"]
148 RE
["(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))"]
149 RE
["(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))"]
150 RE
["(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))"]
153 RE
["(load-file \"" + ARGV[0] + "\")"]
158 while line
= _readline("user> ")
161 rescue Exception
=> e
163 puts
"\t#{e.backtrace.join("\n\t")}"