@@ -87,7 +87,7 @@ BinaryExpression::BinaryExpression(BinaryExpression::Operation oper, ExpressionE
8787{
8888 if (m_oper == In)
8989 {
90- CallParams params;
90+ CallParamsInfo params;
9191 params.kwParams [" seq" ] = rightExpr;
9292 m_inTester = CreateTester (" in" , params);
9393 }
@@ -185,7 +185,7 @@ InternalValue DictCreator::Evaluate(RenderContext& context)
185185 return CreateMapAdapter (std::move (result));;
186186}
187187
188- ExpressionFilter::ExpressionFilter (const std::string& filterName, CallParams params)
188+ ExpressionFilter::ExpressionFilter (const std::string& filterName, CallParamsInfo params)
189189{
190190 m_filter = CreateFilter (filterName, std::move (params));
191191 if (!m_filter)
@@ -200,7 +200,7 @@ InternalValue ExpressionFilter::Evaluate(const InternalValue& baseVal, RenderCon
200200 return m_filter->Filter (baseVal, context);
201201}
202202
203- IsExpression::IsExpression (ExpressionEvaluatorPtr<> value, const std::string& tester, CallParams params)
203+ IsExpression::IsExpression (ExpressionEvaluatorPtr<> value, const std::string& tester, CallParamsInfo params)
204204 : m_value(value)
205205{
206206 m_tester = CreateTester (tester, std::move (params));
@@ -268,13 +268,15 @@ void CallExpression::Render(OutStream& stream, RenderContext& values)
268268 }
269269 }
270270
271+ auto callParams = helpers::EvaluateCallParams (m_params, values);
272+
271273 if (callable->GetType () == Callable::Type::Expression)
272274 {
273- stream.WriteValue (callable->GetExpressionCallable ()(m_params , values));
275+ stream.WriteValue (callable->GetExpressionCallable ()(callParams , values));
274276 }
275277 else
276278 {
277- callable->GetStatementCallable ()(m_params , stream, values);
279+ callable->GetStatementCallable ()(callParams , stream, values);
278280 }
279281}
280282
@@ -294,22 +296,24 @@ InternalValue CallExpression::CallArbitraryFn(RenderContext& values)
294296 if (kind != Callable::GlobalFunc && kind != Callable::UserCallable && kind != Callable::Macro)
295297 return InternalValue ();
296298
299+ auto callParams = helpers::EvaluateCallParams (m_params, values);
300+
297301 if (callable->GetType () == Callable::Type::Expression)
298302 {
299- return callable->GetExpressionCallable ()(m_params , values);
303+ return callable->GetExpressionCallable ()(callParams , values);
300304 }
301305
302306 TargetString resultStr;
303307 auto stream = values.GetRendererCallback ()->GetStreamOnString (resultStr);
304- callable->GetStatementCallable ()(m_params , stream, values);
308+ callable->GetStatementCallable ()(callParams , stream, values);
305309 return resultStr;
306310}
307311
308312InternalValue CallExpression::CallGlobalRange (RenderContext& values)
309313{
310314 bool isArgsParsed = true ;
311315
312- auto args = helpers::ParseCallParams ({{ " start" }, {" stop" , true }, {" step" } }, m_params, isArgsParsed);
316+ auto args = helpers::ParseCallParamsInfo ({ { " start" }, { " stop" , true }, { " step" } }, m_params, isArgsParsed);
313317 if (!isArgsParsed)
314318 return InternalValue ();
315319
@@ -385,8 +389,23 @@ enum ParamState
385389 MappedKw,
386390};
387391
388- template <typename T>
389- ParsedArguments ParseCallParamsImpl (const T& args, const CallParams& params, bool & isSucceeded)
392+ template <typename Result>
393+ struct ParsedArgumentDefaultValGetter ;
394+
395+ template <>
396+ struct ParsedArgumentDefaultValGetter <ParsedArguments>
397+ {
398+ static auto Get (const InternalValue& val) { return val; }
399+ };
400+
401+ template <>
402+ struct ParsedArgumentDefaultValGetter <ParsedArgumentsInfo>
403+ {
404+ static auto Get (const InternalValue& val) { return std::make_shared<ConstantExpression>(val); }
405+ };
406+
407+ template <typename Result, typename T, typename P>
408+ Result ParseCallParamsImpl (const T& args, const P& params, bool & isSucceeded)
390409{
391410 struct ArgInfo
392411 {
@@ -401,7 +420,7 @@ ParsedArguments ParseCallParamsImpl(const T& args, const CallParams& params, boo
401420
402421 isSucceeded = true ;
403422
404- ParsedArguments result;
423+ Result result;
405424
406425 int argIdx = 0 ;
407426 int firstMandatoryIdx = -1 ;
@@ -465,6 +484,8 @@ ParsedArguments ParseCallParamsImpl(const T& args, const CallParams& params, boo
465484 ;
466485
467486 isFirstTime = false ;
487+ if (startPosArg == args.size ())
488+ break ;
468489 continue ;
469490 }
470491
@@ -510,7 +531,14 @@ ParsedArguments ParseCallParamsImpl(const T& args, const CallParams& params, boo
510531 case NotFound:
511532 {
512533 if (!IsEmpty (argInfo.info ->defaultVal ))
513- result.args [argInfo.info ->name ] = std::make_shared<ConstantExpression>(argInfo.info ->defaultVal );
534+ #if __cplusplus >= 201703L
535+ if constexpr (std::is_same<Result, ParsedArgumentsInfo>::value)
536+ result.args [argInfo.info ->name ] = std::make_shared<ConstantExpression>(argInfo.info ->defaultVal );
537+ else
538+ result.args [argInfo.info ->name ] = argInfo.info ->defaultVal ;
539+ #else
540+ result.args [argInfo.info ->name ] = ParsedArgumentDefaultValGetter<Result>::Get (argInfo.info ->defaultVal );
541+ #endif
514542 break ;
515543 }
516544 case NotFoundMandatory:
@@ -537,12 +565,35 @@ ParsedArguments ParseCallParamsImpl(const T& args, const CallParams& params, boo
537565
538566ParsedArguments ParseCallParams (const std::initializer_list<ArgumentInfo>& args, const CallParams& params, bool & isSucceeded)
539567{
540- return ParseCallParamsImpl (args, params, isSucceeded);
568+ return ParseCallParamsImpl<ParsedArguments> (args, params, isSucceeded);
541569}
542570
543571ParsedArguments ParseCallParams (const std::vector<ArgumentInfo>& args, const CallParams& params, bool & isSucceeded)
544572{
545- return ParseCallParamsImpl (args, params, isSucceeded);
573+ return ParseCallParamsImpl<ParsedArguments>(args, params, isSucceeded);
574+ }
575+
576+ ParsedArgumentsInfo ParseCallParamsInfo (const std::initializer_list<ArgumentInfo>& args, const CallParamsInfo& params, bool & isSucceeded)
577+ {
578+ return ParseCallParamsImpl<ParsedArgumentsInfo>(args, params, isSucceeded);
579+ }
580+
581+ ParsedArgumentsInfo ParseCallParamsInfo (const std::vector<ArgumentInfo>& args, const CallParamsInfo& params, bool & isSucceeded)
582+ {
583+ return ParseCallParamsImpl<ParsedArgumentsInfo>(args, params, isSucceeded);
584+ }
585+
586+ CallParams EvaluateCallParams (const CallParamsInfo& info, RenderContext& context)
587+ {
588+ CallParams result;
589+
590+ for (auto & p : info.posParams )
591+ result.posParams .push_back (p->Evaluate (context));
592+
593+ for (auto & kw : info.kwParams )
594+ result.kwParams [kw.first ] = kw.second ->Evaluate (context);
595+
596+ return result;
546597}
547598
548599}
0 commit comments