if a ezc function returns another function we should evaluate it
This commit is contained in:
parent
b8a9217429
commit
bb0cc59eca
148
src/generator.h
148
src/generator.h
|
@ -181,6 +181,7 @@ private:
|
||||||
bool evaluate_last;
|
bool evaluate_last;
|
||||||
const std::wstring * previous_name;
|
const std::wstring * previous_name;
|
||||||
Var<StreamType> * previous_result;
|
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):
|
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;
|
evaluate_last = true;
|
||||||
previous_name = nullptr;
|
previous_name = nullptr;
|
||||||
previous_result = nullptr;
|
previous_result = nullptr;
|
||||||
|
nested_calls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::wstring & current_name()
|
const std::wstring & current_name()
|
||||||
|
@ -291,6 +293,8 @@ private:
|
||||||
bool can_use_vars;
|
bool can_use_vars;
|
||||||
bool program_mode;
|
bool program_mode;
|
||||||
|
|
||||||
|
size_t max_nested_calls;
|
||||||
|
|
||||||
ExpressionParser * expression_parser;
|
ExpressionParser * expression_parser;
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,14 +368,10 @@ private:
|
||||||
|
|
||||||
Var<StreamType> * FindInScope(const std::wstring & name);
|
Var<StreamType> * FindInScope(const std::wstring & name);
|
||||||
|
|
||||||
void FindVariable(FindHelper & find_helper
|
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);
|
||||||
);
|
void EvaluateModelField(FindHelper & find_helper);
|
||||||
|
void EvaluateFunction(typename Var<StreamType>::UserFunction user_function, FindHelper & find_helper);
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// bool CallVariable(FindHelper & findxxx
|
// bool CallVariable(FindHelper & findxxx
|
||||||
|
@ -479,6 +479,7 @@ Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::Generator() :
|
||||||
can_use_vars = true;
|
can_use_vars = true;
|
||||||
expression_parser = nullptr;
|
expression_parser = nullptr;
|
||||||
program_mode = false;
|
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;
|
ezc_frames_stack_size = n.ezc_frames_stack_size;
|
||||||
expression_parser = n.expression_parser;
|
expression_parser = n.expression_parser;
|
||||||
program_mode = n.program_mode;
|
program_mode = n.program_mode;
|
||||||
|
max_nested_calls = n.max_nested_calls;
|
||||||
|
|
||||||
// vars doesn't have to be copied
|
// 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.field_index = 0;
|
||||||
find_helper.previous_name = nullptr;
|
find_helper.previous_name = nullptr;
|
||||||
find_helper.previous_result = nullptr;
|
find_helper.previous_result = nullptr;
|
||||||
|
find_helper.nested_calls = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1838,38 +1841,12 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::EvaluateV
|
||||||
|
|
||||||
if( find_helper.previous_name && find_helper.previous_result )
|
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.nested_calls > max_nested_calls )
|
||||||
{
|
{
|
||||||
if( find_helper.previous_result->type == Var<StreamType>::TYPE_MODEL )
|
return;
|
||||||
{
|
|
||||||
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.found )
|
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 a function returns another function we should make CallFunction() again?
|
||||||
if( var->type == Var<StreamType>::TYPE_FUNCTION && var->user_function )
|
if( var->type == Var<StreamType>::TYPE_FUNCTION && var->user_function )
|
||||||
{
|
{
|
||||||
CallFunction(var->user_function, find_helper);
|
EvaluateFunction(var->user_function, find_helper);
|
||||||
find_helper.found = true;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if( var->type == Var<StreamType>::TYPE_MODEL_CONTAINER_WRAPPER && var->model_container_wrapper )
|
if( var->type == Var<StreamType>::TYPE_MODEL_CONTAINER_WRAPPER && var->model_container_wrapper )
|
||||||
{
|
{
|
||||||
if( find_helper.is_last_field() && is_generating_for )
|
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();
|
var->clear_childs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if( var->type == Var<StreamType>::TYPE_SPACE_WRAPPER && var->space_wrapper )
|
if( var->type == Var<StreamType>::TYPE_SPACE_WRAPPER && var->space_wrapper )
|
||||||
{
|
{
|
||||||
find_helper.found = CallSpace(*var->space_wrapper, find_helper);
|
find_helper.found = CallSpace(*var->space_wrapper, find_helper);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if( var->type == Var<StreamType>::TYPE_DATE && var->date )
|
if( var->type == Var<StreamType>::TYPE_DATE && var->date )
|
||||||
{
|
{
|
||||||
if( find_helper.is_last_field() )
|
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>
|
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallVariable(
|
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallVariable(
|
||||||
|
|
Loading…
Reference in New Issue