diff options
author | Aleksey Kladov <[email protected]> | 2018-08-05 12:08:46 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-05 12:08:46 +0100 |
commit | c871022f9810547f3eeaa5af3a3dc4bc0c85a386 (patch) | |
tree | 71d74bbc3872c7cf5f0731639c196a81c93b9eee /src | |
parent | b513e94d88c8702a051acf4d58c0335c9aed9db2 (diff) |
item-macros
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.ron | 2 | ||||
-rw-r--r-- | src/grammar/items/mod.rs | 78 | ||||
-rw-r--r-- | src/grammar/items/traits.rs | 2 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 4 |
4 files changed, 77 insertions, 9 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index 9f80b3ebf..0a79eeb95 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -109,6 +109,8 @@ Grammar( | |||
109 | "TRAIT_ITEM", | 109 | "TRAIT_ITEM", |
110 | "IMPL_ITEM", | 110 | "IMPL_ITEM", |
111 | "TYPE_ITEM", | 111 | "TYPE_ITEM", |
112 | "MACRO_CALL", | ||
113 | "TOKEN_TREE", | ||
112 | 114 | ||
113 | "PAREN_TYPE", | 115 | "PAREN_TYPE", |
114 | "TUPLE_TYPE", | 116 | "TUPLE_TYPE", |
diff --git a/src/grammar/items/mod.rs b/src/grammar/items/mod.rs index 1ed0aea07..8f766901e 100644 --- a/src/grammar/items/mod.rs +++ b/src/grammar/items/mod.rs | |||
@@ -5,27 +5,43 @@ mod structs; | |||
5 | mod traits; | 5 | mod traits; |
6 | mod use_item; | 6 | mod use_item; |
7 | 7 | ||
8 | // test mod_contents | ||
9 | // fn foo() {} | ||
10 | // macro_rules! foo {} | ||
11 | // foo::bar!(); | ||
12 | // super::baz! {} | ||
13 | // struct S; | ||
8 | pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { | 14 | pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { |
9 | attributes::inner_attributes(p); | 15 | attributes::inner_attributes(p); |
10 | while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { | 16 | while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { |
11 | item(p, stop_on_r_curly) | 17 | item_or_macro(p, stop_on_r_curly) |
12 | } | 18 | } |
13 | } | 19 | } |
14 | 20 | ||
15 | pub(super) fn item(p: &mut Parser, stop_on_r_curly: bool) { | 21 | pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) { |
16 | let m = p.start(); | 22 | let m = p.start(); |
17 | match maybe_item(p) { | 23 | match maybe_item(p) { |
18 | MaybeItem::Item(kind) => { | 24 | MaybeItem::Item(kind) => { |
19 | m.complete(p, kind); | 25 | m.complete(p, kind); |
20 | } | 26 | } |
21 | MaybeItem::None => { | 27 | MaybeItem::None => { |
22 | m.abandon(p); | 28 | if paths::is_path_start(p) { |
23 | if p.at(L_CURLY) { | 29 | match macro_call(p) { |
24 | error_block(p, "expected an item"); | 30 | MacroFlavor::Curly => (), |
25 | } else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { | 31 | MacroFlavor::NonCurly => { |
26 | p.err_and_bump("expected an item"); | 32 | p.expect(SEMI); |
33 | } | ||
34 | } | ||
35 | m.complete(p, MACRO_CALL); | ||
27 | } else { | 36 | } else { |
28 | p.error("expected an item"); | 37 | m.abandon(p); |
38 | if p.at(L_CURLY) { | ||
39 | error_block(p, "expected an item"); | ||
40 | } else if !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { | ||
41 | p.err_and_bump("expected an item"); | ||
42 | } else { | ||
43 | p.error("expected an item"); | ||
44 | } | ||
29 | } | 45 | } |
30 | } | 46 | } |
31 | MaybeItem::Modifiers => { | 47 | MaybeItem::Modifiers => { |
@@ -260,3 +276,49 @@ fn mod_item(p: &mut Parser) { | |||
260 | } | 276 | } |
261 | } | 277 | } |
262 | } | 278 | } |
279 | |||
280 | enum MacroFlavor { | ||
281 | Curly, | ||
282 | NonCurly, | ||
283 | } | ||
284 | |||
285 | fn macro_call(p: &mut Parser) -> MacroFlavor { | ||
286 | assert!(paths::is_path_start(p)); | ||
287 | paths::use_path(p); | ||
288 | p.expect(EXCL); | ||
289 | p.eat(IDENT); | ||
290 | let flavor = match p.current() { | ||
291 | L_CURLY => { | ||
292 | token_tree(p); | ||
293 | MacroFlavor::Curly | ||
294 | } | ||
295 | L_PAREN | L_BRACK => { | ||
296 | token_tree(p); | ||
297 | MacroFlavor::NonCurly | ||
298 | } | ||
299 | _ => { | ||
300 | p.error("expected `{`, `[`, `(`"); | ||
301 | MacroFlavor::NonCurly | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | flavor | ||
306 | } | ||
307 | |||
308 | fn token_tree(p: &mut Parser) { | ||
309 | let closing_paren_kind = match p.current() { | ||
310 | L_CURLY => R_CURLY, | ||
311 | L_PAREN => R_PAREN, | ||
312 | L_BRACK => R_BRACK, | ||
313 | _ => unreachable!(), | ||
314 | }; | ||
315 | p.bump(); | ||
316 | while !p.at(EOF) && !p.at(closing_paren_kind) { | ||
317 | match p.current() { | ||
318 | L_CURLY | L_PAREN | L_BRACK => token_tree(p), | ||
319 | R_CURLY | R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"), | ||
320 | _ => p.bump() | ||
321 | } | ||
322 | }; | ||
323 | p.expect(closing_paren_kind); | ||
324 | } | ||
diff --git a/src/grammar/items/traits.rs b/src/grammar/items/traits.rs index 0614e8ab6..7c0935371 100644 --- a/src/grammar/items/traits.rs +++ b/src/grammar/items/traits.rs | |||
@@ -45,7 +45,7 @@ pub(super) fn impl_item(p: &mut Parser) { | |||
45 | // fn bar(&self) {} | 45 | // fn bar(&self) {} |
46 | // } | 46 | // } |
47 | while !p.at(EOF) && !p.at(R_CURLY) { | 47 | while !p.at(EOF) && !p.at(R_CURLY) { |
48 | item(p, true); | 48 | item_or_macro(p, true); |
49 | } | 49 | } |
50 | p.expect(R_CURLY); | 50 | p.expect(R_CURLY); |
51 | } | 51 | } |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 1d3d3b9c1..8ac13fd63 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -103,6 +103,8 @@ pub enum SyntaxKind { | |||
103 | TRAIT_ITEM, | 103 | TRAIT_ITEM, |
104 | IMPL_ITEM, | 104 | IMPL_ITEM, |
105 | TYPE_ITEM, | 105 | TYPE_ITEM, |
106 | MACRO_CALL, | ||
107 | TOKEN_TREE, | ||
106 | PAREN_TYPE, | 108 | PAREN_TYPE, |
107 | TUPLE_TYPE, | 109 | TUPLE_TYPE, |
108 | NEVER_TYPE, | 110 | NEVER_TYPE, |
@@ -322,6 +324,8 @@ impl SyntaxKind { | |||
322 | TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, | 324 | TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, |
323 | IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, | 325 | IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, |
324 | TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" }, | 326 | TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" }, |
327 | MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" }, | ||
328 | TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" }, | ||
325 | PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" }, | 329 | PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" }, |
326 | TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, | 330 | TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, |
327 | NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, | 331 | NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, |