From dac879c6fd13f6d4ef6223456c6c1dfc49aaeb32 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Thu, 15 Aug 2024 14:43:59 +0200 Subject: [PATCH] grammar: use inner expressions as appropriate --- crates/rune/src/compile/error.rs | 2 +- crates/rune/src/fmt/format.rs | 65 +++++++++++++++--------------- crates/rune/src/fmt/tests/mod.rs | 11 ++++- crates/rune/src/grammar/grammar.rs | 40 ++++++++---------- 4 files changed, 60 insertions(+), 58 deletions(-) diff --git a/crates/rune/src/compile/error.rs b/crates/rune/src/compile/error.rs index 234bf6bb3..044bd012c 100644 --- a/crates/rune/src/compile/error.rs +++ b/crates/rune/src/compile/error.rs @@ -1127,7 +1127,7 @@ impl fmt::Display for ErrorKind { } #[cfg(feature = "fmt")] ErrorKind::UnexpectedEndOfSyntax { inside } => { - write!(f, "Unexpected end of syntax while parsing {inside:?}")?; + write!(f, "Unexpected end of syntax while parsing {inside}")?; } #[cfg(feature = "fmt")] ErrorKind::ExpectedSyntaxEnd { inside, actual } => { diff --git a/crates/rune/src/fmt/format.rs b/crates/rune/src/fmt/format.rs index ff1e555aa..bf3e46a8f 100644 --- a/crates/rune/src/fmt/format.rs +++ b/crates/rune/src/fmt/format.rs @@ -232,7 +232,7 @@ fn local<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { fmt.ws()?; p.one(K![=])?.fmt(fmt)?; fmt.ws()?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.expect(Expr)?.parse(|p| expr(fmt, p))?; Ok(()) } @@ -553,25 +553,26 @@ fn expr_discard<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { } fn expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result { - match p.kind() { - Expr => { - let mut attrs = Attrs::default(); + let mut attrs = Attrs::default(); - while let Some(attr) = p.try_pump(Attribute)? { - attrs.skip |= is_runefmt_skip(fmt, attr.clone()); - attr.fmt(fmt)?; - fmt.ws()?; - } + while let Some(attr) = p.try_pump(Attribute)? { + attrs.skip |= is_runefmt_skip(fmt, attr.clone()); + attr.fmt(fmt)?; + fmt.ws()?; + } - if attrs.skip { - p.write_remaining(fmt)?; - return Ok(Expr); - } else { - modifiers(fmt, p)?; - expr_labels(fmt, p)?; - return p.pump()?.parse(|p| expr(fmt, p)); - } - } + if attrs.skip { + p.write_remaining(fmt)?; + Ok(Expr) + } else { + modifiers(fmt, p)?; + expr_labels(fmt, p)?; + p.pump()?.parse(|p| inner_expr(fmt, p)) + } +} + +fn inner_expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result { + match p.kind() { ExprMacroCall => { p.expect(Path)?.parse(|p| path(fmt, p))?; p.expect(K![!])?.fmt(fmt)?; @@ -663,17 +664,17 @@ fn expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result { p.pump()?.fmt(fmt)?; } ExprRangeFrom => { - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; p.pump()?.fmt(fmt)?; } ExprRangeTo | ExprRangeToInclusive => { p.pump()?.fmt(fmt)?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; } ExprRange | ExprRangeInclusive => { - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; p.pump()?.fmt(fmt)?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; } ExprClosure => { expr_closure(fmt, p)?; @@ -685,11 +686,11 @@ fn expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result { if fmt.options.error_recovery { p.fmt_remaining_trimmed(fmt)?; } else { - return Err(p.unsupported("expression")); + return Err(p.unsupported("inner expression")); } } _ => { - return Err(p.unsupported("expression")); + return Err(p.unsupported("inner expression")); } } @@ -782,11 +783,11 @@ fn compact_expr_macro_call<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> R } fn expr_assign<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; fmt.ws()?; p.expect(K![=])?.fmt(fmt)?; fmt.ws()?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.expect(Expr)?.parse(|p| expr(fmt, p))?; Ok(()) } @@ -860,13 +861,13 @@ fn exprs_compact<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> } fn expr_binary<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; while let Some(op) = p.try_pump(ExprOperator)? { fmt.ws()?; op.fmt(fmt)?; fmt.ws()?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; } Ok(()) @@ -874,7 +875,7 @@ fn expr_binary<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { fn expr_unary<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { p.pump()?.fmt(fmt)?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.pump()?.parse(|p| inner_expr(fmt, p))?; Ok(()) } @@ -1162,7 +1163,7 @@ fn expr_chain<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { // that need indentation in the chain, we can keep it all on one line. let head = p.pump()?.parse(|p| { let first = p.span(); - expr(fmt, p)?; + inner_expr(fmt, p)?; Ok(first) })?; @@ -1264,7 +1265,7 @@ fn condition_or_expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result< if let Some(c) = p.try_pump(Condition)? { c.parse(|p| condition(fmt, p))?; } else { - p.pump()?.parse(|p| expr(fmt, p))?; + p.expect(Expr)?.parse(|p| expr(fmt, p))?; } Ok(()) @@ -1277,7 +1278,7 @@ fn condition<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> { fmt.ws()?; p.expect(K![=])?.fmt(fmt)?; fmt.ws()?; - p.pump()?.parse(|p| expr(fmt, p))?; + p.expect(Expr)?.parse(|p| expr(fmt, p))?; Ok(()) } diff --git a/crates/rune/src/fmt/tests/mod.rs b/crates/rune/src/fmt/tests/mod.rs index 64b7a9bca..04f07103d 100644 --- a/crates/rune/src/fmt/tests/mod.rs +++ b/crates/rune/src/fmt/tests/mod.rs @@ -309,8 +309,8 @@ fn patterns() { "let ::a::b::c = ::a::b::c;" ); assert_format!( - "let ::a ::b<::b, ::c ::d>::c = 42;", - "let ::a::b<::b, ::c::d>::c = 42;" + "let ::a ::b::<::b, ::c ::d>::c = 42;", + "let ::a::b::<::b, ::c::d>::c = 42;" ); assert_format!( "for _ in 121/10..=1*2-100{}", @@ -585,6 +585,13 @@ fn expressions() { }; "# ); + + assert_format!( + r#" + if values - current_joltage < 4 { + } + "# + ); } #[test] diff --git a/crates/rune/src/grammar/grammar.rs b/crates/rune/src/grammar/grammar.rs index 84911afe6..ff2dd0efd 100644 --- a/crates/rune/src/grammar/grammar.rs +++ b/crates/rune/src/grammar/grammar.rs @@ -262,7 +262,7 @@ fn modifiers(p: &mut Parser<'_>) -> Result { } K![in] => { p.bump()?; - path(p, Binary::No)?; + path(p)?; ModifierIn } _ => Error, @@ -469,7 +469,7 @@ fn item_impl(p: &mut Parser<'_>) -> Result<()> { p.bump()?; if matches!(p.peek()?, path_component!()) { - path(p, Binary::No)?; + path(p)?; } block(p)?; @@ -530,7 +530,7 @@ fn pat(p: &mut Parser<'_>) -> Result<()> { } path_component!() => { let c = p.checkpoint()?; - path(p, Binary::No)?; + path(p)?; match p.peek()? { K!['{'] => { @@ -657,13 +657,13 @@ fn outer_expr_with( cx: &dyn ExprCx, ) -> Result { let c = p.checkpoint()?; - let mut kind = expr_primary(p, brace, range, binary, cx)?; + let mut kind = expr_primary(p, brace, range, cx)?; if is_range(kind) { return Ok(kind); } - kind = expr_chain(p, &c, binary, kind)?; + kind = expr_chain(p, &c, kind)?; if p.peek()? == K![=] { p.bump()?; @@ -700,13 +700,7 @@ fn labels(p: &mut Parser<'_>) -> Result<()> { } #[tracing::instrument(skip_all)] -fn expr_primary( - p: &mut Parser<'_>, - brace: Brace, - range: Range, - binary: Binary, - cx: &dyn ExprCx, -) -> Result { +fn expr_primary(p: &mut Parser<'_>, brace: Brace, range: Range, cx: &dyn ExprCx) -> Result { let c = p.checkpoint()?; let kind = match p.peek()? { @@ -715,7 +709,7 @@ fn expr_primary( ExprLit } path_component!() => { - path(p, binary)?; + path(p)?; match p.peek()? { K!['{'] if matches!(brace, Brace::Yes) => { @@ -767,7 +761,7 @@ fn expr_primary( } K![!] | K![-] | K![&] | K![*] => { p.bump()?; - expr_with(p, brace, range, Binary::No, cx)?; + outer_expr_with(p, brace, range, Binary::No, cx)?; ExprUnary } K![if] => { @@ -878,7 +872,7 @@ fn kind_is_callable(kind: Kind) -> bool { } #[tracing::instrument(skip_all)] -fn expr_chain(p: &mut Parser<'_>, c: &Checkpoint, binary: Binary, mut kind: Kind) -> Result { +fn expr_chain(p: &mut Parser<'_>, c: &Checkpoint, mut kind: Kind) -> Result { let mut before = p.checkpoint()?; let mut has_chain = false; @@ -912,7 +906,7 @@ fn expr_chain(p: &mut Parser<'_>, c: &Checkpoint, binary: Binary, mut kind: Kind } // .field path_component!() => { - path(p, binary)?; + path(p)?; ExprField } // . @@ -1151,14 +1145,14 @@ fn condition(p: &mut Parser<'_>) -> Result<()> { } #[tracing::instrument(skip_all)] -fn path(p: &mut Parser<'_>, binary: Binary) -> Result<()> { +fn path(p: &mut Parser<'_>) -> Result<()> { let c = p.checkpoint()?; while matches!(p.peek()?, path_component!()) { - // Parse a generic path if we are not in a binary expression, or if we - // just parsed the prefix `::` of the turbofish syntax. - let has_generics = matches!(binary, Binary::No) || matches!(p.peek()?, K![::]); - + // Parse a generic path if we are in a context supporting binary + // expressions, or if we just parsed the prefix `::` of the turbofish + // syntax. + let has_generics = matches!(p.peek()?, K![::]); p.bump()?; // We can't parse generics in binary expressions, since they would be @@ -1169,7 +1163,7 @@ fn path(p: &mut Parser<'_>, binary: Binary) -> Result<()> { while matches!(p.peek()?, path_component!()) { // Inner paths are unambiguous. - path(p, Binary::No)?; + path(p)?; p.bump_while(K![,])?; } @@ -1208,8 +1202,8 @@ fn expr_binary( p.close_at(&op_c, ExprOperator)?; let c = p.checkpoint()?; + outer_expr_with(p, brace, Range::No, Binary::No, cx)?; - expr_with(p, brace, Range::No, Binary::No, cx)?; has_any = true; lookahead = ast::BinOp::from_peeker(p)?;