Skip to content

Commit 6d6555e

Browse files
committed
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.
1 parent 40a307a commit 6d6555e

File tree

5 files changed

+41
-118
lines changed

5 files changed

+41
-118
lines changed

rinja_parser/src/expr.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ use std::str;
44
use nom::branch::alt;
55
use nom::bytes::complete::{tag, take_till};
66
use nom::character::complete::char;
7-
use nom::combinator::{cut, map, not, opt, peek, recognize};
7+
use nom::combinator::{cut, map, not, opt, peek, recognize, value};
88
use nom::error::ErrorKind;
99
use nom::error_position;
1010
use nom::multi::{fold_many0, many0, separated_list0};
1111
use nom::sequence::{pair, preceded, terminated, tuple};
1212

1313
use super::{
14-
char_lit, filter, identifier, not_ws, num_lit, path_or_identifier, str_lit, ws, Level,
14+
char_lit, filter, identifier, keyword, not_ws, num_lit, path_or_identifier, str_lit, ws, Level,
1515
PathOrIdentifier,
1616
};
1717
use crate::{ErrorContext, ParseResult, WithSpan};
@@ -22,10 +22,7 @@ macro_rules! expr_prec_layer {
2222
let (_, level) = level.nest(i)?;
2323
let start = i;
2424
let (i, left) = Self::$inner(i, level)?;
25-
let (i, right) = many0(pair(
26-
ws(tag($op)),
27-
|i| Self::$inner(i, level),
28-
))(i)?;
25+
let (i, right) = many0(pair(ws($op), |i| Self::$inner(i, level)))(i)?;
2926
Ok((
3027
i,
3128
right.into_iter().fold(left, |left, (op, right)| {
@@ -34,22 +31,21 @@ macro_rules! expr_prec_layer {
3431
))
3532
}
3633
};
37-
( $name:ident, $inner:ident, $( $op:expr ),+ ) => {
38-
fn $name(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> {
39-
let (_, level) = level.nest(i)?;
40-
let start = i;
41-
let (i, left) = Self::$inner(i, level)?;
42-
let (i, right) = many0(pair(
43-
ws(alt(($( tag($op) ),+,))),
44-
|i| Self::$inner(i, level),
45-
))(i)?;
46-
Ok((
34+
}
35+
36+
fn alternative_binop<'a>(
37+
rust: &'static str,
38+
rinja: &'static str,
39+
) -> impl Fn(&'a str) -> ParseResult<'a, &'static str> {
40+
move |i: &'a str| -> ParseResult<'a, &'static str> {
41+
let (i, fail) = opt(tag(rust))(i)?;
42+
if fail.is_some() {
43+
return Err(nom::Err::Failure(ErrorContext::new(
44+
format!("the binary operator '{rust}' is called '{rinja}' in rinja"),
4745
i,
48-
right.into_iter().fold(left, |left, (op, right)| {
49-
WithSpan::new(Self::BinOp(op, Box::new(left), Box::new(right)), start)
50-
}),
51-
))
46+
)));
5247
}
48+
value(rust, keyword(rinja))(i)
5349
}
5450
}
5551

@@ -189,15 +185,26 @@ impl<'a> Expr<'a> {
189185
))(i)
190186
}
191187

192-
expr_prec_layer!(or, and, "||");
193-
expr_prec_layer!(and, compare, "&&");
194-
expr_prec_layer!(compare, bor, "==", "!=", ">=", ">", "<=", "<");
195-
expr_prec_layer!(bor, bxor, "|");
196-
expr_prec_layer!(bxor, band, "^");
197-
expr_prec_layer!(band, shifts, "&");
198-
expr_prec_layer!(shifts, addsub, ">>", "<<");
199-
expr_prec_layer!(addsub, muldivmod, "+", "-");
200-
expr_prec_layer!(muldivmod, filtered, "*", "/", "%");
188+
expr_prec_layer!(or, and, tag("||"));
189+
expr_prec_layer!(and, compare, tag("&&"));
190+
expr_prec_layer!(
191+
compare,
192+
bor,
193+
alt((
194+
tag("=="),
195+
tag("!="),
196+
tag(">="),
197+
tag(">"),
198+
tag("<="),
199+
tag("<"),
200+
))
201+
);
202+
expr_prec_layer!(bor, bxor, alternative_binop("|", "bitor"));
203+
expr_prec_layer!(bxor, band, alternative_binop("^", "xor"));
204+
expr_prec_layer!(band, shifts, alternative_binop("&", "bitand"));
205+
expr_prec_layer!(shifts, addsub, alt((tag(">>"), tag("<<"))));
206+
expr_prec_layer!(addsub, muldivmod, alt((tag("+"), tag("-"))));
207+
expr_prec_layer!(muldivmod, filtered, alt((tag("*"), tag("/"), tag("%"))));
201208

202209
fn filtered(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> {
203210
let (_, level) = level.nest(i)?;

rinja_parser/src/tests.rs

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -684,20 +684,6 @@ fn test_odd_calls() {
684684
})),
685685
)]
686686
);
687-
assert_eq!(
688-
Ast::from_str("{{ a(b) |c }}", None, &syntax).unwrap().nodes,
689-
vec![Node::Expr(
690-
Ws(None, None),
691-
WithSpan::no_span(Expr::BinOp(
692-
"|",
693-
Box::new(WithSpan::no_span(Expr::Call(
694-
Box::new(WithSpan::no_span(Expr::Var("a"))),
695-
vec![WithSpan::no_span(Expr::Var("b"))]
696-
))),
697-
Box::new(WithSpan::no_span(Expr::Var("c")))
698-
),)
699-
)]
700-
);
701687
}
702688

703689
#[test]
@@ -847,19 +833,6 @@ fn test_parse_tuple() {
847833
})),
848834
)],
849835
);
850-
assert_eq!(
851-
Ast::from_str("{{ () | abs }}", None, &syntax)
852-
.unwrap()
853-
.nodes,
854-
vec![Node::Expr(
855-
Ws(None, None),
856-
WithSpan::no_span(Expr::BinOp(
857-
"|",
858-
Box::new(WithSpan::no_span(Expr::Tuple(vec![]))),
859-
Box::new(WithSpan::no_span(Expr::Var("abs")))
860-
)),
861-
)],
862-
);
863836
assert_eq!(
864837
Ast::from_str("{{ (1)|abs }}", None, &syntax).unwrap().nodes,
865838
vec![Node::Expr(
@@ -872,21 +845,6 @@ fn test_parse_tuple() {
872845
})),
873846
)],
874847
);
875-
assert_eq!(
876-
Ast::from_str("{{ (1) | abs }}", None, &syntax)
877-
.unwrap()
878-
.nodes,
879-
vec![Node::Expr(
880-
Ws(None, None),
881-
WithSpan::no_span(Expr::BinOp(
882-
"|",
883-
Box::new(WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span(
884-
Expr::NumLit("1")
885-
))))),
886-
Box::new(WithSpan::no_span(Expr::Var("abs")))
887-
)),
888-
)],
889-
);
890848
assert_eq!(
891849
Ast::from_str("{{ (1,)|abs }}", None, &syntax)
892850
.unwrap()
@@ -901,21 +859,6 @@ fn test_parse_tuple() {
901859
})),
902860
)],
903861
);
904-
assert_eq!(
905-
Ast::from_str("{{ (1,) | abs }}", None, &syntax)
906-
.unwrap()
907-
.nodes,
908-
vec![Node::Expr(
909-
Ws(None, None),
910-
WithSpan::no_span(Expr::BinOp(
911-
"|",
912-
Box::new(WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span(
913-
Expr::NumLit("1")
914-
)]))),
915-
Box::new(WithSpan::no_span(Expr::Var("abs")))
916-
)),
917-
)],
918-
);
919862
assert_eq!(
920863
Ast::from_str("{{ (1, 2)|abs }}", None, &syntax)
921864
.unwrap()
@@ -931,22 +874,6 @@ fn test_parse_tuple() {
931874
})),
932875
)],
933876
);
934-
assert_eq!(
935-
Ast::from_str("{{ (1, 2) | abs }}", None, &syntax)
936-
.unwrap()
937-
.nodes,
938-
vec![Node::Expr(
939-
Ws(None, None),
940-
WithSpan::no_span(Expr::BinOp(
941-
"|",
942-
Box::new(WithSpan::no_span(Expr::Tuple(vec![
943-
WithSpan::no_span(Expr::NumLit("1")),
944-
WithSpan::no_span(Expr::NumLit("2"))
945-
]))),
946-
Box::new(WithSpan::no_span(Expr::Var("abs")))
947-
)),
948-
)],
949-
);
950877
}
951878

952879
#[test]
@@ -1050,17 +977,6 @@ fn test_parse_array() {
1050977
}))
1051978
)],
1052979
);
1053-
assert_eq!(
1054-
Ast::from_str("{{ [] |foo }}", None, &syntax).unwrap().nodes,
1055-
vec![Node::Expr(
1056-
Ws(None, None),
1057-
WithSpan::no_span(Expr::BinOp(
1058-
"|",
1059-
Box::new(WithSpan::no_span(Expr::Array(vec![]))),
1060-
Box::new(WithSpan::no_span(Expr::Var("foo")))
1061-
)),
1062-
)],
1063-
);
1064980
}
1065981

1066982
#[test]

testing/templates/allow-whitespaces.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
{{1+2}}{{ 1+2 }}{{ 1 +2 }}{{ 1+ 2 }} {{ 1 + 2 }}
3636
{{1*2}}{{ 1*2 }}{{ 1 *2 }}{{ 1* 2 }} {{ 1 * 2 }}
3737
{{1&2}}{{ 1&2 }}{{ 1 &2 }}{{ 1& 2 }} {{ 1 & 2 }}
38-
{{1|2}}{{ 1|2 }}{{ 1 |2 }}{{ 1| 2 }} {{ 1 | 2 }}
38+
{{1 bitor 2}}{{ 1 bitor 2 }}{{ 1 bitor 2}}{{1 bitor 2 }} {{1 bitor 2}}
3939

4040
{{true}}{{false}}
4141
{{!true}}{{ !true }}{{ ! true }}

testing/templates/operators.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
{% if c >> b == a -%}
1717
lsh
1818
{%- endif -%}
19-
{% if a & b == b -%}
19+
{% if a bitand b == b -%}
2020
band
2121
{%- endif -%}
22-
{% if b ^ c == a + c -%}
22+
{% if b xor c == a + c -%}
2323
bxor
2424
{%- endif -%}
25-
{% if (b | c) == a + c -%}
25+
{% if b bitor c == a + c -%}
2626
bor
2727
{%- endif -%}
2828
{% if a == b && a + b == c -%}

testing/templates/precedence.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
{{ 1 * 2 + 4 -}}
55
{{ 11 - 15 / 3 -}}
66
{{ 4 + 5 % 3 -}}
7-
{{ 4 | 2 + 5 & 2 -}}
7+
{{ 4 bitor 2 + 5 & 2 -}}

0 commit comments

Comments
 (0)