Commit | Line | Data |
---|---|---|
51ff32e2 | 1 | include "utils"; |
da5289bb | 2 | include "printer"; |
7650046a | 3 | include "reader"; |
da5289bb A |
4 | |
5 | def core_identify: | |
6 | { | |
136fb719 A |
7 | "env": { |
8 | kind: "fn", | |
9 | function: "env", | |
10 | inputs: 0 | |
11 | }, | |
da5289bb A |
12 | "prn": { |
13 | kind: "fn", | |
14 | function: "prn", | |
15 | inputs: -1 | |
16 | }, | |
17 | "pr-str": { | |
18 | kind: "fn", | |
19 | function: "pr-str", | |
20 | inputs: -1 | |
21 | }, | |
22 | "str": { | |
23 | kind: "fn", | |
24 | function: "str", | |
25 | inputs: -1 | |
26 | }, | |
27 | "println": { | |
28 | kind: "fn", | |
29 | function: "println", | |
30 | inputs: -1 | |
31 | }, | |
32 | "list": { | |
33 | kind: "fn", | |
34 | function: "list", | |
35 | inputs: -1 | |
36 | }, | |
37 | "list?": { | |
38 | kind: "fn", | |
39 | function: "list?", | |
40 | inputs: 1 | |
41 | }, | |
42 | "empty?": { | |
43 | kind: "fn", | |
44 | function: "empty?", | |
45 | inputs: 1 | |
46 | }, | |
47 | "count": { | |
48 | kind: "fn", | |
49 | function: "count", | |
50 | inputs: 1 | |
51 | }, | |
52 | "=": { | |
53 | kind: "fn", | |
54 | function: "=", | |
55 | inputs: 2 | |
56 | }, | |
57 | "<": { | |
58 | kind: "fn", | |
59 | function: "<", | |
60 | inputs: 2 | |
61 | }, | |
62 | "<=": { | |
63 | kind: "fn", | |
64 | function: "<=", | |
65 | inputs: 2 | |
66 | }, | |
67 | ">": { | |
68 | kind: "fn", | |
69 | function: ">", | |
70 | inputs: 2 | |
71 | }, | |
72 | ">=": { | |
73 | kind: "fn", | |
74 | function: ">=", | |
75 | inputs: 2 | |
76 | }, | |
7650046a A |
77 | "read-string": { |
78 | kind: "fn", | |
79 | function: "read-string", | |
80 | inputs: 1 | |
81 | }, | |
82 | "slurp": { | |
83 | kind: "fn", | |
84 | function: "slurp", | |
85 | inputs: 1 | |
eedfbb43 A |
86 | }, |
87 | "atom": { | |
88 | kind: "fn", | |
89 | function: "atom", | |
90 | inputs: 1 | |
91 | }, | |
92 | "atom?": { | |
93 | kind: "fn", | |
94 | function: "atom?", | |
95 | inputs: 1 | |
96 | }, | |
97 | "deref": { | |
98 | kind: "fn", | |
99 | function: "deref", | |
100 | inputs: 1 | |
101 | }, | |
102 | "reset!": { # defined in interp | |
103 | kind: "fn", | |
104 | function: "reset!", | |
105 | inputs: 2 | |
106 | }, | |
107 | "swap!": { # defined in interp | |
108 | kind: "fn", | |
109 | function: "swap!", | |
4db6de12 | 110 | inputs: -3 |
a451ec51 A |
111 | }, |
112 | "cons": { | |
113 | kind: "fn", | |
114 | function: "cons", | |
115 | inputs: 2 | |
116 | }, | |
117 | "concat": { | |
118 | kind: "fn", | |
119 | function: "concat", | |
120 | inputs: -1 | |
e41d9de3 A |
121 | }, |
122 | "nth": { | |
123 | kind: "fn", | |
124 | function: "nth", | |
125 | inputs: 2 | |
126 | }, | |
127 | "first": { | |
128 | kind: "fn", | |
129 | function: "first", | |
130 | inputs: 1 | |
131 | }, | |
132 | "rest": { | |
133 | kind: "fn", | |
134 | function: "rest", | |
135 | inputs: 1 | |
4db6de12 A |
136 | }, |
137 | "throw": { | |
138 | kind: "fn", | |
139 | function: "throw", | |
140 | inputs: 1 | |
141 | }, | |
142 | "apply": { # defined in interp | |
143 | kind: "fn", | |
144 | function: "apply", | |
145 | inputs: -3 | |
146 | }, | |
147 | "map": { # defined in interp | |
148 | kind: "fn", | |
149 | function: "map", | |
150 | inputs: 2 | |
151 | }, | |
152 | "nil?": { | |
153 | kind: "fn", | |
154 | function: "nil?", | |
155 | inputs: 1 | |
156 | }, | |
157 | "true?": { | |
158 | kind: "fn", | |
159 | function: "true?", | |
160 | inputs: 1 | |
161 | }, | |
162 | "false?": { | |
163 | kind: "fn", | |
164 | function: "false?", | |
165 | inputs: 1 | |
166 | }, | |
167 | "symbol": { | |
168 | kind: "fn", | |
169 | function: "symbol", | |
170 | inputs: 1 | |
171 | }, | |
172 | "symbol?": { | |
173 | kind: "fn", | |
174 | function: "symbol?", | |
175 | inputs: 1 | |
176 | }, | |
177 | "keyword": { | |
178 | kind: "fn", | |
179 | function: "keyword", | |
180 | inputs: 1 | |
181 | }, | |
182 | "keyword?": { | |
183 | kind: "fn", | |
184 | function: "keyword?", | |
185 | inputs: 1 | |
186 | }, | |
187 | "vector": { | |
188 | kind: "fn", | |
189 | function: "vector", | |
190 | inputs: -1 | |
191 | }, | |
192 | "vector?": { | |
193 | kind: "fn", | |
194 | function: "vector?", | |
195 | inputs: 1 | |
196 | }, | |
197 | "sequential?": { | |
198 | kind: "fn", | |
199 | function: "sequential?", | |
200 | inputs: 1 | |
201 | }, | |
202 | "hash-map": { | |
203 | kind: "fn", | |
204 | function: "hash-map", | |
205 | inputs: -1 | |
206 | }, | |
207 | "map?": { | |
208 | kind: "fn", | |
209 | function: "map?", | |
210 | inputs: 1 | |
211 | }, | |
212 | "assoc": { | |
213 | kind: "fn", | |
214 | function: "assoc", | |
215 | inputs: -2 | |
216 | }, | |
217 | "dissoc": { | |
218 | kind: "fn", | |
219 | function: "dissoc", | |
220 | inputs: -2 | |
221 | }, | |
222 | "get": { | |
223 | kind: "fn", | |
224 | function: "get", | |
225 | inputs: 2 | |
226 | }, | |
227 | "contains?": { | |
228 | kind: "fn", | |
229 | function: "contains?", | |
230 | inputs: 2 | |
231 | }, | |
232 | "keys": { | |
233 | kind: "fn", | |
234 | function: "keys", | |
235 | inputs: 1 | |
236 | }, | |
237 | "vals": { | |
238 | kind: "fn", | |
239 | function: "vals", | |
240 | inputs: 1 | |
b103f95e A |
241 | }, |
242 | "string?": { | |
243 | kind: "fn", | |
244 | function: "string?", | |
245 | inputs: 1 | |
246 | }, | |
247 | "fn?": { | |
248 | kind: "fn", | |
249 | function: "fn?", | |
250 | inputs: 1 | |
251 | }, | |
252 | "number?": { | |
253 | kind: "fn", | |
254 | function: "number?", | |
255 | inputs: 1 | |
256 | }, | |
257 | "macro?": { | |
258 | kind: "fn", | |
259 | function: "macro?", | |
260 | inputs: 1 | |
261 | }, | |
262 | "readline": { | |
263 | kind: "fn", | |
264 | function: "readline", | |
265 | inputs: 1 | |
266 | }, | |
267 | "time-ms": { | |
268 | kind: "fn", | |
269 | function: "time-ms", | |
270 | inputs: 0 | |
271 | }, | |
272 | "meta": { | |
273 | kind: "fn", | |
274 | function: "meta", | |
275 | inputs: 1 | |
276 | }, | |
277 | "with-meta": { | |
278 | kind: "fn", | |
279 | function: "with-meta", | |
280 | inputs: 2 | |
281 | }, | |
282 | "seq": { | |
283 | kind: "fn", | |
284 | function: "seq", | |
285 | inputs: 1 | |
286 | }, | |
287 | "conj": { | |
288 | kind: "fn", | |
289 | function: "conj", | |
290 | inputs: -3 | |
7650046a | 291 | } |
da5289bb | 292 | }; |
51ff32e2 | 293 | |
23f9ce8e A |
294 | def vec2list(obj): |
295 | if obj.kind == "list" then | |
296 | obj.value | map(vec2list(.)) | wrap("list") | |
297 | else | |
4db6de12 A |
298 | if obj.kind == "vector" then |
299 | obj.value | map(vec2list(.)) | wrap("list") | |
300 | else | |
301 | if obj.kind == "hashmap" then | |
302 | obj.value | map_values(.value |= vec2list(.)) | wrap("hashmap") | |
303 | else | |
304 | obj | |
305 | end | |
306 | end | |
307 | end; | |
23f9ce8e | 308 | |
fed3ca50 A |
309 | def make_sequence: |
310 | . as $dot | |
311 | | if .value|length == 0 then null | wrap("nil") else | |
312 | ( | |
313 | select(.kind == "string") | .value | split("") | map(wrap("string")) | |
314 | ) // ( | |
315 | select(.kind == "list" or .kind == "vector") | .value | |
316 | ) // jqmal_error("cannot make sequence from \(.kind)") | wrap("list") | |
317 | end; | |
318 | ||
51ff32e2 A |
319 | def core_interp(arguments; env): |
320 | ( | |
321 | select(.function == "number_add") | | |
322 | arguments | map(.value) | .[0] + .[1] | wrap("number") | |
23f9ce8e | 323 | ) // ( |
51ff32e2 A |
324 | select(.function == "number_sub") | |
325 | arguments | map(.value) | .[0] - .[1] | wrap("number") | |
326 | ) // ( | |
327 | select(.function == "number_mul") | | |
328 | arguments | map(.value) | .[0] * .[1] | wrap("number") | |
329 | ) // ( | |
330 | select(.function == "number_div") | | |
331 | arguments | map(.value) | .[0] / .[1] | wrap("number") | |
136fb719 A |
332 | ) // ( |
333 | select(.function == "env") | | |
334 | env | tojson | wrap("string") | |
da5289bb A |
335 | ) // ( |
336 | select(.function == "prn") | | |
83b974c5 | 337 | arguments | map(pr_str(env; {readable: true})) | join(" ") | _display | null | wrap("nil") |
da5289bb A |
338 | ) // ( |
339 | select(.function == "pr-str") | | |
fed3ca50 | 340 | arguments | map(pr_str(env; {readable: true})) | join(" ") | wrap("string") |
da5289bb A |
341 | ) // ( |
342 | select(.function == "str") | | |
fed3ca50 | 343 | arguments | map(pr_str(env; {readable: false})) | join("") | wrap("string") |
da5289bb A |
344 | ) // ( |
345 | select(.function == "println") | | |
83b974c5 | 346 | arguments | map(pr_str(env; {readable: false})) | join(" ") | _display | null | wrap("nil") |
da5289bb A |
347 | ) // ( |
348 | select(.function == "list") | | |
349 | arguments | wrap("list") | |
350 | ) // ( | |
351 | select(.function == "list?") | null | wrap(arguments | first.kind == "list" | tostring) | |
352 | ) // ( | |
353 | select(.function == "empty?") | null | wrap(arguments|first.value | length == 0 | tostring) | |
354 | ) // ( | |
355 | select(.function == "count") | arguments|first.value | length | wrap("number") | |
356 | ) // ( | |
23f9ce8e | 357 | select(.function == "=") | null | wrap(vec2list(arguments[0]) == vec2list(arguments[1]) | tostring) |
da5289bb A |
358 | ) // ( |
359 | select(.function == "<") | null | wrap(arguments[0].value < arguments[1].value | tostring) | |
360 | ) // ( | |
361 | select(.function == "<=") | null | wrap(arguments[0].value <= arguments[1].value | tostring) | |
362 | ) // ( | |
363 | select(.function == ">") | null | wrap(arguments[0].value > arguments[1].value | tostring) | |
364 | ) // ( | |
365 | select(.function == ">=") | null | wrap(arguments[0].value >= arguments[1].value | tostring) | |
7650046a A |
366 | ) // ( |
367 | select(.function == "slurp") | arguments | map(.value) | issue_extern("read") | wrap("string") | |
368 | ) // ( | |
369 | select(.function == "read-string") | arguments | first.value | read_str | read_form.value | |
eedfbb43 A |
370 | ) // ( |
371 | select(.function == "atom?") | null | wrap(arguments | first.kind == "atom" | tostring) | |
a451ec51 A |
372 | ) // ( |
373 | select(.function == "cons") | ([arguments[0]] + arguments[1].value) | wrap("list") | |
374 | ) // ( | |
375 | select(.function == "concat") | arguments | map(.value) | (add//[]) | wrap("list") | |
e41d9de3 A |
376 | ) // ( |
377 | select(.function == "nth") | |
b103f95e | 378 | | _debug(arguments) |
e41d9de3 A |
379 | | arguments[0].value as $lst |
380 | | arguments[1].value as $idx | |
381 | | if ($lst|length < $idx) or ($idx < 0) then | |
382 | jqmal_error("index out of range") | |
383 | else | |
384 | $lst[$idx] | |
385 | end | |
386 | ) // ( | |
387 | select(.function == "first") | arguments[0].value | first // {kind:"nil"} | |
388 | ) // ( | |
389 | select(.function == "rest") | arguments[0]?.value?[1:]? // [] | wrap("list") | |
4db6de12 A |
390 | ) // ( |
391 | select(.function == "throw") | jqmal_error(arguments[0] | tojson) | |
392 | ) // ( | |
393 | select(.function == "nil?") | null | wrap((arguments[0].kind == "nil") | tostring) | |
394 | ) // ( | |
395 | select(.function == "true?") | null | wrap((arguments[0].kind == "true") | tostring) | |
396 | ) // ( | |
397 | select(.function == "false?") | null | wrap((arguments[0].kind == "false") | tostring) | |
398 | ) // ( | |
399 | select(.function == "symbol?") | null | wrap((arguments[0].kind == "symbol") | tostring) | |
400 | ) // ( | |
401 | select(.function == "symbol") | arguments[0].value | wrap("symbol") | |
402 | ) // ( | |
403 | select(.function == "keyword") | arguments[0].value | wrap("keyword") | |
404 | ) // ( | |
405 | select(.function == "keyword?") | null | wrap((arguments[0].kind == "keyword") | tostring) | |
406 | ) // ( | |
407 | select(.function == "vector") | arguments | wrap("vector") | |
408 | ) // ( | |
409 | select(.function == "vector?") | null | wrap((arguments[0].kind == "vector") | tostring) | |
410 | ) // ( | |
411 | select(.function == "sequential?") | null | wrap((arguments[0].kind == "vector" or arguments[0].kind == "list") | tostring) | |
412 | ) // ( | |
413 | select(.function == "hash-map") | | |
414 | if (arguments|length) % 2 == 1 then | |
415 | jqmal_error("Odd number of arguments to hash-map") | |
416 | else | |
417 | [ arguments | | |
418 | nwise(2) | | |
419 | try { | |
420 | key: (.[0] | extract_string), | |
421 | value: { | |
422 | kkind: .[0].kind, | |
423 | value: .[1] | |
424 | } | |
425 | } | |
426 | ] | from_entries | wrap("hashmap") | |
427 | end | |
428 | ) // ( | |
429 | select(.function == "map?") | null | wrap((arguments[0].kind == "hashmap") | tostring) | |
430 | ) // ( | |
431 | select(.function == "assoc") | | |
432 | if (arguments|length) % 2 == 0 then | |
433 | jqmal_error("Odd number of key-values to assoc") | |
434 | else | |
435 | arguments[0].value + ([ arguments[1:] | | |
436 | nwise(2) | | |
437 | try { | |
438 | key: (.[0] | extract_string), | |
439 | value: { | |
440 | kkind: .[0].kind, | |
441 | value: .[1] | |
442 | } | |
443 | } | |
444 | ] | from_entries) | wrap("hashmap") | |
445 | end | |
446 | ) // ( | |
447 | select(.function == "dissoc") | | |
448 | arguments[1:] | map(.value) as $keynames | | |
449 | arguments[0].value | with_entries(select(.key as $k | $keynames | contains([$k]) | not)) | wrap("hashmap") | |
450 | ) // ( | |
451 | select(.function == "get") | arguments[0].value[arguments[1].value].value // {kind:"nil"} | |
452 | ) // ( | |
453 | select(.function == "contains?") | null | wrap((arguments[0].value | has(arguments[1].value)) | tostring) | |
454 | ) // ( | |
455 | select(.function == "keys") | arguments[0].value | with_entries(.value as $v | .key as $k | {key: $k, value: {value: $k, kind: $v.kkind}}) | to_entries | map(.value) | wrap("list") | |
456 | ) // ( | |
457 | select(.function == "vals") | arguments[0].value | map(.value) | to_entries | map(.value) | wrap("list") | |
b103f95e A |
458 | ) // ( |
459 | select(.function == "string?") | null | wrap((arguments[0].kind == "string") | tostring) | |
460 | ) // ( | |
fed3ca50 | 461 | select(.function == "fn?") | null | wrap((arguments[0].kind == "fn" or (arguments[0].kind == "function" and (arguments[0].is_macro|not))) | tostring) |
b103f95e A |
462 | ) // ( |
463 | select(.function == "number?") | null | wrap((arguments[0].kind == "number") | tostring) | |
464 | ) // ( | |
465 | select(.function == "macro?") | null | wrap((arguments[0].is_macro == true) | tostring) | |
466 | ) // ( | |
467 | select(.function == "readline") | arguments[0].value | __readline | wrap("string") | |
468 | ) // ( | |
469 | select(.function == "time-ms") | now * 1000 | wrap("number") | |
470 | ) // ( | |
471 | select(.function == "meta") | arguments[0].meta // {kind:"nil"} | |
472 | ) // ( | |
473 | select(.function == "with-meta") | arguments[0] | .meta |= arguments[1] | |
fed3ca50 A |
474 | ) // ( |
475 | select(.function == "seq") | arguments[0] | make_sequence | |
476 | ) // ( | |
477 | select(.function == "conj") | |
478 | | arguments[0] as $orig | |
479 | | arguments[1:] as $stuff | |
480 | | if $orig.kind == "list" then | |
481 | [ $stuff|reverse[], $orig.value[] ] | wrap("list") | |
482 | else | |
483 | [ $orig.value[], $stuff[] ] | wrap("vector") | |
484 | end | |
597522fa | 485 | ) // jqmal_error("Unknown native function \(.function)"); |