From 9f87c9a3f927d3b7a3cbb92818c45c979ece693b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 31 Jul 2018 17:35:54 +0300 Subject: Field expr --- src/grammar.ron | 2 ++ src/parser/grammar/expressions.rs | 43 +++++++++++++++++++++++++++++++++++---- src/syntax_kinds/generated.rs | 4 ++++ 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'src') 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( "TUPLE_EXPR", "PATH_EXPR", "CALL_EXPR", + "METHOD_CALL_EXPR", + "FIELD_EXPR", "REF_EXPR", "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 { } pub(super) fn expr(p: &mut Parser) { - let mut lhs = prefix_expr(p); + let mut lhs = match prefix_expr(p) { + Some(lhs) => lhs, + None => return, + }; - while let Some(m) = lhs { - match p.current() { - L_PAREN => lhs = Some(call_expr(p, m)), + loop { + lhs = match p.current() { + L_PAREN => call_expr(p, lhs), + DOT if p.nth(1) == IDENT => + if p.nth(2) == L_PAREN { + method_call_expr(p, lhs) + } else { + field_expr(p, lhs) + } _ => break, } } @@ -95,6 +104,32 @@ fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { m.complete(p, CALL_EXPR) } +// test method_call_expr +// fn foo() { +// x.foo(); +// y.bar(1, 2,); +// } +fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(DOT) && p.nth(1) == IDENT && p.nth(2) == L_PAREN); + let m = lhs.precede(p); + p.bump(); + p.bump(); + arg_list(p); + m.complete(p, METHOD_CALL_EXPR) +} + +// test field_expr +// fn foo() { +// x.foo.bar; +// } +fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { + assert!(p.at(DOT) && p.nth(1) == IDENT); + let m = lhs.precede(p); + p.bump(); + p.bump(); + m.complete(p, FIELD_EXPR) +} + fn arg_list(p: &mut Parser) { assert!(p.at(L_PAREN)); 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 { TUPLE_EXPR, PATH_EXPR, CALL_EXPR, + METHOD_CALL_EXPR, + FIELD_EXPR, REF_EXPR, EXTERN_BLOCK, ENUM_VARIANT, @@ -268,6 +270,8 @@ impl SyntaxKind { TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, + METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, + FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" }, REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, -- cgit v1.2.3