From f07c7248f746a80957711a27eb1bc1d98de9e770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Wed, 19 Jun 2024 10:58:43 +0200 Subject: [PATCH] Use ISO 646 alternative operators for bit ops This change allows simplifying the use of filter expressions, because you won't have to care about spaces around the `|` pipe operator. --- rinja_parser/src/expr.rs | 35 ++++++---- rinja_parser/src/tests.rs | 84 ------------------------ testing/templates/allow-whitespaces.html | 2 +- testing/templates/operators.html | 6 +- testing/templates/precedence.html | 2 +- 5 files changed, 27 insertions(+), 102 deletions(-) diff --git a/rinja_parser/src/expr.rs b/rinja_parser/src/expr.rs index 563b300e..ac3f683e 100644 --- a/rinja_parser/src/expr.rs +++ b/rinja_parser/src/expr.rs @@ -4,14 +4,14 @@ use std::str; use nom::branch::alt; use nom::bytes::complete::{tag, take_till}; use nom::character::complete::char; -use nom::combinator::{cut, map, not, opt, peek, recognize}; +use nom::combinator::{cut, map, not, opt, peek, recognize, value}; use nom::error::ErrorKind; use nom::error_position; use nom::multi::{fold_many0, many0, separated_list0}; use nom::sequence::{pair, preceded, terminated, tuple}; use super::{ - char_lit, filter, identifier, not_ws, num_lit, path_or_identifier, str_lit, ws, Level, + char_lit, filter, identifier, keyword, not_ws, num_lit, path_or_identifier, str_lit, ws, Level, PathOrIdentifier, }; use crate::{ErrorContext, ParseResult, WithSpan}; @@ -23,7 +23,7 @@ macro_rules! expr_prec_layer { let start = i; let (i, left) = Self::$inner(i, level)?; let (i, right) = many0(pair( - ws(tag($op)), + ws($op), |i| Self::$inner(i, level), ))(i)?; Ok(( @@ -40,7 +40,7 @@ macro_rules! expr_prec_layer { let start = i; let (i, left) = Self::$inner(i, level)?; let (i, right) = many0(pair( - ws(alt(($( tag($op) ),+,))), + ws(alt(($( $op, )+))), |i| Self::$inner(i, level), ))(i)?; Ok(( @@ -189,15 +189,24 @@ impl<'a> Expr<'a> { ))(i) } - expr_prec_layer!(or, and, "||"); - expr_prec_layer!(and, compare, "&&"); - expr_prec_layer!(compare, bor, "==", "!=", ">=", ">", "<=", "<"); - expr_prec_layer!(bor, bxor, "|"); - expr_prec_layer!(bxor, band, "^"); - expr_prec_layer!(band, shifts, "&"); - expr_prec_layer!(shifts, addsub, ">>", "<<"); - expr_prec_layer!(addsub, muldivmod, "+", "-"); - expr_prec_layer!(muldivmod, filtered, "*", "/", "%"); + expr_prec_layer!(or, and, tag("||")); + expr_prec_layer!(and, compare, tag("&&")); + expr_prec_layer!( + compare, + bor, + tag("=="), + tag("!="), + tag(">="), + tag(">"), + tag("<="), + tag("<") + ); + expr_prec_layer!(bor, bxor, value("|", keyword("bitor"))); + expr_prec_layer!(bxor, band, alt((tag("^"), value("^", keyword("xor"))))); + expr_prec_layer!(band, shifts, alt((tag("&"), value("&", keyword("bitand"))))); + expr_prec_layer!(shifts, addsub, tag(">>"), tag("<<")); + expr_prec_layer!(addsub, muldivmod, tag("+"), tag("-")); + expr_prec_layer!(muldivmod, filtered, tag("*"), tag("/"), tag("%")); fn filtered(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> { let (_, level) = level.nest(i)?; diff --git a/rinja_parser/src/tests.rs b/rinja_parser/src/tests.rs index 28d4fa22..bb72cab2 100644 --- a/rinja_parser/src/tests.rs +++ b/rinja_parser/src/tests.rs @@ -684,20 +684,6 @@ fn test_odd_calls() { })), )] ); - assert_eq!( - Ast::from_str("{{ a(b) |c }}", None, &syntax).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Call( - Box::new(WithSpan::no_span(Expr::Var("a"))), - vec![WithSpan::no_span(Expr::Var("b"))] - ))), - Box::new(WithSpan::no_span(Expr::Var("c"))) - ),) - )] - ); } #[test] @@ -847,19 +833,6 @@ fn test_parse_tuple() { })), )], ); - assert_eq!( - Ast::from_str("{{ () | abs }}", None, &syntax) - .unwrap() - .nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Tuple(vec![]))), - Box::new(WithSpan::no_span(Expr::Var("abs"))) - )), - )], - ); assert_eq!( Ast::from_str("{{ (1)|abs }}", None, &syntax).unwrap().nodes, vec![Node::Expr( @@ -872,21 +845,6 @@ fn test_parse_tuple() { })), )], ); - assert_eq!( - Ast::from_str("{{ (1) | abs }}", None, &syntax) - .unwrap() - .nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span( - Expr::NumLit("1") - ))))), - Box::new(WithSpan::no_span(Expr::Var("abs"))) - )), - )], - ); assert_eq!( Ast::from_str("{{ (1,)|abs }}", None, &syntax) .unwrap() @@ -901,21 +859,6 @@ fn test_parse_tuple() { })), )], ); - assert_eq!( - Ast::from_str("{{ (1,) | abs }}", None, &syntax) - .unwrap() - .nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span( - Expr::NumLit("1") - )]))), - Box::new(WithSpan::no_span(Expr::Var("abs"))) - )), - )], - ); assert_eq!( Ast::from_str("{{ (1, 2)|abs }}", None, &syntax) .unwrap() @@ -931,22 +874,6 @@ fn test_parse_tuple() { })), )], ); - assert_eq!( - Ast::from_str("{{ (1, 2) | abs }}", None, &syntax) - .unwrap() - .nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Tuple(vec![ - WithSpan::no_span(Expr::NumLit("1")), - WithSpan::no_span(Expr::NumLit("2")) - ]))), - Box::new(WithSpan::no_span(Expr::Var("abs"))) - )), - )], - ); } #[test] @@ -1050,17 +977,6 @@ fn test_parse_array() { })) )], ); - assert_eq!( - Ast::from_str("{{ [] |foo }}", None, &syntax).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::BinOp( - "|", - Box::new(WithSpan::no_span(Expr::Array(vec![]))), - Box::new(WithSpan::no_span(Expr::Var("foo"))) - )), - )], - ); } #[test] diff --git a/testing/templates/allow-whitespaces.html b/testing/templates/allow-whitespaces.html index 4c64ca2e..99716e65 100644 --- a/testing/templates/allow-whitespaces.html +++ b/testing/templates/allow-whitespaces.html @@ -35,7 +35,7 @@ {{1+2}}{{ 1+2 }}{{ 1 +2 }}{{ 1+ 2 }} {{ 1 + 2 }} {{1*2}}{{ 1*2 }}{{ 1 *2 }}{{ 1* 2 }} {{ 1 * 2 }} {{1&2}}{{ 1&2 }}{{ 1 &2 }}{{ 1& 2 }} {{ 1 & 2 }} -{{1|2}}{{ 1|2 }}{{ 1 |2 }}{{ 1| 2 }} {{ 1 | 2 }} +{{1 bitor 2}}{{ 1 bitor 2 }}{{ 1 bitor 2}}{{1 bitor 2 }} {{1 bitor 2}} {{true}}{{false}} {{!true}}{{ !true }}{{ ! true }} diff --git a/testing/templates/operators.html b/testing/templates/operators.html index 7d8ed638..62b7ee70 100644 --- a/testing/templates/operators.html +++ b/testing/templates/operators.html @@ -16,13 +16,13 @@ {% if c >> b == a -%} lsh {%- endif -%} -{% if a & b == b -%} +{% if a bitand b == b -%} band {%- endif -%} -{% if b ^ c == a + c -%} +{% if b xor c == a + c -%} bxor {%- endif -%} -{% if (b | c) == a + c -%} +{% if b bitor c == a + c -%} bor {%- endif -%} {% if a == b && a + b == c -%} diff --git a/testing/templates/precedence.html b/testing/templates/precedence.html index e5d12ddb..6e1d2d9d 100644 --- a/testing/templates/precedence.html +++ b/testing/templates/precedence.html @@ -4,4 +4,4 @@ {{ 1 * 2 + 4 -}} {{ 11 - 15 / 3 -}} {{ 4 + 5 % 3 -}} -{{ 4 | 2 + 5 & 2 -}} +{{ 4 bitor 2 + 5 & 2 -}}