diff options
Diffstat (limited to 'stag/src/stag.scm')
-rw-r--r-- | stag/src/stag.scm | 538 |
1 files changed, 526 insertions, 12 deletions
diff --git a/stag/src/stag.scm b/stag/src/stag.scm index b6271b8..dc56e74 100644 --- a/stag/src/stag.scm +++ b/stag/src/stag.scm | |||
@@ -1,36 +1,550 @@ | |||
1 | [ | 1 | [(block) |
2 | (block) | ||
3 | (declaration_list) | 2 | (declaration_list) |
4 | (impl_item) | 3 | (impl_item) |
5 | (struct_item) | 4 | |
6 | (enum_item) | 5 | ;; let expressions create scopes |
7 | (union_item) | ||
8 | (type_item) | ||
9 | (trait_item) | ||
10 | (if_expression | 6 | (if_expression |
11 | [(let_condition) | 7 | [(let_condition) |
12 | (let_chain)]) | 8 | (let_chain)]) |
13 | ] @cap | 9 | |
10 | ;; each match arm can bind variables with | ||
11 | ;; patterns, without creating a block scope; | ||
12 | ;; | ||
13 | ;; match _ { | ||
14 | ;; (a, b) => a, | ||
15 | ;; } | ||
16 | ;; | ||
17 | ;; The bindings for a, b are constrained to | ||
18 | ;; the match arm. | ||
19 | (match_arm) | ||
20 | |||
21 | ;; loop labels are defs that are available only | ||
22 | ;; within the scope they create: | ||
23 | ;; | ||
24 | ;; 'outer: loop { | ||
25 | ;; let x = 2; | ||
26 | ;; }; | ||
27 | ;; let y = 2; | ||
28 | ;; | ||
29 | ;; Produces a scope graph like so: | ||
30 | ;; | ||
31 | ;; { | ||
32 | ;; defs: [ y ], | ||
33 | ;; scopes: [ | ||
34 | ;; { | ||
35 | ;; defs: [ 'outer ], | ||
36 | ;; scopes: [ | ||
37 | ;; { | ||
38 | ;; defs: [ x ] | ||
39 | ;; } | ||
40 | ;; ] | ||
41 | ;; } | ||
42 | ;; ] | ||
43 | ;; } | ||
44 | ;; | ||
45 | (loop_expression) | ||
46 | (for_expression) | ||
47 | (while_expression)] @cap | ||
14 | { | 48 | { |
15 | (scope (range @cap)) | 49 | (scope (range @cap)) |
16 | } | 50 | } |
17 | 51 | ||
52 | |||
18 | (function_item | 53 | (function_item |
54 | (identifier) @i | ||
19 | (parameters) @params | 55 | (parameters) @params |
20 | (block) @body) | 56 | (block) @body) |
21 | { | 57 | { |
58 | (def @i "function") | ||
22 | (scope (cover @params @body)) | 59 | (scope (cover @params @body)) |
23 | } | 60 | } |
24 | 61 | ||
25 | 62 | ||
26 | (let_declaration | 63 | ;; impl items can define types and lifetimes: |
27 | pattern: (identifier) @cap) | 64 | ;; |
65 | ;; impl<'a, T> Trait for Struct { .. } | ||
66 | ;; | ||
67 | ;; in order to constrain those to the impl block, | ||
68 | ;; we add a local scope here: | ||
69 | [(struct_item (type_identifier) @i (type_parameters)? @t body: (_) @b) | ||
70 | (union_item (type_identifier) @i (type_parameters)? @t body: (_) @b) | ||
71 | (enum_item (type_identifier) @i (type_parameters)? @t body: (_) @b) | ||
72 | (type_item (type_identifier) @i (type_parameters)? @t type: (_) @b) | ||
73 | (trait_item (type_identifier) @i (type_parameters)? @t body: (_) @b)] | ||
74 | { | ||
75 | (def @i) | ||
76 | (scope (cover @t @b)) | ||
77 | (scope (range @b)) | ||
78 | } | ||
79 | |||
80 | |||
81 | ;; DEFS | ||
82 | ;; ---- | ||
83 | |||
84 | ;; let x = ...; | ||
85 | (let_declaration pattern: (identifier) @cap) | ||
86 | { | ||
87 | (def @cap "variable") | ||
88 | } | ||
89 | |||
90 | ;; if let x = ...; | ||
91 | ;; while let x = ...; | ||
92 | (let_condition (identifier) @cap . "=") | ||
93 | { | ||
94 | (def @cap "variable") | ||
95 | } | ||
96 | |||
97 | ;; let (a, b, ...) = ..; | ||
98 | ;; if let (a, b, ...) = {} | ||
99 | ;; while let (a, b, ...) = {} | ||
100 | ;; match _ { (a, b) => { .. } } | ||
101 | (tuple_pattern (identifier) @cap) | ||
102 | { | ||
103 | (def @cap "variable") | ||
104 | } | ||
105 | |||
106 | ;; Some(a) | ||
107 | (tuple_struct_pattern | ||
108 | type: (_) | ||
109 | (identifier) @cap) | ||
110 | { | ||
111 | (def @cap "variable") | ||
112 | } | ||
113 | |||
114 | ;; let S { field: a } = ..; | ||
115 | (struct_pattern | ||
116 | (field_pattern | ||
117 | (identifier) @cap)) | ||
118 | { | ||
119 | (def @cap "variable") | ||
120 | } | ||
121 | |||
122 | |||
123 | [ | ||
124 | ;; (mut x: T) | ||
125 | (mut_pattern (identifier) @i) | ||
126 | |||
127 | ;; (ref x: T) | ||
128 | (ref_pattern (identifier) @i) | ||
129 | |||
130 | ;; const x = ...; | ||
131 | (const_item (identifier) @i) | ||
132 | |||
133 | ;; static x = ...; | ||
134 | (static_item (identifier) @i)] | ||
135 | { | ||
136 | (def @i "variable") | ||
137 | } | ||
138 | |||
139 | ;; fn _(x: _) | ||
140 | (parameters | ||
141 | (parameter | ||
142 | pattern: (identifier) @cap)) | ||
143 | { | ||
144 | (def @cap) | ||
145 | } | ||
146 | |||
147 | ;; fn _(self) | ||
148 | (parameters | ||
149 | (self_parameter | ||
150 | (self) @cap)) | ||
151 | { | ||
152 | (def @cap) | ||
153 | } | ||
154 | |||
155 | ;; type parameters | ||
156 | (type_parameters | ||
157 | (type_identifier) @cap) | ||
158 | { | ||
159 | (def @cap) | ||
160 | } | ||
161 | (type_parameters | ||
162 | (lifetime) @cap) | ||
163 | { | ||
164 | (def @cap) | ||
165 | } | ||
166 | (constrained_type_parameter | ||
167 | left: (type_identifier) @cap) | ||
168 | { | ||
169 | (def @cap) | ||
170 | } | ||
171 | |||
172 | ;; |x| { ... } | ||
173 | ;; no type | ||
174 | (closure_parameters (identifier) @cap) | ||
175 | { | ||
176 | (def @cap) | ||
177 | } | ||
178 | |||
179 | ;; |x: T| { ... } | ||
180 | ;; with type | ||
181 | (closure_parameters | ||
182 | (parameter | ||
183 | (identifier) @cap)) | ||
184 | { | ||
185 | (def @cap) | ||
186 | } | ||
187 | |||
188 | ;; 'outer: loop { .. } | ||
189 | (loop_expression | ||
190 | (loop_label) @cap) | ||
191 | { | ||
192 | (def @cap) | ||
193 | } | ||
194 | |||
195 | ;; `for` exprs create two defs: a label (if any) and the | ||
196 | ;; loop variable | ||
197 | (for_expression . (identifier) @cap) | ||
198 | { | ||
199 | (def @cap) | ||
200 | } | ||
201 | (for_expression (loop_label) @cap) | ||
28 | { | 202 | { |
29 | (def @cap) | 203 | (def @cap) |
30 | } | 204 | } |
31 | 205 | ||
206 | ;; 'label: while cond { .. } | ||
207 | (while_expression | ||
208 | (loop_label) @cap) | ||
209 | { | ||
210 | (def @cap) | ||
211 | } | ||
32 | 212 | ||
33 | (binary_expression (identifier) @c) { | 213 | ;; struct and union fields |
34 | (ref @c) | 214 | (field_declaration_list |
215 | (field_declaration | ||
216 | (field_identifier) @cap)) | ||
217 | { | ||
218 | (def @cap) | ||
35 | } | 219 | } |
36 | 220 | ||
221 | ;; enum variants | ||
222 | (enum_variant_list | ||
223 | (enum_variant | ||
224 | (identifier) @cap)) | ||
225 | { | ||
226 | (def @cap) | ||
227 | } | ||
228 | |||
229 | ;; mod x; | ||
230 | (mod_item (identifier) @cap) | ||
231 | { | ||
232 | (def @cap) | ||
233 | } | ||
234 | |||
235 | |||
236 | ;; IMPORTS | ||
237 | ;; ------- | ||
238 | |||
239 | ;; use item; | ||
240 | (use_declaration | ||
241 | (identifier) @cap) | ||
242 | { | ||
243 | (def @cap) | ||
244 | } | ||
245 | |||
246 | ;; use path as item; | ||
247 | (use_as_clause | ||
248 | alias: (identifier) @cap) | ||
249 | { | ||
250 | (def @cap) | ||
251 | } | ||
252 | |||
253 | ;; use path::item; | ||
254 | (use_declaration | ||
255 | (scoped_identifier | ||
256 | name: (identifier) @cap)) | ||
257 | { | ||
258 | (def @cap) | ||
259 | } | ||
260 | |||
261 | ;; use module::{member1, member2, member3}; | ||
262 | (use_list | ||
263 | (identifier) @cap) | ||
264 | { | ||
265 | (def @cap) | ||
266 | } | ||
267 | |||
268 | (use_list | ||
269 | (scoped_identifier | ||
270 | name: (identifier) @cap)) | ||
271 | { | ||
272 | (def @cap) | ||
273 | } | ||
274 | |||
275 | |||
276 | ;; REFS | ||
277 | ;; ---- | ||
278 | |||
279 | [ | ||
280 | ;; !x | ||
281 | (unary_expression (identifier) @cap) | ||
282 | ;; &x | ||
283 | (reference_expression (identifier) @cap) | ||
284 | |||
285 | ;; (x) | ||
286 | (parenthesized_expression (identifier) @cap) | ||
287 | |||
288 | ;; x? | ||
289 | (try_expression (identifier) @cap) | ||
290 | |||
291 | ;; a = b | ||
292 | (assignment_expression (identifier) @cap) | ||
293 | |||
294 | ;; a op b | ||
295 | (binary_expression (identifier) @cap) | ||
296 | |||
297 | ;; a op= b | ||
298 | (compound_assignment_expr (identifier) @cap) | ||
299 | |||
300 | ;; a as b | ||
301 | (type_cast_expression (identifier) @cap) | ||
302 | |||
303 | ;; a() | ||
304 | (call_expression (identifier) @cap) | ||
305 | |||
306 | ;; return a | ||
307 | (return_expression (identifier) @cap) | ||
308 | |||
309 | ;; break a | ||
310 | (break_expression (identifier) @cap) | ||
311 | |||
312 | ;; break 'label | ||
313 | (break_expression (loop_label) @cap) | ||
314 | |||
315 | ;; continue 'label; | ||
316 | (continue_expression (loop_label) @cap) | ||
317 | |||
318 | ;; yield x; | ||
319 | (yield_expression (identifier) @cap) | ||
320 | |||
321 | ;; await a | ||
322 | (await_expression (identifier) @cap) | ||
323 | |||
324 | ;; (a, b) | ||
325 | (tuple_expression (identifier) @cap) | ||
326 | |||
327 | ;; a[] | ||
328 | (index_expression (identifier) @cap) | ||
329 | |||
330 | ;; ident; | ||
331 | (expression_statement (identifier) @cap) | ||
332 | |||
333 | ;; a..b | ||
334 | (range_expression (identifier) @cap) | ||
335 | |||
336 | ;; [ident; N] | ||
337 | (array_expression (identifier) @cap) | ||
338 | |||
339 | ;; path::to::item | ||
340 | ;; | ||
341 | ;; `path` is a ref | ||
342 | (scoped_identifier | ||
343 | path: (identifier) @cap) | ||
344 | |||
345 | ;; rhs of let decls | ||
346 | (let_declaration | ||
347 | value: (identifier) @cap) | ||
348 | |||
349 | ;; type T = [T; N] | ||
350 | ;; | ||
351 | ;; N is a ident ref | ||
352 | (array_type | ||
353 | length: (identifier) @cap) | ||
354 | |||
355 | ;; S { _ } | ||
356 | (struct_expression | ||
357 | (type_identifier) @cap) | ||
358 | |||
359 | ;; S { a } | ||
360 | (struct_expression | ||
361 | (field_initializer_list | ||
362 | (shorthand_field_initializer | ||
363 | (identifier) @cap))) | ||
364 | |||
365 | ;; S { a: value } | ||
366 | (struct_expression | ||
367 | (field_initializer_list | ||
368 | (field_initializer | ||
369 | (identifier) @cap))) | ||
370 | |||
371 | ;; S { ..a } | ||
372 | (struct_expression | ||
373 | (field_initializer_list | ||
374 | (base_field_initializer | ||
375 | (identifier) @cap))) | ||
376 | |||
377 | ;; if a {} | ||
378 | (if_expression (identifier) @cap) | ||
379 | |||
380 | ;; for pattern in value {} | ||
381 | ;; | ||
382 | ;; `value` is a ref | ||
383 | (for_expression | ||
384 | value: (identifier) @cap) | ||
385 | |||
386 | ;; while a {} | ||
387 | (while_expression (identifier) @cap) | ||
388 | |||
389 | ;; match a | ||
390 | (match_expression (identifier) @cap) | ||
391 | |||
392 | ;; match _ { | ||
393 | ;; pattern => a, | ||
394 | ;; } | ||
395 | ;; | ||
396 | ;; this `a` is somehow not any expression form | ||
397 | (match_arm (identifier) @cap) | ||
398 | |||
399 | ;; a.b | ||
400 | ;; | ||
401 | ;; `b` is ignored | ||
402 | (field_expression | ||
403 | (identifier) @cap) | ||
404 | |||
405 | ;; { stmt; foo } | ||
406 | (block | ||
407 | (identifier) @cap) | ||
408 | |||
409 | ;; arguments to method calls or function calls | ||
410 | (arguments | ||
411 | (identifier) @cap) | ||
412 | |||
413 | ;; impl S { .. } | ||
414 | (impl_item (type_identifier) @cap) | ||
415 | |||
416 | ;; where T: ... | ||
417 | (where_predicate | ||
418 | left: (type_identifier) @cap) | ||
419 | |||
420 | ;; trait bounds | ||
421 | (trait_bounds | ||
422 | (type_identifier) @cap) | ||
423 | (trait_bounds | ||
424 | (lifetime) @cap) | ||
425 | |||
426 | ;; idents in macros | ||
427 | (token_tree | ||
428 | (identifier) @cap) | ||
429 | |||
430 | |||
431 | ;; types | ||
432 | |||
433 | ;; (T, U) | ||
434 | (tuple_type | ||
435 | (type_identifier) @cap) | ||
436 | |||
437 | ;; &T | ||
438 | (reference_type | ||
439 | (type_identifier) @cap) | ||
440 | |||
441 | ;; &'a T | ||
442 | (reference_type | ||
443 | (lifetime) @cap) | ||
444 | |||
445 | ;; &'a self | ||
446 | (self_parameter | ||
447 | (lifetime) @cap) | ||
448 | |||
449 | ;; *mut T | ||
450 | ;; *const T | ||
451 | (pointer_type | ||
452 | (type_identifier) @cap) | ||
453 | |||
454 | ;; A<_> | ||
455 | (generic_type | ||
456 | (type_identifier) @cap) | ||
457 | |||
458 | ;; _<V> | ||
459 | (type_arguments | ||
460 | (type_identifier) @cap) | ||
461 | (type_arguments | ||
462 | (lifetime) @cap) | ||
463 | |||
464 | ;; T<U = V> | ||
465 | ;; | ||
466 | ;; U is ignored | ||
467 | ;; V is a ref | ||
468 | (type_binding | ||
469 | name: (_) | ||
470 | type: (type_identifier) @cap) | ||
471 | |||
472 | ;; [T] | ||
473 | (array_type | ||
474 | (type_identifier) @cap) | ||
475 | |||
476 | ;; type T = U; | ||
477 | ;; | ||
478 | ;; T is a def | ||
479 | ;; U is a ref | ||
480 | (type_item | ||
481 | name: (_) | ||
482 | type: (type_identifier) @cap) | ||
483 | |||
484 | (function_item | ||
485 | return_type: (type_identifier) @cap) | ||
486 | |||
487 | ;; type refs in params | ||
488 | ;; | ||
489 | ;; fn _(_: T) | ||
490 | (parameters | ||
491 | (parameter | ||
492 | type: (type_identifier) @cap)) | ||
493 | |||
494 | ;; dyn T | ||
495 | (dynamic_type | ||
496 | (type_identifier) @cap) | ||
497 | |||
498 | ;; <T>::call() | ||
499 | (bracketed_type | ||
500 | (type_identifier) @cap) | ||
501 | |||
502 | ;; T as Trait | ||
503 | (qualified_type | ||
504 | (type_identifier) @cap) | ||
505 | |||
506 | ;; module::T | ||
507 | ;; | ||
508 | ;; `module` is a def | ||
509 | ;; `T` is a ref | ||
510 | (scoped_type_identifier | ||
511 | path: (identifier) @cap) | ||
512 | |||
513 | ;; struct _ { field: Type } | ||
514 | ;; `Type` is a ref | ||
515 | (field_declaration | ||
516 | name: (_) | ||
517 | type: (type_identifier) @cap) | ||
518 | |||
519 | ;; Self::foo() | ||
520 | ;; | ||
521 | ;; `foo` can be resolved | ||
522 | (call_expression | ||
523 | (scoped_identifier | ||
524 | (identifier) @_self_type | ||
525 | (identifier) @cap) | ||
526 | (#match? @_self_type "Self")) | ||
527 | |||
528 | ;; self.foo() | ||
529 | ;; | ||
530 | ;; `foo` can be resolved | ||
531 | (call_expression | ||
532 | (field_expression | ||
533 | (self) | ||
534 | (field_identifier) @cap)) | ||
535 | |||
536 | ;; if let _ = a {} | ||
537 | ;; | ||
538 | ;; the ident following the `=` is a ref | ||
539 | ;; the ident preceding the `=` is a def | ||
540 | ;; while let _ = a {} | ||
541 | (let_condition | ||
542 | "=" | ||
543 | . | ||
544 | (identifier) @cap) | ||
545 | ] | ||
546 | { | ||
547 | (ref @cap) | ||
548 | } | ||
549 | |||
550 | |||