aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron10
-rw-r--r--src/parser/grammar/expressions.rs27
-rw-r--r--src/parser/grammar/mod.rs1
-rw-r--r--src/parser/grammar/paths.rs32
-rw-r--r--src/parser/grammar/type_args.rs26
-rw-r--r--src/syntax_kinds/generated.rs16
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// }
7pub(super) fn literal(p: &mut Parser) -> bool { 16pub(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// }
57fn 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;
27mod paths; 27mod paths;
28mod patterns; 28mod patterns;
29mod type_params; 29mod type_params;
30mod type_args;
30mod types; 31mod types;
31 32
32use { 33use {
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
10pub(super) fn use_path(p: &mut Parser) { 10pub(super) fn use_path(p: &mut Parser) {
11 path(p) 11 path(p, Mode::Use)
12} 12}
13 13
14pub(super) fn type_path(p: &mut Parser) { 14pub(super) fn type_path(p: &mut Parser) {
15 path(p) 15 path(p, Mode::Type)
16} 16}
17 17
18fn path(p: &mut Parser) { 18pub(super) fn expr_path(p: &mut Parser) {
19 path(p, Mode::Expr)
20}
21
22#[derive(Clone, Copy, Eq, PartialEq)]
23enum Mode { Use, Type, Expr }
24
25fn 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
42fn path_segment(p: &mut Parser, first: bool) { 49fn 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
67fn 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 @@
1use super::*;
2
3pub(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" },