Commit | Line | Data |
---|---|---|
a9cd6543 JM |
1 | import types |
2 | import types.MalException | |
3 | import types.MalSymbol | |
3d1dbb20 | 4 | import types.MalFunc |
a9cd6543 JM |
5 | import reader |
6 | import printer | |
7 | ||
8 | class core { | |
9 | def static do_pr_str(args) { | |
10 | return printer._pr_list(args, " ", true) | |
11 | } | |
12 | def static do_str(args) { | |
13 | return printer._pr_list(args, "", false) | |
14 | } | |
15 | def static do_prn(args) { | |
16 | println(printer._pr_list(args, " ", true)) | |
17 | } | |
18 | def static do_println(args) { | |
19 | println(printer._pr_list(args, " ", false)) | |
20 | } | |
21 | ||
22 | def static do_concat(args) { | |
23 | args.inject([], { a, b -> a + (b as List) }) | |
24 | } | |
25 | def static do_nth(args) { | |
26 | if (args[0].size() <= args[1]) { | |
27 | throw new MalException("nth: index out of range") | |
28 | } | |
29 | args[0][args[1]] | |
30 | } | |
31 | def static do_apply(args) { | |
32 | def start_args = args.drop(1).take(args.size()-2) as List | |
33 | args[0](start_args + (args.last() as List)) | |
34 | } | |
35 | ||
36 | def static do_swap_BANG(args) { | |
37 | def (atm,f) = [args[0], args[1]] | |
38 | atm.value = f([atm.value] + (args.drop(2) as List)) | |
39 | } | |
40 | ||
8e32dbb6 JM |
41 | def static do_conj(args) { |
42 | if (types.list_Q(args[0])) { | |
43 | args.drop(1).inject(args[0], { a, b -> [b] + a }) | |
44 | } else { | |
45 | types.vector(args.drop(1).inject(args[0], { a, b -> a + [b] })) | |
46 | } | |
47 | } | |
48 | def static do_seq(args) { | |
49 | def obj = args[0] | |
50 | switch (obj) { | |
51 | case { types.list_Q(obj) }: | |
52 | return obj.size() == 0 ? null : obj | |
53 | case { types.vector_Q(obj) }: | |
54 | return obj.size() == 0 ? null : obj.clone() | |
55 | case { types.string_Q(obj) }: | |
56 | return obj.size() == 0 ? null : obj.collect{ it.toString() } | |
57 | case null: | |
58 | return null | |
59 | default: | |
60 | throw new MalException("seq: called on non-sequence") | |
61 | } | |
62 | } | |
63 | ||
a9cd6543 JM |
64 | static ns = [ |
65 | "=": { a -> a[0]==a[1]}, | |
66 | "throw": { a -> throw new MalException(a[0]) }, | |
67 | ||
68 | "nil?": { a -> a[0] == null }, | |
69 | "true?": { a -> a[0] == true }, | |
70 | "false?": { a -> a[0] == false }, | |
8e32dbb6 | 71 | "string?": { a -> types.string_Q(a[0]) }, |
a9cd6543 JM |
72 | "symbol": { a -> new MalSymbol(a[0]) }, |
73 | "symbol?": { a -> a[0] instanceof MalSymbol }, | |
74 | "keyword": { a -> types.keyword(a[0]) }, | |
75 | "keyword?": { a -> types.keyword_Q(a[0]) }, | |
3d1dbb20 JM |
76 | "number?": { a -> a[0] instanceof Integer }, |
77 | "fn?": { a -> (a[0] instanceof MalFunc && !a[0].ismacro) || | |
78 | a[0] instanceof Closure }, | |
79 | "macro?": { a -> a[0] instanceof MalFunc && a[0].ismacro }, | |
a9cd6543 JM |
80 | |
81 | "pr-str": core.&do_pr_str, | |
82 | "str": core.&do_str, | |
83 | "prn": core.&do_prn, | |
84 | "println": core.&do_println, | |
85 | "read-string": reader.&read_str, | |
86 | "readline": { a -> System.console().readLine(a[0]) }, | |
87 | "slurp": { a -> new File(a[0]).text }, | |
88 | ||
89 | "<": { a -> a[0]<a[1]}, | |
90 | "<=": { a -> a[0]<=a[1]}, | |
91 | ">": { a -> a[0]>a[1]}, | |
92 | ">=": { a -> a[0]>=a[1]}, | |
93 | "+": { a -> a[0]+a[1]}, | |
94 | "-": { a -> a[0]-a[1]}, | |
95 | "*": { a -> a[0]*a[1]}, | |
96 | "/": { a -> a[0]/a[1]}, // / | |
97 | "time-ms": { a -> System.currentTimeMillis() }, | |
98 | ||
99 | "list": { a -> a}, | |
100 | "list?": { a -> types.list_Q(a[0]) }, | |
101 | "vector": { a -> types.vector(a) }, | |
102 | "vector?": { a -> types.vector_Q(a[0]) }, | |
103 | "hash-map": { a -> types.hash_map(a) }, | |
104 | "map?": { a -> types.hash_map_Q(a[0]) }, | |
105 | "assoc": { a -> types.assoc_BANG(types.copy(a[0]), a.drop(1)) }, | |
106 | "dissoc": { a -> types.dissoc_BANG(types.copy(a[0]), a.drop(1)) }, | |
107 | "get": { a -> a[0] == null ? null : a[0][a[1]] }, | |
108 | "contains?": { a -> a[0].containsKey(a[1]) }, | |
109 | "keys": { a -> a[0].keySet() as List }, | |
110 | "vals": { a -> a[0].values() as List }, | |
111 | ||
112 | "sequential?": { a -> types.&sequential_Q(a[0]) }, | |
113 | "cons": { a -> [a[0]] + (a[1] as List) }, | |
114 | "concat": core.&do_concat, | |
fbfe6784 | 115 | "vec": { a -> types.vector_Q(a[0]) ? a[0] : types.vector(a[0]) }, |
a9cd6543 | 116 | "nth": core.&do_nth, |
c36d5b39 DM |
117 | "first": { a -> a[0] == null || a[0].size() == 0 ? null : a[0][0] }, |
118 | "rest": { a -> a[0] == null ? [] as List : a[0].drop(1) }, | |
a9cd6543 JM |
119 | "empty?": { a -> a[0] == null || a[0].size() == 0 }, |
120 | "count": { a -> a[0] == null ? 0 : a[0].size() }, | |
121 | "apply": core.&do_apply, | |
122 | "map": { a -> a[1].collect { x -> a[0].call([x]) } }, | |
123 | ||
4ed89670 | 124 | "conj": core.&do_conj, |
8e32dbb6 | 125 | "seq": core.&do_seq, |
a9cd6543 JM |
126 | |
127 | "meta": { a -> a[0].hasProperty("meta") ? a[0].getProperties().meta : null }, | |
128 | "with-meta": { a -> def b = types.copy(a[0]); b.getMetaClass().meta = a[1]; b }, | |
129 | "atom": { a -> new types.MalAtom(a[0]) }, | |
130 | "atom?": { a -> a[0] instanceof types.MalAtom }, | |
131 | "deref": { a -> a[0].value }, | |
132 | "reset!": { a -> a[0].value = a[1] }, | |
133 | "swap!": core.&do_swap_BANG | |
134 | ] | |
135 | } | |
136 |