aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron2
-rw-r--r--src/parser/grammar/expressions.rs43
-rw-r--r--src/syntax_kinds/generated.rs4
3 files changed, 45 insertions, 4 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index a8c922040..fca29f1ef 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -126,6 +126,8 @@ Grammar(
126 "TUPLE_EXPR", 126 "TUPLE_EXPR",
127 "PATH_EXPR", 127 "PATH_EXPR",
128 "CALL_EXPR", 128 "CALL_EXPR",
129 "METHOD_CALL_EXPR",
130 "FIELD_EXPR",
129 "REF_EXPR", 131 "REF_EXPR",
130 132
131 "EXTERN_BLOCK", 133 "EXTERN_BLOCK",
diff --git a/src/parser/grammar/expressions.rs b/src/parser/grammar/expressions.rs
index 11bb3436b..3956df568 100644
--- a/src/parser/grammar/expressions.rs
+++ b/src/parser/grammar/expressions.rs
@@ -26,11 +26,20 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
26} 26}
27 27
28pub(super) fn expr(p: &mut Parser) { 28pub(super) fn expr(p: &mut Parser) {
29 let mut lhs = prefix_expr(p); 29 let mut lhs = match prefix_expr(p) {
30 Some(lhs) => lhs,
31 None => return,
32 };
30 33
31 while let Some(m) = lhs { 34 loop {
32 match p.current() { 35 lhs = match p.current() {
33 L_PAREN => lhs = Some(call_expr(p, m)), 36 L_PAREN => call_expr(p, lhs),
37 DOT if p.nth(1) == IDENT =>
38 if p.nth(2) == L_PAREN {
39 method_call_expr(p, lhs)
40 } else {
41 field_expr(p, lhs)
42 }
34 _ => break, 43 _ => break,
35 } 44 }
36 } 45 }
@@ -95,6 +104,32 @@ fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
95 m.complete(p, CALL_EXPR) 104 m.complete(p, CALL_EXPR)
96} 105}
97 106
107// test method_call_expr
108// fn foo() {
109// x.foo();
110// y.bar(1, 2,);
111// }
112fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
113 assert!(p.at(DOT) && p.nth(1) == IDENT && p.nth(2) == L_PAREN);
114 let m = lhs.precede(p);
115 p.bump();
116 p.bump();
117 arg_list(p);
118 m.complete(p, METHOD_CALL_EXPR)
119}
120
121// test field_expr
122// fn foo() {
123// x.foo.bar;
124// }
125fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
126 assert!(p.at(DOT) && p.nth(1) == IDENT);
127 let m = lhs.precede(p);
128 p.bump();
129 p.bump();
130 m.complete(p, FIELD_EXPR)
131}
132
98fn arg_list(p: &mut Parser) { 133fn arg_list(p: &mut Parser) {
99 assert!(p.at(L_PAREN)); 134 assert!(p.at(L_PAREN));
100 let m = p.start(); 135 let m = p.start();
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index c49ad9a59..699f5282e 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -117,6 +117,8 @@ pub enum SyntaxKind {
117 TUPLE_EXPR, 117 TUPLE_EXPR,
118 PATH_EXPR, 118 PATH_EXPR,
119 CALL_EXPR, 119 CALL_EXPR,
120 METHOD_CALL_EXPR,
121 FIELD_EXPR,
120 REF_EXPR, 122 REF_EXPR,
121 EXTERN_BLOCK, 123 EXTERN_BLOCK,
122 ENUM_VARIANT, 124 ENUM_VARIANT,
@@ -268,6 +270,8 @@ impl SyntaxKind {
268 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, 270 TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
269 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, 271 PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
270 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, 272 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },
273 METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" },
274 FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" },
271 REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, 275 REF_EXPR => &SyntaxInfo { name: "REF_EXPR" },
272 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 276 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
273 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 277 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },