summaryrefslogtreecommitdiff
path: root/stag/src/stag.scm
diff options
context:
space:
mode:
Diffstat (limited to 'stag/src/stag.scm')
-rw-r--r--stag/src/stag.scm538
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