Julia: update to verion 0.4. Add time-ms.
[jackhill/mal.git] / julia / core.jl
1 module core
2
3 import types
4 import reader
5 using printer
6 import readline_mod
7
8 export ns
9
10 function concat(args...)
11 res = []
12 for a=args
13 res = [res; Any[a...]]
14 end
15 res
16 end
17
18 function do_apply(f, all_args...)
19 fn = isa(f,types.MalFunc) ? f.fn : f
20 args = concat(all_args[1:end-1], all_args[end])
21 fn(args...)
22 end
23
24 function with_meta(obj, meta)
25 new_obj = types.copy(obj)
26 new_obj.meta = meta
27 new_obj
28 end
29
30 ns = Dict{Any,Any}(
31 symbol("=") => (a,b) -> types.equal_Q(a, b),
32 :throw => (a) -> throw(types.MalException(a)),
33
34 symbol("nil?") => (a) -> a === nothing,
35 symbol("true?") => (a) -> a === true,
36 symbol("false?") => (a) -> a === false,
37 symbol("symbol") => (a) -> symbol(a),
38 symbol("symbol?") => (a) -> typeof(a) === Symbol,
39 symbol("keyword") => (a) -> a[1] == '\u029e' ? a : "\u029e$(a)",
40 symbol("keyword?") => (a) -> isa(a,AbstractString) && a[1] == '\u029e',
41
42 symbol("pr-str") => (a...) -> join(map((e)->pr_str(e, true),a)," "),
43 :str => (a...) -> join(map((e)->pr_str(e, false),a),""),
44 :prn => (a...) -> println(join(map((e)->pr_str(e, true),a)," ")),
45 :println => (a...) -> println(join(map((e)->pr_str(e, false),a)," ")),
46 symbol("read-string") => (a) -> reader.read_str(a),
47 :readline => readline_mod.do_readline,
48 :slurp => (a) -> readall(open(a)),
49
50 :< => <,
51 :<= => <=,
52 :> => >,
53 :>= => >=,
54 :+ => +,
55 :- => -,
56 symbol("*") => *,
57 :/ => div,
58 symbol("time-ms") => () -> round(Int, time()*1000),
59
60 :list => (a...) -> Any[a...],
61 symbol("list?") => (a) -> isa(a, Array),
62 :vector => (a...) -> tuple(a...),
63 symbol("vector?") => (a) -> isa(a, Tuple),
64 symbol("hash-map") => types.hash_map,
65 symbol("map?") => (a) -> isa(a, Dict),
66 :assoc => (a, b...) -> merge(a, types.hash_map(b...)),
67 :dissoc => (a, b...) -> foldl((x,y) -> delete!(x,y),copy(a), b),
68 :get => (a,b) -> a === nothing ? nothing : get(a,b,nothing),
69 symbol("contains?") => haskey,
70 :keys => (a) -> [keys(a)...],
71 :vals => (a) -> [values(a)...],
72
73 symbol("sequential?") => types.sequential_Q,
74 :cons => (a,b) -> [Any[a]; Any[b...]],
75 :concat => concat,
76 :nth => (a,b) -> b+1 > length(a) ? error("nth: index out of range") : a[b+1],
77 :first => (a) -> isempty(a) ? nothing : first(a),
78 :rest => (a) -> Any[a[2:end]...],
79 symbol("empty?") => isempty,
80 :count => (a) -> a == nothing ? 0 : length(a),
81 :apply => do_apply,
82 :map => (a,b) -> isa(a,types.MalFunc) ? [map(a.fn,b)...] : [map(a,b)...],
83
84 :conj => nothing,
85
86 :meta => (a) -> isa(a,types.MalFunc) ? a.meta : nothing,
87 symbol("with-meta") => with_meta,
88 :atom => (a) -> types.Atom(a),
89 symbol("atom?") => (a) -> isa(a,types.Atom),
90 :deref => (a) -> a.val,
91 :reset! => (a,b) -> a.val = b,
92 :swap! => (a,b,c...) -> a.val = do_apply(b, a.val, c),
93 )
94
95 end