tree-sitter-clojure-orchard 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +121 -0
- package/README.md +14 -0
- package/binding.gyp +35 -0
- package/bindings/node/binding.cc +19 -0
- package/bindings/node/binding_test.js +9 -0
- package/bindings/node/index.d.ts +27 -0
- package/bindings/node/index.js +11 -0
- package/grammar.js +528 -0
- package/package.json +51 -0
- package/queries/highlights.scm +29 -0
- package/src/grammar.json +1940 -0
- package/src/node-types.json +3502 -0
- package/src/parser.c +24817 -0
- package/src/tree_sitter/alloc.h +54 -0
- package/src/tree_sitter/array.h +291 -0
- package/src/tree_sitter/parser.h +286 -0
- package/tree-sitter.json +38 -0
package/grammar.js
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
// one aim is to try to parse what is correct (in the sense of
|
|
2
|
+
// officially supported), but also be looser in parsing additional
|
|
3
|
+
// things. this is more or less in line with advice from tree-sitter
|
|
4
|
+
// folks.
|
|
5
|
+
|
|
6
|
+
function regex(...patts) {
|
|
7
|
+
return RegExp(patts.join(""));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// java.lang.Character.isWhitespace AND comma
|
|
11
|
+
//
|
|
12
|
+
// Space Separator (Zs) but NOT including (U+00A0, U+2007, U+202F)
|
|
13
|
+
// U+0020, U+1680, U+2000, U+2001, U+2002, U+2003, U+2004, U+2005,
|
|
14
|
+
// U+2006, U+2008, U+2009, U+200A, U+205F, U+3000
|
|
15
|
+
// Line Separator (Zl)
|
|
16
|
+
// U+2028
|
|
17
|
+
// Paragraph Separator (Zp)
|
|
18
|
+
// U+2029
|
|
19
|
+
// Horizontal Tabulation
|
|
20
|
+
// \t
|
|
21
|
+
// Line Feed
|
|
22
|
+
// \n
|
|
23
|
+
// Vertical Tabulation
|
|
24
|
+
// U+000B
|
|
25
|
+
// Form Feed
|
|
26
|
+
// \f
|
|
27
|
+
// Carriage Return
|
|
28
|
+
// \r
|
|
29
|
+
// File Separator
|
|
30
|
+
// U+001C
|
|
31
|
+
// Group Separator
|
|
32
|
+
// U+001D
|
|
33
|
+
// Record Separator
|
|
34
|
+
// U+001E
|
|
35
|
+
// Unit Separator
|
|
36
|
+
// U+001F
|
|
37
|
+
const WHITESPACE_CHAR =
|
|
38
|
+
regex("[",
|
|
39
|
+
"\\f\\n\\r\\t, ",
|
|
40
|
+
"\\u000B\\u001C\\u001D\\u001E\\u001F",
|
|
41
|
+
"\\u2028\\u2029\\u1680",
|
|
42
|
+
"\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008",
|
|
43
|
+
"\\u2009\\u200a\\u205f\\u3000",
|
|
44
|
+
"]");
|
|
45
|
+
|
|
46
|
+
const WHITESPACE =
|
|
47
|
+
token(repeat1(WHITESPACE_CHAR));
|
|
48
|
+
|
|
49
|
+
const COMMENT =
|
|
50
|
+
token(regex('(;|#!).*\n?'));
|
|
51
|
+
|
|
52
|
+
const DIGIT =
|
|
53
|
+
regex('[0-9]');
|
|
54
|
+
|
|
55
|
+
const ALPHANUMERIC =
|
|
56
|
+
regex('[0-9a-zA-Z]');
|
|
57
|
+
|
|
58
|
+
const HEX_DIGIT =
|
|
59
|
+
regex('[0-9a-fA-F]');
|
|
60
|
+
|
|
61
|
+
const OCTAL_DIGIT =
|
|
62
|
+
regex('[0-7]');
|
|
63
|
+
|
|
64
|
+
const HEX_NUMBER =
|
|
65
|
+
seq("0",
|
|
66
|
+
regex('[xX]'),
|
|
67
|
+
repeat1(HEX_DIGIT),
|
|
68
|
+
optional("N"));
|
|
69
|
+
|
|
70
|
+
const OCTAL_NUMBER =
|
|
71
|
+
seq("0",
|
|
72
|
+
repeat1(OCTAL_DIGIT),
|
|
73
|
+
optional("N"));
|
|
74
|
+
|
|
75
|
+
// XXX: not constraining number before r/R
|
|
76
|
+
// XXX: not constraining portion after r/R
|
|
77
|
+
const RADIX_NUMBER =
|
|
78
|
+
seq(repeat1(DIGIT),
|
|
79
|
+
regex('[rR]'),
|
|
80
|
+
repeat1(ALPHANUMERIC));
|
|
81
|
+
|
|
82
|
+
const RATIO =
|
|
83
|
+
seq(repeat1(DIGIT),
|
|
84
|
+
"/",
|
|
85
|
+
repeat1(DIGIT));
|
|
86
|
+
|
|
87
|
+
const DOUBLE =
|
|
88
|
+
seq(repeat1(DIGIT),
|
|
89
|
+
optional(seq(".",
|
|
90
|
+
repeat(DIGIT))),
|
|
91
|
+
optional(seq(regex('[eE]'),
|
|
92
|
+
optional(regex('[+-]')),
|
|
93
|
+
repeat1(DIGIT))),
|
|
94
|
+
optional("M"));
|
|
95
|
+
|
|
96
|
+
const INTEGER =
|
|
97
|
+
seq(repeat1(DIGIT),
|
|
98
|
+
optional(regex('[MN]')));
|
|
99
|
+
|
|
100
|
+
const NUMBER =
|
|
101
|
+
token(prec(10, seq(optional(regex('[+-]')),
|
|
102
|
+
choice(HEX_NUMBER,
|
|
103
|
+
OCTAL_NUMBER,
|
|
104
|
+
RADIX_NUMBER,
|
|
105
|
+
RATIO,
|
|
106
|
+
DOUBLE,
|
|
107
|
+
INTEGER))));
|
|
108
|
+
|
|
109
|
+
const NIL =
|
|
110
|
+
token('nil');
|
|
111
|
+
|
|
112
|
+
const BOOLEAN =
|
|
113
|
+
token(choice('false',
|
|
114
|
+
'true'));
|
|
115
|
+
|
|
116
|
+
const KEYWORD_HEAD =
|
|
117
|
+
regex("[^",
|
|
118
|
+
"\\f\\n\\r\\t ",
|
|
119
|
+
"()",
|
|
120
|
+
"\\[\\]",
|
|
121
|
+
"{}",
|
|
122
|
+
'"',
|
|
123
|
+
"@~^;`",
|
|
124
|
+
"\\\\",
|
|
125
|
+
",:/",
|
|
126
|
+
"\\u000B\\u001C\\u001D\\u001E\\u001F",
|
|
127
|
+
"\\u2028\\u2029\\u1680",
|
|
128
|
+
"\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008",
|
|
129
|
+
"\\u2009\\u200a\\u205f\\u3000",
|
|
130
|
+
"]");
|
|
131
|
+
|
|
132
|
+
const KEYWORD_BODY =
|
|
133
|
+
choice(regex("[:']"), KEYWORD_HEAD);
|
|
134
|
+
|
|
135
|
+
const KEYWORD_NAMESPACED_BODY =
|
|
136
|
+
token(repeat1(choice(regex("[:'/]"), KEYWORD_HEAD)));
|
|
137
|
+
|
|
138
|
+
const KEYWORD_NO_SIGIL =
|
|
139
|
+
token(seq(KEYWORD_HEAD,
|
|
140
|
+
repeat(KEYWORD_BODY)));
|
|
141
|
+
|
|
142
|
+
const KEYWORD_MARK =
|
|
143
|
+
token(":");
|
|
144
|
+
|
|
145
|
+
const AUTO_RESOLVE_MARK =
|
|
146
|
+
token("::");
|
|
147
|
+
|
|
148
|
+
const STRING =
|
|
149
|
+
token(seq('"',
|
|
150
|
+
repeat(regex('[^"\\\\]')),
|
|
151
|
+
repeat(seq("\\",
|
|
152
|
+
regex("."),
|
|
153
|
+
repeat(regex('[^"\\\\]')))),
|
|
154
|
+
'"'));
|
|
155
|
+
|
|
156
|
+
// XXX: better to match \o378 as a single item
|
|
157
|
+
const OCTAL_CHAR =
|
|
158
|
+
seq("o",
|
|
159
|
+
choice(seq(DIGIT, DIGIT, DIGIT),
|
|
160
|
+
seq(DIGIT, DIGIT),
|
|
161
|
+
seq(DIGIT)));
|
|
162
|
+
|
|
163
|
+
const NAMED_CHAR =
|
|
164
|
+
choice("backspace",
|
|
165
|
+
"formfeed",
|
|
166
|
+
"newline",
|
|
167
|
+
"return",
|
|
168
|
+
"space",
|
|
169
|
+
"tab");
|
|
170
|
+
|
|
171
|
+
// XXX: outside of: (c >= '\uD800' && c <= '\uDFFF') - LispReader.java
|
|
172
|
+
// but not doing this
|
|
173
|
+
const UNICODE =
|
|
174
|
+
seq("u",
|
|
175
|
+
HEX_DIGIT,
|
|
176
|
+
HEX_DIGIT,
|
|
177
|
+
HEX_DIGIT,
|
|
178
|
+
HEX_DIGIT);
|
|
179
|
+
|
|
180
|
+
// XXX: not quite sure what this is supposed to be...
|
|
181
|
+
// return Character.valueOf(token.charAt(0)); -- LispReader.java
|
|
182
|
+
// java char is 16 bits...what can tree-sitter manage?
|
|
183
|
+
//
|
|
184
|
+
// XXX: null is supposed to be usable but putting \x00 below
|
|
185
|
+
// does not seem to work
|
|
186
|
+
const ANY_CHAR =
|
|
187
|
+
regex('.|\n');
|
|
188
|
+
|
|
189
|
+
const CHARACTER =
|
|
190
|
+
token(seq("\\",
|
|
191
|
+
choice(OCTAL_CHAR,
|
|
192
|
+
NAMED_CHAR,
|
|
193
|
+
UNICODE,
|
|
194
|
+
ANY_CHAR)));
|
|
195
|
+
|
|
196
|
+
const SYMBOL_HEAD =
|
|
197
|
+
regex("[^",
|
|
198
|
+
"\\f\\n\\r\\t ",
|
|
199
|
+
"/",
|
|
200
|
+
"()\\[\\]{}",
|
|
201
|
+
'"',
|
|
202
|
+
"@~^;`",
|
|
203
|
+
"\\\\",
|
|
204
|
+
",:#'0-9",
|
|
205
|
+
"\\u000B\\u001C\\u001D\\u001E\\u001F",
|
|
206
|
+
"\\u2028\\u2029\\u1680",
|
|
207
|
+
"\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008",
|
|
208
|
+
"\\u2009\\u200a\\u205f\\u3000",
|
|
209
|
+
"]");
|
|
210
|
+
|
|
211
|
+
const NS_DELIMITER =
|
|
212
|
+
token("/");
|
|
213
|
+
|
|
214
|
+
const SYMBOL_BODY =
|
|
215
|
+
choice(SYMBOL_HEAD,
|
|
216
|
+
regex("[:#'0-9]"));
|
|
217
|
+
|
|
218
|
+
const SYMBOL_NAMESPACED_NAME =
|
|
219
|
+
token(repeat1(choice(SYMBOL_HEAD,
|
|
220
|
+
regex("[/:#'0-9]"))));
|
|
221
|
+
|
|
222
|
+
// XXX: no attempt is made to enforce certain complex things, e.g.
|
|
223
|
+
//
|
|
224
|
+
// Symbols beginning or ending with ':' are reserved by Clojure.
|
|
225
|
+
// A symbol can contain one or more non-repeating ':'s
|
|
226
|
+
const SYMBOL =
|
|
227
|
+
token(seq(SYMBOL_HEAD,
|
|
228
|
+
repeat(SYMBOL_BODY)));
|
|
229
|
+
|
|
230
|
+
module.exports = grammar({
|
|
231
|
+
name: 'clojure_orchard',
|
|
232
|
+
|
|
233
|
+
extras: $ =>
|
|
234
|
+
[],
|
|
235
|
+
|
|
236
|
+
conflicts: $ =>
|
|
237
|
+
[],
|
|
238
|
+
|
|
239
|
+
inline: $ =>
|
|
240
|
+
[$._kwd_leading_slash,
|
|
241
|
+
$._kwd_just_slash,
|
|
242
|
+
$._kwd_qualified,
|
|
243
|
+
$._kwd_unqualified,
|
|
244
|
+
$._kwd_marker,
|
|
245
|
+
$._sym_qualified,
|
|
246
|
+
$._sym_unqualified],
|
|
247
|
+
|
|
248
|
+
rules: {
|
|
249
|
+
// THIS MUST BE FIRST -- even though this doesn't look like it matters
|
|
250
|
+
source: $ =>
|
|
251
|
+
repeat(choice($._form,
|
|
252
|
+
$._gap)),
|
|
253
|
+
|
|
254
|
+
_gap: $ =>
|
|
255
|
+
choice($._ws,
|
|
256
|
+
$.comment,
|
|
257
|
+
$.dis_expr),
|
|
258
|
+
|
|
259
|
+
_ws: $ =>
|
|
260
|
+
WHITESPACE,
|
|
261
|
+
|
|
262
|
+
comment: $ =>
|
|
263
|
+
COMMENT,
|
|
264
|
+
|
|
265
|
+
dis_expr: $ =>
|
|
266
|
+
seq(field('marker', "#_"),
|
|
267
|
+
repeat($._gap),
|
|
268
|
+
field('value', $._form)),
|
|
269
|
+
|
|
270
|
+
_form: $ =>
|
|
271
|
+
choice($.num_lit, // atom-ish
|
|
272
|
+
$.kwd_lit,
|
|
273
|
+
$.str_lit,
|
|
274
|
+
$.char_lit,
|
|
275
|
+
$.nil_lit,
|
|
276
|
+
$.bool_lit,
|
|
277
|
+
$.sym_lit,
|
|
278
|
+
// basic collection-ish
|
|
279
|
+
$.list_lit,
|
|
280
|
+
$.map_lit,
|
|
281
|
+
$.vec_lit,
|
|
282
|
+
// dispatch reader macros
|
|
283
|
+
$.set_lit,
|
|
284
|
+
$.anon_fn_lit,
|
|
285
|
+
$.regex_lit,
|
|
286
|
+
$.read_cond_lit,
|
|
287
|
+
$.splicing_read_cond_lit,
|
|
288
|
+
$.ns_map_lit,
|
|
289
|
+
$.var_quoting_lit,
|
|
290
|
+
$.sym_val_lit,
|
|
291
|
+
$.evaling_lit,
|
|
292
|
+
$.tagged_or_ctor_lit,
|
|
293
|
+
// some other reader macros
|
|
294
|
+
$.derefing_lit,
|
|
295
|
+
$.quoting_lit,
|
|
296
|
+
$.syn_quoting_lit,
|
|
297
|
+
$.unquote_splicing_lit,
|
|
298
|
+
$.unquoting_lit),
|
|
299
|
+
|
|
300
|
+
num_lit: $ =>
|
|
301
|
+
NUMBER,
|
|
302
|
+
|
|
303
|
+
kwd_lit: $ =>
|
|
304
|
+
choice($._kwd_leading_slash,
|
|
305
|
+
$._kwd_just_slash,
|
|
306
|
+
$._kwd_qualified,
|
|
307
|
+
$._kwd_unqualified),
|
|
308
|
+
|
|
309
|
+
// (namespace :/usr/bin/env) ; => ""
|
|
310
|
+
// (name :/usr/bin/env) ; => "usr/bin/env"
|
|
311
|
+
_kwd_leading_slash: $ =>
|
|
312
|
+
seq(field('marker', $._kwd_marker),
|
|
313
|
+
field('delimiter', NS_DELIMITER),
|
|
314
|
+
field('name', alias(KEYWORD_NAMESPACED_BODY, $.kwd_name))),
|
|
315
|
+
|
|
316
|
+
// (namespace :/) ;=> nil
|
|
317
|
+
// (name :/) ;=> "/"
|
|
318
|
+
_kwd_just_slash: $ =>
|
|
319
|
+
seq(field('marker', $._kwd_marker),
|
|
320
|
+
field('name', alias(NS_DELIMITER, $.kwd_name))),
|
|
321
|
+
|
|
322
|
+
_kwd_qualified: $ =>
|
|
323
|
+
prec(2, seq(field('marker', $._kwd_marker),
|
|
324
|
+
field('namespace', alias(KEYWORD_NO_SIGIL, $.kwd_ns)),
|
|
325
|
+
field('delimiter', NS_DELIMITER),
|
|
326
|
+
field('name', alias(KEYWORD_NAMESPACED_BODY, $.kwd_name)))),
|
|
327
|
+
|
|
328
|
+
_kwd_unqualified: $ =>
|
|
329
|
+
prec(1, seq(field('marker', $._kwd_marker),
|
|
330
|
+
field('name', alias(KEYWORD_NO_SIGIL, $.kwd_name)))),
|
|
331
|
+
|
|
332
|
+
_kwd_marker: $ =>
|
|
333
|
+
choice(KEYWORD_MARK, AUTO_RESOLVE_MARK),
|
|
334
|
+
|
|
335
|
+
str_lit: $ =>
|
|
336
|
+
STRING,
|
|
337
|
+
|
|
338
|
+
char_lit: $ =>
|
|
339
|
+
CHARACTER,
|
|
340
|
+
|
|
341
|
+
nil_lit: $ =>
|
|
342
|
+
NIL,
|
|
343
|
+
|
|
344
|
+
bool_lit: $ =>
|
|
345
|
+
BOOLEAN,
|
|
346
|
+
|
|
347
|
+
sym_lit: $ =>
|
|
348
|
+
seq(repeat($._metadata_lit),
|
|
349
|
+
choice($._sym_qualified, $._sym_unqualified)),
|
|
350
|
+
|
|
351
|
+
_sym_qualified: $ =>
|
|
352
|
+
prec(1, seq(field("namespace", alias(SYMBOL, $.sym_ns)),
|
|
353
|
+
field("delimiter", NS_DELIMITER),
|
|
354
|
+
field("name", alias(SYMBOL_NAMESPACED_NAME, $.sym_name)))),
|
|
355
|
+
|
|
356
|
+
_sym_unqualified: $ =>
|
|
357
|
+
field('name', alias(choice(NS_DELIMITER, // division symbol
|
|
358
|
+
SYMBOL),
|
|
359
|
+
$.sym_name)),
|
|
360
|
+
|
|
361
|
+
_metadata_lit: $ =>
|
|
362
|
+
seq(choice(field("meta", $.meta_lit),
|
|
363
|
+
field("old_meta", $.old_meta_lit)),
|
|
364
|
+
optional(repeat($._gap))),
|
|
365
|
+
|
|
366
|
+
meta_lit: $ =>
|
|
367
|
+
seq(field('marker', "^"),
|
|
368
|
+
repeat($._gap),
|
|
369
|
+
field('value', $._form)),
|
|
370
|
+
|
|
371
|
+
old_meta_lit: $ =>
|
|
372
|
+
seq(field('marker', "#^"),
|
|
373
|
+
repeat($._gap),
|
|
374
|
+
field('value', $._form)),
|
|
375
|
+
|
|
376
|
+
list_lit: $ =>
|
|
377
|
+
seq(repeat($._metadata_lit),
|
|
378
|
+
$._bare_list_lit),
|
|
379
|
+
|
|
380
|
+
_bare_list_lit: $ =>
|
|
381
|
+
seq(field('open', "("),
|
|
382
|
+
repeat(choice(field('value', $._form),
|
|
383
|
+
$._gap)),
|
|
384
|
+
field('close', ")")),
|
|
385
|
+
|
|
386
|
+
map_lit: $ =>
|
|
387
|
+
seq(repeat($._metadata_lit),
|
|
388
|
+
$._bare_map_lit),
|
|
389
|
+
|
|
390
|
+
_bare_map_lit: $ =>
|
|
391
|
+
seq(field('open', "{"),
|
|
392
|
+
repeat(choice(field('value', $._form),
|
|
393
|
+
$._gap)),
|
|
394
|
+
field('close', "}")),
|
|
395
|
+
|
|
396
|
+
vec_lit: $ =>
|
|
397
|
+
seq(repeat($._metadata_lit),
|
|
398
|
+
$._bare_vec_lit),
|
|
399
|
+
|
|
400
|
+
_bare_vec_lit: $ =>
|
|
401
|
+
seq(field('open', "["),
|
|
402
|
+
repeat(choice(field('value', $._form),
|
|
403
|
+
$._gap)),
|
|
404
|
+
field('close', "]")),
|
|
405
|
+
|
|
406
|
+
set_lit: $ =>
|
|
407
|
+
seq(repeat($._metadata_lit),
|
|
408
|
+
$._bare_set_lit),
|
|
409
|
+
|
|
410
|
+
_bare_set_lit: $ =>
|
|
411
|
+
seq(field('marker', "#"),
|
|
412
|
+
field('open', "{"),
|
|
413
|
+
repeat(choice(field('value', $._form),
|
|
414
|
+
$._gap)),
|
|
415
|
+
field('close', "}")),
|
|
416
|
+
|
|
417
|
+
anon_fn_lit: $ =>
|
|
418
|
+
seq(repeat($._metadata_lit),
|
|
419
|
+
field('marker', "#"),
|
|
420
|
+
$._bare_list_lit),
|
|
421
|
+
|
|
422
|
+
regex_lit: $ =>
|
|
423
|
+
seq(field('marker', "#"),
|
|
424
|
+
STRING),
|
|
425
|
+
|
|
426
|
+
read_cond_lit: $ =>
|
|
427
|
+
seq(repeat($._metadata_lit),
|
|
428
|
+
field('marker', "#?"),
|
|
429
|
+
// whitespace possible, but neither comment nor discard
|
|
430
|
+
repeat($._ws),
|
|
431
|
+
$._bare_list_lit),
|
|
432
|
+
|
|
433
|
+
splicing_read_cond_lit: $ =>
|
|
434
|
+
// XXX: metadata here doesn't seem to make sense, but the repl
|
|
435
|
+
// will accept: [^:x #?@(:clj [[:a]] :cljr [[:b]])]
|
|
436
|
+
seq(repeat($._metadata_lit),
|
|
437
|
+
field('marker', "#?@"),
|
|
438
|
+
// whitespace possible, but neither comment nor discard
|
|
439
|
+
repeat($._ws),
|
|
440
|
+
$._bare_list_lit),
|
|
441
|
+
|
|
442
|
+
auto_res_mark: $ =>
|
|
443
|
+
AUTO_RESOLVE_MARK,
|
|
444
|
+
|
|
445
|
+
ns_map_lit: $ =>
|
|
446
|
+
seq(repeat($._metadata_lit),
|
|
447
|
+
field('marker', "#"),
|
|
448
|
+
field('prefix', choice($.auto_res_mark,
|
|
449
|
+
$.kwd_lit)),
|
|
450
|
+
repeat($._gap),
|
|
451
|
+
$._bare_map_lit),
|
|
452
|
+
|
|
453
|
+
var_quoting_lit: $ =>
|
|
454
|
+
seq(repeat($._metadata_lit),
|
|
455
|
+
field('marker', "#'"),
|
|
456
|
+
repeat($._gap),
|
|
457
|
+
// XXX: symbol, reader conditional, and tagged literal can work
|
|
458
|
+
// any other things?
|
|
459
|
+
field('value', $._form)),
|
|
460
|
+
|
|
461
|
+
sym_val_lit: $ =>
|
|
462
|
+
seq(field('marker', "##"),
|
|
463
|
+
repeat($._gap),
|
|
464
|
+
field('value', $._form)),
|
|
465
|
+
|
|
466
|
+
evaling_lit: $ =>
|
|
467
|
+
seq(repeat($._metadata_lit), // ^:x #=(vector 1)
|
|
468
|
+
field('marker', "#="),
|
|
469
|
+
repeat($._gap),
|
|
470
|
+
field('value', choice($.list_lit,
|
|
471
|
+
$.read_cond_lit,
|
|
472
|
+
// #= ^:a java.lang.String
|
|
473
|
+
$.sym_lit))),
|
|
474
|
+
|
|
475
|
+
// #uuid "00000000-0000-0000-0000-000000000000"
|
|
476
|
+
// #user.Fun[1 2]
|
|
477
|
+
// #user.Fun{:a 1 :b 2}
|
|
478
|
+
tagged_or_ctor_lit: $ =>
|
|
479
|
+
seq(repeat($._metadata_lit),
|
|
480
|
+
field('marker', "#"),
|
|
481
|
+
// # uuid "00000000-0000-0000-0000-000000000000"
|
|
482
|
+
// # #_ 1 uuid "00000000-0000-0000-0000-000000000000"
|
|
483
|
+
// etc.
|
|
484
|
+
repeat($._gap),
|
|
485
|
+
// # ^:a uuid "00000000-0000-0000-0000-000000000000"
|
|
486
|
+
field('tag', $.sym_lit),
|
|
487
|
+
repeat($._gap),
|
|
488
|
+
field('value', $._form)),
|
|
489
|
+
|
|
490
|
+
derefing_lit: $ =>
|
|
491
|
+
seq(repeat($._metadata_lit),
|
|
492
|
+
field('marker', "@"),
|
|
493
|
+
repeat($._gap),
|
|
494
|
+
field('value', $._form)),
|
|
495
|
+
|
|
496
|
+
quoting_lit: $ =>
|
|
497
|
+
seq(repeat($._metadata_lit),
|
|
498
|
+
field('marker', "'"),
|
|
499
|
+
repeat($._gap),
|
|
500
|
+
field('value', $._form)),
|
|
501
|
+
|
|
502
|
+
syn_quoting_lit: $ =>
|
|
503
|
+
seq(repeat($._metadata_lit),
|
|
504
|
+
field('marker', "`"),
|
|
505
|
+
repeat($._gap),
|
|
506
|
+
field('value', $._form)),
|
|
507
|
+
|
|
508
|
+
unquote_splicing_lit: $ =>
|
|
509
|
+
// XXX: metadata here doesn't seem to make sense, but the repl
|
|
510
|
+
// will accept: `(^:x ~@[:a :b :c])
|
|
511
|
+
seq(repeat($._metadata_lit),
|
|
512
|
+
field('marker', "~@"),
|
|
513
|
+
repeat($._gap),
|
|
514
|
+
field('value', $._form)),
|
|
515
|
+
|
|
516
|
+
unquoting_lit: $ =>
|
|
517
|
+
seq(repeat($._metadata_lit),
|
|
518
|
+
field('marker', "~"),
|
|
519
|
+
repeat($._gap),
|
|
520
|
+
field('value', $._form)),
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// Local Variables:
|
|
525
|
+
// mode: js-mode
|
|
526
|
+
// js-indent-align-list-continuation: t
|
|
527
|
+
// js-indent-level: 2
|
|
528
|
+
// End:
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tree-sitter-clojure-orchard",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Parser for Clojure files",
|
|
5
|
+
"repository": "https://codeberg.org/grammar-orchard/tree-sitter-clojure-orchard",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "a"
|
|
9
|
+
},
|
|
10
|
+
"main": "bindings/node",
|
|
11
|
+
"types": "bindings/node",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"incremental",
|
|
14
|
+
"parsing",
|
|
15
|
+
"tree-sitter",
|
|
16
|
+
"clojure_orchard"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"grammar.js",
|
|
20
|
+
"tree-sitter.json",
|
|
21
|
+
"binding.gyp",
|
|
22
|
+
"prebuilds/**",
|
|
23
|
+
"bindings/node/*",
|
|
24
|
+
"queries/*",
|
|
25
|
+
"src/**",
|
|
26
|
+
"*.wasm"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"node-addon-api": "^8.5.0",
|
|
30
|
+
"node-gyp-build": "^4.8.4"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"prebuildify": "^6.0.1",
|
|
34
|
+
"tree-sitter": "^0.22.4",
|
|
35
|
+
"tree-sitter-cli": "^0.25.9"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"tree-sitter": "^0.22.4"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"tree-sitter": {
|
|
42
|
+
"optional": true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"install": "node-gyp-build",
|
|
47
|
+
"prestart": "tree-sitter build --wasm",
|
|
48
|
+
"start": "tree-sitter playground",
|
|
49
|
+
"test": "node --test bindings/node/*_test.js"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
;; Literals
|
|
2
|
+
|
|
3
|
+
(num_lit) @number
|
|
4
|
+
|
|
5
|
+
[
|
|
6
|
+
(char_lit)
|
|
7
|
+
(str_lit)
|
|
8
|
+
] @string
|
|
9
|
+
|
|
10
|
+
[
|
|
11
|
+
(bool_lit)
|
|
12
|
+
(nil_lit)
|
|
13
|
+
] @constant.builtin
|
|
14
|
+
|
|
15
|
+
(kwd_lit) @constant
|
|
16
|
+
|
|
17
|
+
;; Comments
|
|
18
|
+
|
|
19
|
+
(comment) @comment
|
|
20
|
+
|
|
21
|
+
;; Treat quasiquotation as operators for the purpose of highlighting.
|
|
22
|
+
|
|
23
|
+
[
|
|
24
|
+
"'"
|
|
25
|
+
"`"
|
|
26
|
+
"~"
|
|
27
|
+
"@"
|
|
28
|
+
"~@"
|
|
29
|
+
] @operator
|