From d4366940976a3d150a8b5bf92dc24f0162d4d62c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Jul 2018 17:02:51 +0300 Subject: Path expressions --- src/parser/grammar/expressions.rs | 27 ++++++++++++++++++++++++++- src/parser/grammar/mod.rs | 1 + src/parser/grammar/paths.rs | 32 +++++++++++++++++++++++++------- src/parser/grammar/type_args.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 src/parser/grammar/type_args.rs (limited to 'src/parser') 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::*; // test expr_literals // fn foo() { -// let _ = 92; +// let _ = true; +// let _ = false; +// let _ = 1; +// let _ = 2.0; +// let _ = b'a'; +// let _ = 'b'; +// let _ = "c"; +// let _ = r"d"; +// let _ = b"e"; +// let _ = br"f"; // } pub(super) fn literal(p: &mut Parser) -> bool { match p.current() { @@ -21,6 +30,9 @@ pub(super) fn expr(p: &mut Parser) { if literal(p) { return; } + if paths::is_path_start(p) { + return path_expr(p); + } match p.current() { L_PAREN => tuple_expr(p), @@ -35,3 +47,16 @@ fn tuple_expr(p: &mut Parser) { p.expect(R_PAREN); m.complete(p, TUPLE_EXPR); } + +// test path_expr +// fn foo() { +// let _ = a; +// let _ = a::b; +// let _ = ::a::; +// } +fn path_expr(p: &mut Parser) { + assert!(paths::is_path_start(p)); + let m = p.start(); + paths::expr_path(p); + m.complete(p, PATH_EXPR); +} 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; mod paths; mod patterns; mod type_params; +mod type_args; mod types; 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 { } pub(super) fn use_path(p: &mut Parser) { - path(p) + path(p, Mode::Use) } pub(super) fn type_path(p: &mut Parser) { - path(p) + path(p, Mode::Type) } -fn path(p: &mut Parser) { +pub(super) fn expr_path(p: &mut Parser) { + path(p, Mode::Expr) +} + +#[derive(Clone, Copy, Eq, PartialEq)] +enum Mode { Use, Type, Expr } + +fn path(p: &mut Parser, mode: Mode) { if !is_path_start(p) { return; } let path = p.start(); - path_segment(p, true); + path_segment(p, mode, true); let mut qual = path.complete(p, PATH); loop { let use_tree = match p.nth(1) { @@ -30,7 +37,7 @@ fn path(p: &mut Parser) { if p.at(COLONCOLON) && !use_tree { let path = qual.precede(p); p.bump(); - path_segment(p, false); + path_segment(p, mode, false); let path = path.complete(p, PATH); qual = path; } else { @@ -39,13 +46,16 @@ fn path(p: &mut Parser) { } } -fn path_segment(p: &mut Parser, first: bool) { +fn path_segment(p: &mut Parser, mode: Mode, first: bool) { let segment = p.start(); if first { p.eat(COLONCOLON); } match p.current() { - IDENT => name_ref(p), + IDENT => { + name_ref(p); + path_generic_args(p, mode); + }, SELF_KW | SUPER_KW => p.bump(), _ => { p.error("expected identifier"); @@ -53,3 +63,11 @@ fn path_segment(p: &mut Parser, first: bool) { }; segment.complete(p, PATH_SEGMENT); } + +fn path_generic_args(p: &mut Parser, mode: Mode) { + match mode { + Mode::Use => return, + Mode::Type => type_args::list(p, false), + Mode::Expr => type_args::list(p, true), + } +} 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 @@ +use super::*; + +pub(super) fn list(p: &mut Parser, colon_colon_required: bool) { + let m; + match (colon_colon_required, p.nth(0), p.nth(1)) { + (_, COLONCOLON, L_ANGLE) => { + m = p.start(); + p.bump(); + p.bump(); + } + (false, L_ANGLE, _) => { + m = p.start(); + p.bump(); + } + _ => return + }; + + while !p.at(EOF) && !p.at(R_ANGLE) { + types::type_(p); + if !p.at(R_ANGLE) && !p.expect(COMMA) { + break; + } + } + p.expect(R_ANGLE); + m.complete(p, TYPE_ARG_LIST); +} -- cgit v1.2.3