8000 Bugfix issue 47 (#114) · jinja2cpp/Jinja2Cpp@9235979 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9235979

Browse files
palchukovskyflexferrum
authored andcommitted
Bugfix issue 47 (#114)
* Fixed pipe operator ('|') precedence #47 * Removed method FullExpressionEvaluator::SetFilter, as it isn't required anymore after bug #47 resolving.
1 parent dac6c5b commit 9235979

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

src/expression_evaluator.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,17 @@ InternalValue FullExpressionEvaluator::Evaluate(RenderContext& values)
2727
if (!m_expression)
2828
return InternalValue();
2929

30-
InternalValue origVal = m_expression->Evaluate(values);
31-
if (m_filter)
32-
origVal = m_filter->Evaluate(origVal, values);
30+
auto result = m_expression->Evaluate(values);
3331

3432
if (m_tester && !m_tester->Evaluate(values))
3533
return m_tester->EvaluateAltValue(values);
3634

37-
return origVal;
35+
return result;
3836
}
3937

4038
void FullExpressionEvaluator::Render(OutStream& stream, RenderContext& values)
4139
{
42-
if (!m_filter && !m_tester)
40+
if (!m_tester)
4341
m_expression->Render(stream, values);
4442
else
4543
Expression::Render(stream, values);
@@ -71,6 +69,12 @@ InternalValue SubscriptExpression::Evaluate(RenderContext& values)
7169
return cur;
7270
}
7371

72+
InternalValue FilteredExpression::Evaluate(RenderContext& values)
73+
{
74+
auto origResult = m_expression->Evaluate(values);
75+
return m_filter->Evaluate(origResult, values);
76+
}
77+
7478
InternalValue UnaryExpression::Evaluate(RenderContext& values)
7579
{
7680
return Apply<visitors::UnaryOperation>(m_expr->Evaluate(values), m_oper);

src/expression_evaluator.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ class FullExpressionEvaluator : public ExpressionEvaluatorBase
6969
{
7070
m_expression = std::move(expr);
7171
}
72-
void SetFilter(ExpressionEvaluatorPtr<ExpressionFilter> expr)
73-
{
74-
m_filter = std::move(expr);
75-
}
7672
void SetTester(ExpressionEvaluatorPtr<IfExpression> expr)
7773
{
7874
m_tester = std::move(expr);
@@ -81,7 +77,6 @@ class FullExpressionEvaluator : public ExpressionEvaluatorBase
8177
void Render(OutStream &stream, RenderContext &values) override;
8278
private:
8379
ExpressionEvaluatorPtr<Expression> m_expression;
84-
ExpressionEvaluatorPtr<ExpressionFilter> m_filter;
8580
ExpressionEvaluatorPtr<IfExpression> m_tester;
8681
};
8782

@@ -115,6 +110,21 @@ class SubscriptExpression : public Expression
115110
std::vector<ExpressionEvaluatorPtr<Expression>> m_subscriptExprs;
116111
};
117112

113+
class FilteredExpression : public Expression
114+
{
115+
public:
116+
explicit FilteredExpression(ExpressionEvaluatorPtr<Expression> expression, ExpressionEvaluatorPtr<ExpressionFilter> filter)
117+
: m_expression(std::move(expression))
118+
, m_filter(std::move(filter))
119+
{
120+
}
121+
InternalValue Evaluate(RenderContext&) override;
122+
123+
private:
124+
ExpressionEvaluatorPtr<Expression> m_expression;
125+
ExpressionEvaluatorPtr<ExpressionFilter> m_filter;
126+
};
127+
118128
class ConstantExpression : public Expression
119129
{
120130
public:

src/expression_parser.cpp

Lines changed: 19 additions & 14 deletions

Original file line numberDiff line numberDiff line change
@@ -53,13 +53,6 @@ ExpressionParser::ParseResult<ExpressionEvaluatorPtr<FullExpressionEvaluator>> E
5353
return value.get_unexpected();
5454

5555
evaluator->SetExpression(*value);
56-
if (lexer.EatIfEqual('|'))
57-
{
58-
auto filter = ParseFilterExpression(lexer);
59-
if (!filter)
60-
return filter.get_unexpected();
61-
evaluator->SetFilter(*filter);
62-
}
6356

6457
if (includeIfPart && lexer.EatIfEqual(Keyword::If))
6558
{
@@ -265,18 +258,30 @@ ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionPars
265258
266259
ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionParser::ParseUnaryPlusMinus(LexScanner& lexer)
267260
{
268-
Token tok = lexer.NextToken();
269-
if (tok != '+' && tok != '-' && lexer.GetAsKeyword(tok) != Keyword::LogicalNot)
270-
{
261+
const auto tok = lexer.NextToken();
262+
const auto isUnary = tok == '+' || tok == '-' || lexer.GetAsKeyword(tok) == Keyword::LogicalNot;
263+
if (!isUnary)
271264
lexer.ReturnToken();
272-
return ParseValueExpression(lexer);
273-
}
274-
265+
275266
auto subExpr = ParseValueExpression(lexer);
276267
if (!subExpr)
277268
return subExpr;
278269

279-
return std::make_shared<UnaryExpression>(tok == '+' ? UnaryExpression::UnaryPlus : (tok == '-' ? UnaryExpression::UnaryMinus : UnaryExpression::LogicalNot), *subExpr);
270+
ExpressionEvaluatorPtr<Expression> result;
271+
if (isUnary)
272+
result = std::make_shared<UnaryExpression>(tok == '+' ? UnaryExpression::UnaryPlus : (tok == '-' ? UnaryExpression::UnaryMinus : UnaryExpression::LogicalNot), *subExpr);
273+
else
274+
result = subExpr.value();
275+
276+
if (lexer.EatIfEqual('|'))
277+
{
278+
auto filter = ParseFilterExpression(lexer);
279+
if (!filter)
280+
return filter.get_unexpected();
281+
result = std::make_shared<FilteredExpression>(std::move(result), *filter);
282+
}
283+
284+
return result;
280285
}
281286

282287
ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionParser::ParseValueExpression(LexScanner& lexer)

test/expressions_test.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,24 @@ Outer ValueInner Value
122122
EXPECT_STREQ(expectedResult.c_str(), result.c_str());
123123
}
124124

125+
TEST(ExpressionsTest, PipeOperatorPrecedenceTest)
126+
{
127+
const std::string source = R"(>> {{ 2 < '6' | int }} <<
128+
>> {{ -30 | abs < str | int }} <<)";
129+
130+
Template tpl;
131+
ASSERT_TRUE(tpl.Load(source));
132+
133+
const ValuesMap params = {{"str", "20"}};
134+
135+
const auto result = tpl.RenderAsString(params).value();
136+
std::cout << result << std::endl;
137+
const std::string expectedResult = R"(>> true <<
138+
>> false <<)";
139+
140+
EXPECT_STREQ(expectedResult.c_str(), result.c_str());
141+
}
142+
125143
struct LogicalExprTestTag;
126144
using LogicalExprTest = InputOutputPairTest<LogicalExprTestTag>;
127145

0 commit comments

Comments
 (0)
0