2 require_relative
"reader"
3 require_relative
"printer"
6 :"=" => lambda
{|a
,b
| a
== b
},
7 :throw => lambda
{|a
| raise MalException
.new(a
), "Mal Exception"},
8 :nil? => lambda
{|a
| a
== nil},
9 :true? => lambda
{|a
| a
== true},
10 :false? => lambda
{|a
| a
== false},
11 :symbol => lambda
{|a
| a
.to_sym
},
12 :symbol? => lambda
{|a
| a
.is_a
? Symbol
},
13 :keyword => lambda
{|a
| "\u029e"+a
},
14 :keyword? => lambda
{|a
| (a
.is_a
? String
) && "\u029e" == a
[0]},
16 :"pr-str" => lambda
{|*a
| a
.map
{|e
| _pr_str(e
, true)}.join(" ")},
17 :str => lambda
{|*a
| a
.map
{|e
| _pr_str(e
, false)}.join("")},
18 :prn => lambda
{|*a
| puts(a
.map
{|e
| _pr_str(e
, true)}.join(" "))},
19 :println => lambda
{|*a
| puts(a
.map
{|e
| _pr_str(e
, false)}.join(" "))},
20 :readline => lambda
{|a
| Readline
.readline(a
,true)},
21 :"read-string" => lambda
{|a
| read_str(a
)},
22 :slurp => lambda
{|a
| File
.read(a
)},
23 :< => lambda
{|a
,b
| a
< b
},
24 :<= => lambda
{|a
,b
| a
<= b
},
25 :> => lambda
{|a
,b
| a
> b
},
26 :>= => lambda
{|a
,b
| a
>= b
},
27 :+ => lambda
{|a
,b
| a
+ b
},
28 :- => lambda
{|a
,b
| a
- b
},
29 :* => lambda
{|a
,b
| a
* b
},
30 :/ => lambda {|a,b| a / b
},
31 :"time-ms" => lambda
{|| (Time
.now
.to_f
* 1000).to_i
},
33 :list => lambda
{|*a
| List
.new a
},
34 :list? => lambda
{|*a
| a
[0].is_a
? List
},
35 :vector => lambda
{|*a
| Vector
.new a
},
36 :vector? => lambda
{|*a
| a
[0].is_a
? Vector
},
37 :"hash-map" =>lambda
{|*a
| Hash
[a
.each_slice(2).to_a
]},
38 :map? => lambda
{|a
| a
.is_a
? Hash
},
39 :assoc => lambda
{|*a
| a
[0].merge(Hash
[a
.drop(1).each_slice(2).to_a
])},
40 :dissoc => lambda
{|*a
| h
= a
[0].clone
; a
.drop(1).each
{|k
| h
.delete k
}; h
},
41 :get => lambda
{|a
,b
| return nil if a
== nil; a
[b
]},
42 :contains? => lambda
{|a
,b
| a
.key
? b
},
43 :keys => lambda
{|a
| List
.new a
.keys
},
44 :vals => lambda
{|a
| List
.new a
.values
},
46 :sequential? => lambda
{|a
| sequential
?(a
)},
47 :cons => lambda
{|a
,b
| List
.new(b
.clone
.insert(0,a
))},
48 :concat => lambda
{|*a
| List
.new(a
&& a
.reduce(:concat) || [])},
49 :nth => lambda
{|a
,b
| raise "nth: index out of range" if b
>= a
.size
; a
[b
]},
50 :first => lambda
{|a
| a
[0]},
51 :rest => lambda
{|a
| List
.new(a
.size
> 0 && a
.drop(1) || [])},
52 :empty? => lambda
{|a
| a
.size
== 0},
53 :count => lambda
{|a
| return 0 if a
== nil; a
.size
},
54 :conj => lambda
{|*a
| a
[0].clone
.conj(a
.drop(1))},
55 :apply => lambda
{|*a
| a
[0][*a
[1..-2].concat(a
[-1])]},
56 :map => lambda
{|a
,b
| List
.new(b
.map
{|e
| a
[e
]})},
58 :"with-meta" => lambda
{|a
,b
| x
= a
.clone
; x
.meta
= b
; x
},
59 :meta => lambda
{|a
| a
.meta
},
60 :atom => lambda
{|a
| Atom
.new(a
)},
61 :atom? => lambda
{|a
| a
.is_a
? Atom
},
62 :deref => lambda
{|a
| a
.val
},
63 :reset! => lambda
{|a
,b
| a
.val
= b
},
64 :swap! => lambda
{|*a
| a
[0].val
= a
[1][*[a
[0].val
].concat(a
.drop(2))]},