if a ezc function returns another function we should evaluate it

This commit is contained in:
Tomasz Sowa 2021-11-05 22:23:22 +01:00
parent b8a9217429
commit bb0cc59eca
1 changed files with 104 additions and 44 deletions

View File

@ -181,6 +181,7 @@ private:
bool evaluate_last;
const std::wstring * previous_name;
Var<StreamType> * previous_result;
size_t nested_calls;
FindHelper(const std::wstring & name, std::vector<std::wstring> & fields, std::vector<Var<StreamType>> & parameters, Var<StreamType> & result):
@ -191,6 +192,7 @@ private:
evaluate_last = true;
previous_name = nullptr;
previous_result = nullptr;
nested_calls = 0;
}
const std::wstring & current_name()
@ -291,6 +293,8 @@ private:
bool can_use_vars;
bool program_mode;
size_t max_nested_calls;
ExpressionParser * expression_parser;
@ -364,14 +368,10 @@ private:
Var<StreamType> * FindInScope(const std::wstring & name);
void FindVariable(FindHelper & find_helper
//const std::wstring & name, std::vector<std::wstring> & fields, size_t & field_index, std::vector<Var<StreamType>> & parameters
);
void EvaluateVariable(FindHelper & find_helper
//const std::wstring & name, Var<StreamType> & var, std::vector<std::wstring> & fields, size_t & field_index, std::vector<Var<StreamType>> & parameters, Var<StreamType> & result
);
void FindVariable(FindHelper & find_helper);
void EvaluateVariable(FindHelper & find_helper);
void EvaluateModelField(FindHelper & find_helper);
void EvaluateFunction(typename Var<StreamType>::UserFunction user_function, FindHelper & find_helper);
// bool CallVariable(FindHelper & findxxx
@ -479,6 +479,7 @@ Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::Generator() :
can_use_vars = true;
expression_parser = nullptr;
program_mode = false;
max_nested_calls = 64;
}
@ -516,6 +517,7 @@ Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::operator=(cons
ezc_frames_stack_size = n.ezc_frames_stack_size;
expression_parser = n.expression_parser;
program_mode = n.program_mode;
max_nested_calls = n.max_nested_calls;
// vars doesn't have to be copied
@ -1810,6 +1812,7 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindVaria
find_helper.field_index = 0;
find_helper.previous_name = nullptr;
find_helper.previous_result = nullptr;
find_helper.nested_calls = 0;
do
{
@ -1838,38 +1841,12 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateV
if( find_helper.previous_name && find_helper.previous_result )
{
//var = find_helper.previous_result->find_child(name);
EvaluateModelField(find_helper);
}
//if( !var )
{
if( find_helper.previous_result->type == Var<StreamType>::TYPE_MODEL )
{
find_helper.found = CallModelField(*find_helper.previous_result->model, find_helper);
find_helper.previous_result = find_helper.found ? &find_helper.result : nullptr;
}
if( find_helper.previous_result->type == Var<StreamType>::TYPE_MODEL_CONTAINER_WRAPPER )
{
morm::Model * model = find_helper.previous_result->model_container_wrapper->get_model();
if( model )
{
find_helper.found = CallModelField(*model, find_helper); // parameters here?
find_helper.previous_result = find_helper.found ? &find_helper.result : nullptr;
}
else
{
// put some log (no [for] statement)
// CreateMsg(L"model ", name, fields, L" is not initialized, have you forgotten to use [for ...] statement?");
return;
}
}
}
// else
// {
// // child found
//
// }
if( find_helper.nested_calls > max_nested_calls )
{
return;
}
if( !find_helper.found )
@ -1881,10 +1858,9 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateV
// if a function returns another function we should make CallFunction() again?
if( var->type == Var<StreamType>::TYPE_FUNCTION && var->user_function )
{
CallFunction(var->user_function, find_helper);
find_helper.found = true;
EvaluateFunction(var->user_function, find_helper);
}
else
if( var->type == Var<StreamType>::TYPE_MODEL_CONTAINER_WRAPPER && var->model_container_wrapper )
{
if( find_helper.is_last_field() && is_generating_for )
@ -1893,12 +1869,12 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateV
var->clear_childs();
}
}
else
if( var->type == Var<StreamType>::TYPE_SPACE_WRAPPER && var->space_wrapper )
{
find_helper.found = CallSpace(*var->space_wrapper, find_helper);
}
else
if( var->type == Var<StreamType>::TYPE_DATE && var->date )
{
if( find_helper.is_last_field() )
@ -1923,6 +1899,90 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateV
}
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateModelField(FindHelper & find_helper)
{
//var = find_helper.previous_result->find_child(name);
//if( !var )
{
if( find_helper.previous_result->type == Var<StreamType>::TYPE_MODEL )
{
find_helper.found = CallModelField(*find_helper.previous_result->model, find_helper);
find_helper.previous_result = find_helper.found ? &find_helper.result : nullptr;
}
else
if( find_helper.previous_result->type == Var<StreamType>::TYPE_MODEL_CONTAINER_WRAPPER )
{
morm::Model * model = find_helper.previous_result->model_container_wrapper->get_model();
if( model )
{
find_helper.found = CallModelField(*model, find_helper); // parameters here?
find_helper.previous_result = find_helper.found ? &find_helper.result : nullptr;
}
else
{
// put some log (no [for] statement)
// CreateMsg(L"model ", name, fields, L" is not initialized, have you forgotten to use [for ...] statement?");
return;
}
}
if( find_helper.found )
{
if( find_helper.result.type == Var<StreamType>::TYPE_FUNCTION && find_helper.result.user_function )
{
EvaluateFunction(find_helper.result.user_function, find_helper);
if( !find_helper.found )
return; // maximum nested calls exceeded
}
}
}
// else
// {
// // child found
//
// }
}
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateFunction(typename Var<StreamType>::UserFunction user_function, FindHelper & find_helper)
{
bool call_again;
do
{
call_again = false;
CallFunction(user_function, find_helper);
find_helper.found = true;
if( find_helper.result.type == Var<StreamType>::TYPE_FUNCTION && find_helper.result.user_function )
{
user_function = find_helper.result.user_function;
find_helper.result.clear();
find_helper.nested_calls += 1;
if( find_helper.nested_calls <= max_nested_calls )
{
call_again = true;
}
else
{
CreateMsg(L"Generator exceeded max nested calls");
find_helper.found = false;
}
}
}
while( call_again );
}
/*
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallVariable(