diff --git a/src/env.h b/src/env.h index e7081df..a020ee8 100644 --- a/src/env.h +++ b/src/env.h @@ -143,8 +143,8 @@ struct Env //const std::wstring & par; // an input stream used in [filter] statement - // if there is other statement than [filter] then this is an empty stream - const StreamType & in; + // and when methods/functions are chained + Var & in; // indicates that this function is from [for ...] statement bool is_for; @@ -189,7 +189,7 @@ struct Env Env(Var & result, std::vector> & pars, - const StreamType & input_stream, + Var & input_stream, Stack & s, const Item & item_) : out(result.stream), res(result), params(pars), in(input_stream), stack(s), item(item_) { diff --git a/src/generator.h b/src/generator.h index b4010e9..9d0b571 100644 --- a/src/generator.h +++ b/src/generator.h @@ -176,23 +176,31 @@ private: std::vector & fields; size_t field_index; std::vector> & parameters; - Var & result; + Var * input; + Var * result; bool found; - bool evaluate_last; const std::wstring * previous_name; - Var * previous_result; + morm::Model * previous_model; + morm::ModelContainerWrapper * previous_model_container_wrapper; + morm::SpaceWrapper * previous_space_wrapper; size_t nested_calls; - FindHelper(const std::wstring & name, std::vector & fields, std::vector> & parameters, Var & result): - name(name), fields(fields), parameters(parameters), result(result) + FindHelper( + const std::wstring & name, + std::vector & fields, + std::vector> & parameters + ): name(name), fields(fields), parameters(parameters) { field_index = 0; found = false; - evaluate_last = true; previous_name = nullptr; - previous_result = nullptr; nested_calls = 0; + input = nullptr; + result = nullptr; + previous_model = nullptr; + previous_model_container_wrapper = nullptr; + previous_space_wrapper = nullptr; } const std::wstring & current_name() @@ -202,9 +210,6 @@ private: bool is_last_field() { - if( field_index == 0 ) - return true; - return field_index == fields.size(); } @@ -370,7 +375,7 @@ private: void FindVariable(FindHelper & find_helper); void EvaluateVariable(FindHelper & find_helper); - void EvaluateModelField(FindHelper & find_helper); + bool EvaluateModelField(FindHelper & find_helper); void EvaluateFunction(typename Var::UserFunction user_function, FindHelper & find_helper); @@ -1047,8 +1052,7 @@ void Generator::CallFunct { // if( find_helper.parameters.empty() ) { - StreamType fake_stream; - Env info(find_helper.result, find_helper.parameters, fake_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + Env info(*find_helper.result, find_helper.parameters, *find_helper.input, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallFunction(function, info); } // else @@ -1111,14 +1115,14 @@ void Generator::DumpSpace if( dump_space ) { - space.serialize_to_space_stream(find_helper.result.stream, pretty); - find_helper.result.type = Var::TYPE_STREAM; + space.serialize_to_space_stream(find_helper.result->stream, pretty); + find_helper.result->type = Var::TYPE_STREAM; } else if( dump_json ) { - space.serialize_to_json_stream(find_helper.result.stream, pretty); - find_helper.result.type = Var::TYPE_STREAM; + space.serialize_to_json_stream(find_helper.result->stream, pretty); + find_helper.result->type = Var::TYPE_STREAM; } } } @@ -1167,23 +1171,23 @@ void Generator::PrintDate if( only_date ) { - find_helper.result.type = Var::TYPE_STREAM; - date.SerializeYearMonthDay(find_helper.result.stream, is_roman); + find_helper.result->type = Var::TYPE_STREAM; + date.SerializeYearMonthDay(find_helper.result->stream, is_roman); } else if( only_time ) { - find_helper.result.type = Var::TYPE_STREAM; + find_helper.result->type = Var::TYPE_STREAM; if( is_no_sec ) - date.SerializeHourMin(find_helper.result.stream); + date.SerializeHourMin(find_helper.result->stream); else - date.SerializeHourMinSec(find_helper.result.stream); + date.SerializeHourMinSec(find_helper.result->stream); } else { - find_helper.result.type = Var::TYPE_STREAM; - date.Serialize(find_helper.result.stream, is_roman, !is_no_sec); + find_helper.result->type = Var::TYPE_STREAM; + date.Serialize(find_helper.result->stream, is_roman, !is_no_sec); } } @@ -1358,14 +1362,14 @@ void Generator::CallSpace if( HasParam(find_helper.parameters, L"index") ) { - find_helper.result.stream << space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); - find_helper.result.type = Var::TYPE_STREAM; + find_helper.result->stream << space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); + find_helper.result->type = Var::TYPE_STREAM; } if( HasParam(find_helper.parameters, L"index-one") ) { - find_helper.result.stream << (space_wrapper.get_space_iterator_value(model_wrapper_space_table_index) + 1); - find_helper.result.type = Var::TYPE_STREAM; + find_helper.result->stream << (space_wrapper.get_space_iterator_value(model_wrapper_space_table_index) + 1); + find_helper.result->type = Var::TYPE_STREAM; } } } @@ -1407,15 +1411,15 @@ void Generator::PrintLast if( no_escape ) { //pt::WTextStream str; - space.serialize_to_string(find_helper.result.stream); - find_helper.result.type = Var::TYPE_STREAM; + space.serialize_to_string(find_helper.result->stream); + find_helper.result->type = Var::TYPE_STREAM; //CopyStream(str, out_stream, false); } else { // space->serialize_to_string(out_stream); - space.serialize_to_string(find_helper.result.stream); - find_helper.result.type = Var::TYPE_STREAM; + space.serialize_to_string(find_helper.result->stream); + find_helper.result->type = Var::TYPE_STREAM; } } @@ -1536,9 +1540,8 @@ bool Generator::CallModel */ //pt::WTextStream str; bool found = false; - StreamType fake_stream; - Env info(find_helper.result, find_helper.parameters, fake_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + Env info(*find_helper.result, find_helper.parameters, *find_helper.input, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); found = model.get_raw_value(nullptr, find_helper.current_name().c_str(), nullptr, info); // if( found && !str.empty()) @@ -1811,23 +1814,69 @@ void Generator::FindVaria { find_helper.field_index = 0; find_helper.previous_name = nullptr; - find_helper.previous_result = nullptr; + find_helper.previous_model = nullptr; + find_helper.previous_model_container_wrapper = nullptr; + find_helper.previous_space_wrapper = nullptr; find_helper.nested_calls = 0; + Var * origin_result = find_helper.result; + Var local_result, local_result2; + bool use_first_local_result = true; + + origin_result->clear(); + do { + if( find_helper.is_last_field() ) + { + find_helper.result = origin_result; + } + else + { + find_helper.result = use_first_local_result ? &local_result : &local_result2; + find_helper.result->clear(); + } + find_helper.found = false; EvaluateVariable(find_helper); + find_helper.previous_model = nullptr; + find_helper.previous_model_container_wrapper = nullptr; + find_helper.previous_space_wrapper = nullptr; + if( find_helper.found ) { + if( find_helper.result->type == Var::TYPE_MODEL ) + { + find_helper.previous_model = find_helper.result->model; + } + else + if( find_helper.result->type == Var::TYPE_MODEL_CONTAINER_WRAPPER ) + { + find_helper.previous_model_container_wrapper = find_helper.result->model_container_wrapper; + } + else + if( find_helper.result->type == Var::TYPE_SPACE_WRAPPER ) + { + find_helper.previous_space_wrapper = find_helper.result->space_wrapper; + } + else + { + find_helper.input = find_helper.result; + use_first_local_result = !use_first_local_result; + } + find_helper.previous_name = &find_helper.current_name(); find_helper.field_index += 1; } else { - find_helper.result.clear(); + if( find_helper.is_last_field() ) + { + find_helper.result->clear(); + } } + } while( find_helper.found && find_helper.field_index < find_helper.fields.size() + 1 ); } @@ -1839,14 +1888,10 @@ void Generator::EvaluateV Var * var = nullptr; const std::wstring & name = find_helper.current_name(); - if( find_helper.previous_name && find_helper.previous_result ) + if( find_helper.previous_name && (find_helper.previous_model || find_helper.previous_model_container_wrapper || find_helper.previous_space_wrapper) ) { - EvaluateModelField(find_helper); - } - - if( find_helper.nested_calls > max_nested_calls ) - { - return; + if( !EvaluateModelField(find_helper) ) + return; } if( !find_helper.found ) @@ -1855,7 +1900,6 @@ void Generator::EvaluateV if( var ) { - // if a function returns another function we should make CallFunction() again? if( var->type == Var::TYPE_FUNCTION && var->user_function ) { EvaluateFunction(var->user_function, find_helper); @@ -1881,62 +1925,55 @@ void Generator::EvaluateV PrintDate(*var->date, find_helper); } } - - find_helper.previous_result = var ? &find_helper.result : nullptr; } if( find_helper.found ) { - if( find_helper.result.type == Var::Type::TYPE_VOID && !find_helper.result.stream.empty() ) - find_helper.result.type = Var::Type::TYPE_STREAM; - -// if( !find_helper.is_last_field() || find_helper.evaluate_last ) -// { -// -// -// } + if( find_helper.result->type == Var::Type::TYPE_VOID && !find_helper.result->stream.empty() ) + { + find_helper.result->type = Var::Type::TYPE_STREAM; + } } } template -void Generator::EvaluateModelField(FindHelper & find_helper) +bool Generator::EvaluateModelField(FindHelper & find_helper) { //var = find_helper.previous_result->find_child(name); //if( !var ) { - if( find_helper.previous_result->type == Var::TYPE_MODEL ) + if( find_helper.previous_model ) { - find_helper.found = CallModelField(*find_helper.previous_result->model, find_helper); - find_helper.previous_result = find_helper.found ? &find_helper.result : nullptr; + find_helper.found = CallModelField(*find_helper.previous_model, find_helper); } else - if( find_helper.previous_result->type == Var::TYPE_MODEL_CONTAINER_WRAPPER ) + if( find_helper.previous_model_container_wrapper ) { - morm::Model * model = find_helper.previous_result->model_container_wrapper->get_model(); + morm::Model * model = find_helper.previous_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; + find_helper.found = CallModelField(*model, find_helper); } else { // put some log (no [for] statement) // CreateMsg(L"model ", name, fields, L" is not initialized, have you forgotten to use [for ...] statement?"); - return; + find_helper.found = false; + return false; } } if( find_helper.found ) { - if( find_helper.result.type == Var::TYPE_FUNCTION && find_helper.result.user_function ) + if( find_helper.result->type == Var::TYPE_FUNCTION && find_helper.result->user_function ) { - EvaluateFunction(find_helper.result.user_function, find_helper); + EvaluateFunction(find_helper.result->user_function, find_helper); if( !find_helper.found ) - return; // maximum nested calls exceeded + return false; // maximum nested calls exceeded } } } @@ -1945,6 +1982,8 @@ void Generator::EvaluateM // // child found // // } + + return true; } @@ -1960,10 +1999,10 @@ void Generator::EvaluateF CallFunction(user_function, find_helper); find_helper.found = true; - if( find_helper.result.type == Var::TYPE_FUNCTION && find_helper.result.user_function ) + if( find_helper.result->type == Var::TYPE_FUNCTION && find_helper.result->user_function ) { - user_function = find_helper.result.user_function; - find_helper.result.clear(); + user_function = find_helper.result->user_function; + find_helper.result->clear(); find_helper.nested_calls += 1; if( find_helper.nested_calls <= max_nested_calls ) @@ -2094,7 +2133,12 @@ std::vector> parameters; } } - FindHelper find_helper(*name, item_fun.fields, parameters, result); + Var empty_input; // fix me for filters + + FindHelper find_helper(*name, item_fun.fields, parameters); + find_helper.result = &result; + find_helper.input = &empty_input; + FindVariable(find_helper); return find_helper.found; }