diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.ron | 10 | ||||
-rw-r--r-- | src/parser/grammar/expressions.rs | 27 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 1 | ||||
-rw-r--r-- | src/parser/grammar/paths.rs | 32 | ||||
-rw-r--r-- | src/parser/grammar/type_args.rs | 26 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 16 |
6 files changed, 95 insertions, 17 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index d5d2e6162..8232ba1dc 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -120,6 +120,7 @@ Grammar( | |||
120 | "PLACEHOLDER_PAT", | 120 | "PLACEHOLDER_PAT", |
121 | 121 | ||
122 | "TUPLE_EXPR", | 122 | "TUPLE_EXPR", |
123 | "PATH_EXPR", | ||
123 | 124 | ||
124 | "EXTERN_BLOCK", | 125 | "EXTERN_BLOCK", |
125 | "ENUM_VARIANT", | 126 | "ENUM_VARIANT", |
@@ -133,15 +134,18 @@ Grammar( | |||
133 | "LITERAL", | 134 | "LITERAL", |
134 | "ALIAS", | 135 | "ALIAS", |
135 | "VISIBILITY", | 136 | "VISIBILITY", |
136 | "TYPE_PARAM_LIST", | ||
137 | "WHERE_CLAUSE", | 137 | "WHERE_CLAUSE", |
138 | "LIFETIME_PARAM", | ||
139 | "TYPE_PARAM", | ||
140 | "ABI", | 138 | "ABI", |
141 | "NAME", | 139 | "NAME", |
142 | "NAME_REF", | 140 | "NAME_REF", |
143 | "VALUE_PARAMETER", | 141 | "VALUE_PARAMETER", |
144 | "BLOCK", | 142 | "BLOCK", |
145 | "LET_STMT", | 143 | "LET_STMT", |
144 | |||
145 | "TYPE_PARAM", | ||
146 | "LIFETIME_PARAM", | ||
147 | "TYPE_PARAM_LIST", | ||
148 | "TYPE_ARG_LIST", | ||
149 | |||
146 | ] | 150 | ] |
147 | ) | 151 | ) |
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs index 40f41535e..ece698248 100644 --- a/src/parser/grammar/expressions.rs +++ b/src/parser/grammar/expressions.rs | |||
@@ -2,7 +2,16 @@ use super::*; | |||
2 | 2 | ||
3 | // test expr_literals | 3 | // test expr_literals |
4 | // fn foo() { | 4 | // fn foo() { |
5 | // let _ = 92; | 5 | // let _ = true; |
6 | // let _ = false; | ||
7 | // let _ = 1; | ||
8 | // let _ = 2.0; | ||
9 | // let _ = b'a'; | ||
10 | // let _ = 'b'; | ||
11 | // let _ = "c"; | ||
12 | // let _ = r"d"; | ||
13 | // let _ = b"e"; | ||
14 | // let _ = br"f"; | ||
6 | // } | 15 | // } |
7 | pub(super) fn literal(p: &mut Parser) -> bool { | 16 | pub(super) fn literal(p: &mut Parser) -> bool { |
8 | match p.current() { | 17 | match p.current() { |
@@ -21,6 +30,9 @@ pub(super) fn expr(p: &mut Parser) { | |||
21 | if literal(p) { | 30 | if literal(p) { |
22 | return; | 31 | return; |
23 | } | 32 | } |
33 | if paths::is_path_start(p) { | ||
34 | return path_expr(p); | ||
35 | } | ||
24 | 36 | ||
25 | match p.current() { | 37 | match p.current() { |
26 | L_PAREN => tuple_expr(p), | 38 | L_PAREN => tuple_expr(p), |
@@ -35,3 +47,16 @@ fn tuple_expr(p: &mut Parser) { | |||
35 | p.expect(R_PAREN); | 47 | p.expect(R_PAREN); |
36 | m.complete(p, TUPLE_EXPR); | 48 | m.complete(p, TUPLE_EXPR); |
37 | } | 49 | } |
50 | |||
51 | // test path_expr | ||
52 | // fn foo() { | ||
53 | // let _ = a; | ||
54 | // let _ = a::b; | ||
55 | // let _ = ::a::<b>; | ||
56 | // } | ||
57 | fn path_expr(p: &mut Parser) { | ||
58 | assert!(paths::is_path_start(p)); | ||
59 | let m = p.start(); | ||
60 | paths::expr_path(p); | ||
61 | m.complete(p, PATH_EXPR); | ||
62 | } | ||
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index e24f1055e..e4823eadb 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs | |||
@@ -27,6 +27,7 @@ mod items; | |||
27 | mod paths; | 27 | mod paths; |
28 | mod patterns; | 28 | mod patterns; |
29 | mod type_params; | 29 | mod type_params; |
30 | mod type_args; | ||
30 | mod types; | 31 | mod types; |
31 | 32 | ||
32 | use { | 33 | use { |
diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs index d3eb20ea1..69ed84665 100644 --- a/src/parser/grammar/paths.rs +++ b/src/parser/grammar/paths.rs | |||
@@ -8,19 +8,26 @@ pub(super) fn is_path_start(p: &Parser) -> bool { | |||
8 | } | 8 | } |
9 | 9 | ||
10 | pub(super) fn use_path(p: &mut Parser) { | 10 | pub(super) fn use_path(p: &mut Parser) { |
11 | path(p) | 11 | path(p, Mode::Use) |
12 | } | 12 | } |
13 | 13 | ||
14 | pub(super) fn type_path(p: &mut Parser) { | 14 | pub(super) fn type_path(p: &mut Parser) { |
15 | path(p) | 15 | path(p, Mode::Type) |
16 | } | 16 | } |
17 | 17 | ||
18 | fn path(p: &mut Parser) { | 18 | pub(super) fn expr_path(p: &mut Parser) { |
19 | path(p, Mode::Expr) | ||
20 | } | ||
21 | |||
22 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
23 | enum Mode { Use, Type, Expr } | ||
24 | |||
25 | fn path(p: &mut Parser, mode: Mode) { | ||
19 | if !is_path_start(p) { | 26 | if !is_path_start(p) { |
20 | return; | 27 | return; |
21 | } | 28 | } |
22 | let path = p.start(); | 29 | let path = p.start(); |
23 | path_segment(p, true); | 30 | path_segment(p, mode, true); |
24 | let mut qual = path.complete(p, PATH); | 31 | let mut qual = path.complete(p, PATH); |
25 | loop { | 32 | loop { |
26 | let use_tree = match p.nth(1) { | 33 | let use_tree = match p.nth(1) { |
@@ -30,7 +37,7 @@ fn path(p: &mut Parser) { | |||
30 | if p.at(COLONCOLON) && !use_tree { | 37 | if p.at(COLONCOLON) && !use_tree { |
31 | let path = qual.precede(p); | 38 | let path = qual.precede(p); |
32 | p.bump(); | 39 | p.bump(); |
33 | path_segment(p, false); | 40 | path_segment(p, mode, false); |
34 | let path = path.complete(p, PATH); | 41 | let path = path.complete(p, PATH); |
35 | qual = path; | 42 | qual = path; |
36 | } else { | 43 | } else { |
@@ -39,13 +46,16 @@ fn path(p: &mut Parser) { | |||
39 | } | 46 | } |
40 | } | 47 | } |
41 | 48 | ||
42 | fn path_segment(p: &mut Parser, first: bool) { | 49 | fn path_segment(p: &mut Parser, mode: Mode, first: bool) { |
43 | let segment = p.start(); | 50 | let segment = p.start(); |
44 | if first { | 51 | if first { |
45 | p.eat(COLONCOLON); | 52 | p.eat(COLONCOLON); |
46 | } | 53 | } |
47 | match p.current() { | 54 | match p.current() { |
48 | IDENT => name_ref(p), | 55 | IDENT => { |
56 | name_ref(p); | ||
57 | path_generic_args(p, mode); | ||
58 | }, | ||
49 | SELF_KW | SUPER_KW => p.bump(), | 59 | SELF_KW | SUPER_KW => p.bump(), |
50 | _ => { | 60 | _ => { |
51 | p.error("expected identifier"); | 61 | p.error("expected identifier"); |
@@ -53,3 +63,11 @@ fn path_segment(p: &mut Parser, first: bool) { | |||
53 | }; | 63 | }; |
54 | segment.complete(p, PATH_SEGMENT); | 64 | segment.complete(p, PATH_SEGMENT); |
55 | } | 65 | } |
66 | |||
67 | fn path_generic_args(p: &mut Parser, mode: Mode) { | ||
68 | match mode { | ||
69 | Mode::Use => return, | ||
70 | Mode::Type => type_args::list(p, false), | ||
71 | Mode::Expr => type_args::list(p, true), | ||
72 | } | ||
73 | } | ||
diff --git a/src/parser/grammar/type_args.rs b/src/parser/grammar/type_args.rs new file mode 100644 index 000000000..20e75b4b0 --- /dev/null +++ b/src/parser/grammar/type_args.rs | |||
@@ -0,0 +1,26 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn list(p: &mut Parser, colon_colon_required: bool) { | ||
4 | let m; | ||
5 | match (colon_colon_required, p.nth(0), p.nth(1)) { | ||
6 | (_, COLONCOLON, L_ANGLE) => { | ||
7 | m = p.start(); | ||
8 | p.bump(); | ||
9 | p.bump(); | ||
10 | } | ||
11 | (false, L_ANGLE, _) => { | ||
12 | m = p.start(); | ||
13 | p.bump(); | ||
14 | } | ||
15 | _ => return | ||
16 | }; | ||
17 | |||
18 | while !p.at(EOF) && !p.at(R_ANGLE) { | ||
19 | types::type_(p); | ||
20 | if !p.at(R_ANGLE) && !p.expect(COMMA) { | ||
21 | break; | ||
22 | } | ||
23 | } | ||
24 | p.expect(R_ANGLE); | ||
25 | m.complete(p, TYPE_ARG_LIST); | ||
26 | } | ||
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 029972bb3..bc2a995f6 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -115,6 +115,7 @@ pub enum SyntaxKind { | |||
115 | BIND_PAT, | 115 | BIND_PAT, |
116 | PLACEHOLDER_PAT, | 116 | PLACEHOLDER_PAT, |
117 | TUPLE_EXPR, | 117 | TUPLE_EXPR, |
118 | PATH_EXPR, | ||
118 | EXTERN_BLOCK, | 119 | EXTERN_BLOCK, |
119 | ENUM_VARIANT, | 120 | ENUM_VARIANT, |
120 | NAMED_FIELD, | 121 | NAMED_FIELD, |
@@ -127,16 +128,17 @@ pub enum SyntaxKind { | |||
127 | LITERAL, | 128 | LITERAL, |
128 | ALIAS, | 129 | ALIAS, |
129 | VISIBILITY, | 130 | VISIBILITY, |
130 | TYPE_PARAM_LIST, | ||
131 | WHERE_CLAUSE, | 131 | WHERE_CLAUSE, |
132 | LIFETIME_PARAM, | ||
133 | TYPE_PARAM, | ||
134 | ABI, | 132 | ABI, |
135 | NAME, | 133 | NAME, |
136 | NAME_REF, | 134 | NAME_REF, |
137 | VALUE_PARAMETER, | 135 | VALUE_PARAMETER, |
138 | BLOCK, | 136 | BLOCK, |
139 | LET_STMT, | 137 | LET_STMT, |
138 | TYPE_PARAM, | ||
139 | LIFETIME_PARAM, | ||
140 | TYPE_PARAM_LIST, | ||
141 | TYPE_ARG_LIST, | ||
140 | // Technical SyntaxKinds: they appear temporally during parsing, | 142 | // Technical SyntaxKinds: they appear temporally during parsing, |
141 | // but never end up in the final tree | 143 | // but never end up in the final tree |
142 | #[doc(hidden)] | 144 | #[doc(hidden)] |
@@ -259,6 +261,7 @@ impl SyntaxKind { | |||
259 | BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, | 261 | BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, |
260 | PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, | 262 | PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, |
261 | TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, | 263 | TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, |
264 | PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, | ||
262 | EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, | 265 | EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, |
263 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, | 266 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, |
264 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, | 267 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, |
@@ -271,16 +274,17 @@ impl SyntaxKind { | |||
271 | LITERAL => &SyntaxInfo { name: "LITERAL" }, | 274 | LITERAL => &SyntaxInfo { name: "LITERAL" }, |
272 | ALIAS => &SyntaxInfo { name: "ALIAS" }, | 275 | ALIAS => &SyntaxInfo { name: "ALIAS" }, |
273 | VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, | 276 | VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, |
274 | TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, | ||
275 | WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, | 277 | WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, |
276 | LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, | ||
277 | TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, | ||
278 | ABI => &SyntaxInfo { name: "ABI" }, | 278 | ABI => &SyntaxInfo { name: "ABI" }, |
279 | NAME => &SyntaxInfo { name: "NAME" }, | 279 | NAME => &SyntaxInfo { name: "NAME" }, |
280 | NAME_REF => &SyntaxInfo { name: "NAME_REF" }, | 280 | NAME_REF => &SyntaxInfo { name: "NAME_REF" }, |
281 | VALUE_PARAMETER => &SyntaxInfo { name: "VALUE_PARAMETER" }, | 281 | VALUE_PARAMETER => &SyntaxInfo { name: "VALUE_PARAMETER" }, |
282 | BLOCK => &SyntaxInfo { name: "BLOCK" }, | 282 | BLOCK => &SyntaxInfo { name: "BLOCK" }, |
283 | LET_STMT => &SyntaxInfo { name: "LET_STMT" }, | 283 | LET_STMT => &SyntaxInfo { name: "LET_STMT" }, |
284 | TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, | ||
285 | LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, | ||
286 | TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, | ||
287 | TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" }, | ||
284 | 288 | ||
285 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, | 289 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, |
286 | EOF => &SyntaxInfo { name: "EOF" }, | 290 | EOF => &SyntaxInfo { name: "EOF" }, |