12 -> (args : Array(Mal::Type)) {
13 x, y = args[0].unwrap, args[1].unwrap
14 eval_error "invalid arguments for binary operator {{op.id}}" unless x.is_a?(Int32) && y.is_a?(Int32)
15 Mal::Type.new(x {{op.id}} y)
24 args.first.unwrap.is_a? Mal::List
29 a.is_a?(Array) ? a.empty? : false
40 eval_error "invalid argument for function 'count'"
44 def self.pr_str_(args)
45 args.map{|a| pr_str(a)}.join(" ")
49 args.map{|a| pr_str(a, false)}.join
53 puts self.pr_str_(args)
57 def self.println(args)
58 puts args.map{|a| pr_str(a, false)}.join(" ")
62 def self.read_string(args)
63 head = args.first.unwrap
64 eval_error "argument of read-str must be string" unless head.is_a? String
69 head = args.first.unwrap
70 eval_error "argument of slurp must be string" unless head.is_a? String
74 eval_error "no such file"
79 head, tail = args[0] as Mal::Type, args[1].unwrap
80 eval_error "2nd arg of cons must be list" unless tail.is_a? Array
81 ([head] + tail).to_mal
85 args.each_with_object(Mal::List.new) do |arg, list|
87 eval_error "arguments of concat must be list" unless a.is_a?(Array)
93 a0, a1 = args[0].unwrap, args[1].unwrap
94 eval_error "1st argument of nth must be list or vector" unless a0.is_a? Array
95 eval_error "2nd argument of nth must be integer" unless a1.is_a? Int32
102 return nil if a0.nil?
103 eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array
104 a0.empty? ? nil : a0.first
110 return Mal::List.new if a0.nil?
111 eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array
112 return Mal::List.new if a0.empty?
117 eval_error "apply must take at least 2 arguments" unless args.size >= 2
119 head = args.first.unwrap
120 last = args.last.unwrap
122 eval_error "last argument of apply must be list or vector" unless last.is_a? Array
126 head.fn.call(args[1..-2] + last)
128 head.call(args[1..-2] + last)
130 eval_error "1st argument of apply must be function or closure"
135 func = args.first.unwrap
136 list = args[1].unwrap
138 eval_error "2nd argument of map must be list or vector" unless list.is_a? Array
141 when Mal::Closure then func.fn
142 when Mal::Func then func
143 else eval_error "1st argument of map must be function"
146 list.each_with_object(Mal::List.new) do |elem, mapped|
147 mapped << f.call([elem])
152 args.first.unwrap.nil?
156 a = args.first.unwrap
160 def self.false?(args)
161 a = args.first.unwrap
165 def self.symbol?(args)
166 args.first.unwrap.is_a?(Mal::Symbol)
169 def self.symbol(args)
170 head = args.first.unwrap
171 eval_error "1st argument of symbol function must be string" unless head.is_a? String
175 def self.keyword(args)
176 head = args.first.unwrap
177 eval_error "1st argument of symbol function must be string" unless head.is_a? String
181 def self.keyword?(args)
182 head = args.first.unwrap
183 head.is_a?(String) && !head.empty? && head[0] == '\u029e'
186 def self.vector(args)
187 args.to_mal(Mal::Vector)
190 def self.vector?(args)
191 args.first.unwrap.is_a? Mal::Vector
194 def self.hash_map(args)
195 eval_error "hash-map must take even number of arguments" unless args.size.even?
196 map = Mal::HashMap.new
197 args.each_slice(2) do |kv|
199 eval_error "key must be string" unless k.is_a? String
206 args.first.unwrap.is_a? Mal::HashMap
210 head = args.first.unwrap
211 eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
212 eval_error "assoc must take a list and even number of arguments" unless (args.size - 1).even?
214 map = Mal::HashMap.new
215 head.each{|k, v| map[k] = v}
217 args[1..-1].each_slice(2) do |kv|
219 eval_error "key must be string" unless k.is_a? String
226 def self.dissoc(args)
227 head = args.first.unwrap
228 eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
230 map = Mal::HashMap.new
231 head.each{|k,v| map[k] = v}
233 args[1..-1].each do |arg|
235 eval_error "key must be string" unless key.is_a? String
243 a0, a1 = args[0].unwrap, args[1].unwrap
244 return nil unless a0.is_a? Mal::HashMap
245 eval_error "2nd argument of get must be string" unless a1.is_a? String
247 # a0[a1]? isn't available because type ofa0[a1] is infered NoReturn
248 a0.has_key?(a1) ? a0[a1] : nil
251 def self.contains?(args)
252 a0, a1 = args[0].unwrap, args[1].unwrap
253 eval_error "1st argument of get must be hashmap" unless a0.is_a? Mal::HashMap
254 eval_error "2nd argument of get must be string" unless a1.is_a? String
259 head = args.first.unwrap
260 eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
261 head.keys.each_with_object(Mal::List.new){|e,l| l << Mal::Type.new(e)}
265 head = args.first.unwrap
266 eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
270 def self.sequential?(args)
271 args.first.unwrap.is_a? Array
274 def self.readline(args)
275 head = args.first.unwrap
276 eval_error "1st argument of readline must be string" unless head.is_a? String
285 def self.with_meta(args)
292 Mal::Atom.new args.first
296 args.first.unwrap.is_a? Mal::Atom
300 head = args.first.unwrap
301 eval_error "1st argument of deref must be atom" unless head.is_a? Mal::Atom
305 def self.reset!(args)
306 head = args.first.unwrap
307 eval_error "1st argument of reset! must be atom" unless head.is_a? Mal::Atom
312 atom = args.first.unwrap
313 eval_error "1st argument of swap! must be atom" unless atom.is_a? Mal::Atom
315 a = [atom.val] + args[2..-1]
317 func = args[1].unwrap
320 atom.val = func.call a
322 atom.val = func.fn.call a
324 eval_error "2nd argumetn of swap! must be function"
329 seq = args.first.unwrap
332 (args[1..-1].reverse + seq).to_mal
334 (seq + args[1..-1]).to_mal(Mal::Vector)
336 eval_error "1st argument of conj must be list or vector"
340 def self.time_ms(args)
341 (Time.now.to_i.to_i32) * 1000
345 # Simply using ->self.some_func doesn't work
347 -> (args : Array(Mal::Type)) { Mal::Type.new self.{{name.id}}(args) }
351 -> (args : Array(Mal::Type)) { Mal::Type.new (args[0] {{op.id}} args[1]) }
359 "list" => func(:list)
360 "list?" => func(:list?)
361 "empty?" => func(:empty?)
362 "count" => func(:count)
368 "pr-str" => func(:pr_str_)
371 "println" => func(:println)
372 "read-string" => func(:read_string)
373 "slurp" => func(:slurp)
374 "cons" => func(:cons)
375 "concat" => func(:concat)
377 "first" => func(:first)
378 "rest" => func(:rest)
379 "throw" => -> (args : Array(Mal::Type)) { raise Mal::RuntimeException.new args[0] }
380 "apply" => func(:apply)
382 "nil?" => func(:nil?)
383 "true?" => func(:true?)
384 "false?" => func(:false?)
385 "symbol?" => func(:symbol?)
386 "symbol" => func(:symbol)
387 "keyword" => func(:keyword)
388 "keyword?" => func(:keyword?)
389 "vector" => func(:vector)
390 "vector?" => func(:vector?)
391 "hash-map" => func(:hash_map)
392 "map?" => func(:map?)
393 "assoc" => func(:assoc)
394 "dissoc" => func(:dissoc)
396 "contains?" => func(:contains?)
397 "keys" => func(:keys)
398 "vals" => func(:vals)
399 "sequential?" => func(:sequential?)
400 "readline" => func(:readline)
401 "meta" => func(:meta)
402 "with-meta" => func(:with_meta)
403 "atom" => func(:atom)
404 "atom?" => func(:atom?)
405 "deref" => func(:deref)
406 "deref" => func(:deref)
407 "reset!" => func(:reset!)
408 "swap!" => func(:swap!)
409 "conj" => func(:conj)
410 "time-ms" => func(:time_ms)
411 } of String => Mal::Func