Skip to content

Commit a9629bb

Browse files
committed
Fix values subscription parser
1 parent 425cd20 commit a9629bb

File tree

6 files changed

+75
-65
lines changed

6 files changed

+75
-65
lines changed

src/expression_evaluator.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,31 @@ InternalValue DictionaryCreator::Evaluate(RenderContext& context)
172172

173173
InternalValue CallExpression::Evaluate(RenderContext& values)
174174
{
175-
std::string valueRef = boost::algorithm::join(m_valueRef, ".");
175+
enum
176+
{
177+
InvalidFn = -1,
178+
RangeFn = 1,
179+
LoopCycleFn = 2
180+
};
181+
182+
auto& scope = values.EnterScope();
183+
scope["range"] = InternalValue(static_cast<int64_t>(RangeFn));
184+
scope["loop"] = MapAdapter::CreateAdapter(InternalValueMap{{"cycle", InternalValue(static_cast<int64_t>(LoopCycleFn))}});
185+
auto fn = m_valueRef->Evaluate(values);
186+
values.ExitScope();
187+
188+
auto fnId = ConvertToInt(fn, InvalidFn);
189+
176190

177-
if (valueRef == "range")
191+
switch (fnId)
192+
{
193+
case RangeFn:
178194
return CallGlobalRange(values);
179-
else if (valueRef == "loop.cycle")
195+
case LoopCycleFn:
180196
return CallLoopCycle(values);
197+
default:
198+
break;
199+
}
181200

182201
return InternalValue();
183202
}

src/expression_evaluator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ class CallExpression : public Expression
252252
public:
253253
virtual ~CallExpression() {}
254254

255-
CallExpression(std::vector<std::string> valueRef, CallParams params)
255+
CallExpression(ExpressionEvaluatorPtr<> valueRef, CallParams params)
256256
: m_valueRef(std::move(valueRef))
257257
, m_params(std::move(params))
258258
{
@@ -268,7 +268,7 @@ class CallExpression : public Expression
268268
InternalValue CallLoopCycle(RenderContext &values);
269269

270270
private:
271-
std::vector<std::string> m_valueRef;
271+
ExpressionEvaluatorPtr<> m_valueRef;
272272
CallParams m_params;
273273
};
274274

src/expression_parser.cpp

Lines changed: 25 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -280,31 +280,13 @@ ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseValueExpression(LexSca
280280
{
281281
lexer.ReturnToken();
282282
auto valueRef = ParseValueRef(lexer);
283-
if (valueRef.empty())
284-
return ExpressionEvaluatorPtr<Expression>();
285283

286-
Token nextTok = lexer.NextToken();
287-
if (nextTok == '[')
288-
{
289-
return ParseSubsicpt(lexer, valueRef);
290-
}
291-
else if (nextTok == '(')
284+
if (lexer.EatIfEqual('('))
292285
{
293286
return ParseCall(lexer, valueRef);
294287
}
295288

296-
lexer.ReturnToken();
297-
298-
ExpressionEvaluatorPtr<Expression> baseValueRef = std::make_shared<ValueRefExpression>(valueRef[0]);
299-
if (valueRef.size() != 1)
300-
{
301-
for (size_t i = 1; i < valueRef.size(); ++ i)
302-
{
303-
auto indexExpr = std::make_shared<ConstantExpression>(InternalValue(valueRef[i]));
304-
baseValueRef = std::make_shared<SubscriptExpression>(baseValueRef, indexExpr);
305-
}
306-
}
307-
return baseValueRef;
289+
return valueRef;
308290
}
309291
case Token::IntegerNum:
310292
case Token::FloatNum:
@@ -407,32 +389,7 @@ ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseTuple(LexScanner& lexe
407389
return result;
408390
}
409391

410-
ExpressionEvaluatorPtr<SubscriptExpression> ExpressionParser::ParseSubsicpt(LexScanner& lexer, const std::vector<std::string>& valueRef)
411-
{
412-
ExpressionEvaluatorPtr<SubscriptExpression> result;
413-
414-
auto finalIndexExpr = ParseFullExpression(lexer);
415-
if (!finalIndexExpr || lexer.PeekNextToken() != ']')
416-
return result;
417-
418-
lexer.EatToken();
419-
420-
ExpressionEvaluatorPtr<Expression> baseValueRef = std::make_shared<ValueRefExpression>(valueRef[0]);
421-
if (valueRef.size() != 1)
422-
{
423-
for (size_t i = 1; i < valueRef.size(); ++ i)
424-
{
425-
auto indexExpr = std::make_shared<ConstantExpression>(InternalValue(valueRef[i]));
426-
baseValueRef = std::make_shared<SubscriptExpression>(baseValueRef, indexExpr);
427-
}
428-
}
429-
430-
result = std::make_shared<SubscriptExpression>(baseValueRef, finalIndexExpr);
431-
432-
return result;
433-
}
434-
435-
ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseCall(LexScanner& lexer, const std::vector<std::string>& valueRef)
392+
ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseCall(LexScanner& lexer, ExpressionEvaluatorPtr<Expression> valueRef)
436393
{
437394
ExpressionEvaluatorPtr<Expression> result;
438395

@@ -484,25 +441,37 @@ CallParams ExpressionParser::ParseCallParams(LexScanner& lexer, bool& isValid)
484441
return result;
485442
}
486443

487-
std::vector<std::string> ExpressionParser::ParseValueRef(LexScanner& lexer)
444+
ExpressionEvaluatorPtr<Expression> ExpressionParser::ParseValueRef(LexScanner& lexer)
488445
{
489446
Token tok = lexer.NextToken();
490447
auto valueName = AsString(tok.value);
448+
ExpressionEvaluatorPtr<Expression> valueRef = std::make_shared<ValueRefExpression>(valueName);
491449

492-
std::vector<std::string> result;
493-
result.push_back(valueName);
494-
495-
while (lexer.NextToken() == '.')
450+
for (tok = lexer.NextToken(); tok.type == '.' || tok.type == '['; tok = lexer.NextToken())
496451
{
497-
tok = lexer.NextToken();
498-
if (tok != Token::Identifier)
499-
return std::vector<std::string>();
452+
ExpressionEvaluatorPtr<Expression> indexExpr;
453+
if (tok == '.')
454+
{
455+
tok = lexer.NextToken();
456+
if (tok.type != Token::Identifier)
457+
return ExpressionEvaluatorPtr<>();
458+
valueName = AsString(tok.value);
459+
indexExpr = std::make_shared<ConstantExpression>(InternalValue(valueName));
460+
}
461+
else
462+
{
463+
indexExpr = ParseFullExpression(lexer);
500464

501-
result.push_back(AsString(tok.value));
465+
if (!indexExpr || !lexer.EatIfEqual(']'))
466+
return ExpressionEvaluatorPtr<>();
467+
}
468+
469+
valueRef = std::make_shared<SubscriptExpression>(valueRef, indexExpr);
502470
}
471+
503472
lexer.ReturnToken();
504473

505-
return result;
474+
return valueRef;
506475
}
507476

508477
ExpressionEvaluatorPtr<ExpressionFilter> ExpressionParser::ParseFilterExpression(LexScanner& lexer)

src/expression_parser.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ class ExpressionParser
2727
ExpressionEvaluatorPtr<Expression> ParseBracedExpressionOrTuple(LexScanner& lexer);
2828
ExpressionEvaluatorPtr<Expression> ParseDictionary(LexScanner& lexer);
2929
ExpressionEvaluatorPtr<Expression> ParseTuple(LexScanner& lexer);
30-
ExpressionEvaluatorPtr<SubscriptExpression> ParseSubsicpt(LexScanner& lexer, const std::vector<std::string>& valueRef);
31-
ExpressionEvaluatorPtr<Expression> ParseCall(LexScanner& lexer, const std::vector<std::string>& valueRef);
30+
ExpressionEvaluatorPtr<Expression> ParseCall(LexScanner& lexer, ExpressionEvaluatorPtr<Expression> valueRef);
3231
CallParams ParseCallParams(LexScanner& lexer, bool& isValid);
33-
std::vector<std::string> ParseValueRef(LexScanner& lexer);
32+
ExpressionEvaluatorPtr<Expression> ParseValueRef(LexScanner& lexer);
3433
ExpressionEvaluatorPtr<ExpressionFilter> ParseFilterExpression(LexScanner& lexer);
3534
ExpressionEvaluatorPtr<IfExpression> ParseIfExpression(LexScanner& lexer);
3635

src/lexer.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,25 @@ class LexScanner
227227
return *m_state.m_cur;
228228
}
229229

230+
bool EatIfEqual(char type)
231+
{
232+
return EatIfEqual(static_cast<Token::Type>(type));
233+
}
234+
235+
bool EatIfEqual(Token::Type type)
236+
{
237+
if (m_state.m_cur == m_state.m_end)
238+
return type == Token::Type::Eof;
239+
240+
if (m_state.m_cur->type == type)
241+
{
242+
++ m_state.m_cur;
243+
return true;
244+
}
245+
246+
return false;
247+
}
248+
230249
private:
231250
State m_state;
232251
static const Token& EofToken()

test/expressions_test.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ INSTANTIATE_TEST_CASE_P(DotSubscriptionTest, ExpressionSubstitutionTest, ::testi
142142

143143

144144
INSTANTIATE_TEST_CASE_P(ComplexSubscriptionTest, ExpressionSubstitutionTest, ::testing::Values(
145-
// InputOutputPair{"mapValue.reflectedList[1]['intValue']", "1"},
145+
InputOutputPair{"mapValue.reflectedList[1]['intValue']", "1"},
146+
InputOutputPair{"mapValue['reflectedList'][1]['intValue']", "1"},
147+
InputOutputPair{"mapValue.reflectedList[1].intValue", "1"},
148+
InputOutputPair{"reflectedList[1].intValue", "1"},
149+
InputOutputPair{"reflectedList[1].strValue[0]", "t"},
146150
InputOutputPair{"reflectedVal.strValue[0]", "t"}
147151
));

0 commit comments

Comments
 (0)