WIP: add a Val struct as an input/output when calling a function

This commit is contained in:
2024-12-12 17:57:24 +01:00
parent 0ac4df97e9
commit 6f75664400
4 changed files with 503 additions and 279 deletions

View File

@@ -142,12 +142,13 @@ private:
Item::Function & item_fun,
const std::wstring & fun_name,
std::vector<std::wstring> & fields,
Val & current,
Val & baseval,
std::vector<Val> & parameters,
Val & result,
pt::Stream & out_stream,
const pt::Stream & in_stream) :
item_fun(item_fun), fun_name(fun_name), fields(fields), current(current), parameters(parameters), result(result), out_stream(out_stream), in_stream(in_stream)
item_fun(item_fun), fun_name(fun_name), fields(fields), baseval(baseval), currentval(&baseval),
parameters(parameters), result(result), out_stream(out_stream), in_stream(in_stream)
{
#ifdef EZC_HAS_MORM_LIBRARY
field_index = 0;
@@ -159,7 +160,8 @@ private:
Item::Function & item_fun;
const std::wstring & fun_name;
std::vector<std::wstring> & fields;
Val & current;
Val & baseval;
Val * currentval;
std::vector<Val> & parameters;
Val & result;
pt::Stream & out_stream;
@@ -358,8 +360,10 @@ private:
#ifdef EZC_HAS_MORM_LIBRARY
bool CallModelField(FindHelper & find_helper, morm::Model & model);
bool CallModel(FindHelper & find_helper, morm::Model & model);
Val WrapperToVal(morm::Wrapper & wrapper);
void FindLastModelWrapper(FindHelper & find_helper);
bool CallWrapper(FindHelper & find_helper);
bool CallModel(FindHelper & find_helper);
bool CallModelContainerWrapper(FindHelper & find_helper);
#endif
void CallObject(BaseObj & base_obj,
@@ -376,7 +380,7 @@ private:
// pt::Stream & out_stream,
// const pt::Stream & in_stream);
bool PrepareParameters(FindHelper & find_helper);
void PrepareParameters(FindHelper & find_helper);
bool ReduceFields(FindHelper & find_helper);
bool CallValue(FindHelper & find_helper);
void CleanupParameters(std::vector<Val> & parameters);
@@ -1057,7 +1061,7 @@ bool Generator::CheckBlockArgument(FindHelper & find_helper)
if( size_t(find_helper.item_fun.arg) < block_stack.args.size() )
{
find_helper.current.set(block_stack.args[find_helper.item_fun.arg]);
find_helper.baseval.set(block_stack.args[find_helper.item_fun.arg]);
return true;
}
}
@@ -1115,25 +1119,25 @@ bool Generator::FindInModels(FindHelper & find_helper)
{
if( m->model )
{
find_helper.current.set(*m->model);
find_helper.baseval.set(*m->model);
found = true;
}
else
if( m->model_container_wrapper )
{
find_helper.current.set(*m->model_container_wrapper);
find_helper.baseval.set(*m->model_container_wrapper);
found = true;
}
else
if( m->date )
{
find_helper.current.set(*m->date);
find_helper.baseval.set(*m->date);
found = true;
}
else
if( m->space_wrapper )
{
find_helper.current.set(*m->space_wrapper);
find_helper.baseval.set(*m->space_wrapper);
found = true;
}
}
@@ -1166,7 +1170,7 @@ bool Generator::FindInFunctionsAndBlocks(FindHelper & find_helper)
if( i != pfunctions->End() )
{
find_helper.current.set(i->second);
find_helper.baseval.set(i->second);
return true;
}
}
@@ -1177,7 +1181,7 @@ bool Generator::FindInFunctionsAndBlocks(FindHelper & find_helper)
if( i != pblocks->End() )
{
find_helper.current.set(i->second);
find_helper.baseval.set(i->second);
return true;
}
}
@@ -1195,7 +1199,7 @@ bool Generator::FindInVariables(FindHelper & find_helper)
if( i != pvals->end() )
{
find_helper.current.set(i->second);
find_helper.baseval.set(i->second);
return true;
}
}
@@ -1277,8 +1281,14 @@ void Generator::CallFunction(FindHelper & find_helper)
{
if( !IsTestingFunctionExistence() )
{
Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(find_helper.current.user_function, env);
if( find_helper.baseval.type == Val::TYPE_FUNCTION && find_helper.baseval.pointer )
{
using UserFunction = void (*)(Env &);
UserFunction user_function = reinterpret_cast<UserFunction>(find_helper.baseval.pointer);
Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(user_function, env);
}
}
}
@@ -1295,15 +1305,10 @@ bool Generator::HasParam(std::vector<Val> & parameters, const wchar_t * param1,
{
for(Val & val : parameters)
{
/*
if( !val.is_function )
if( val.is_equal_string(param1) || (param2 && val.is_equal_string(param2)) )
{
if( val.str == param1 || (param2 && val.str == param2) )
{
return true;
}
return true;
}
*/
}
return false;
@@ -1375,7 +1380,7 @@ void Generator::DumpModelIfNeeded(FindHelper & find_helper, morm::Model & model)
// pt::TextStream temp_str;
// model.to_text(temp_str, false, false);
// find_helper.out_stream << temp_str;
model.to_text(find_helper.out_stream);
model.to_text(find_helper.out_stream, false, false);
}
}
}
@@ -1472,23 +1477,35 @@ bool Generator::CallDate(FindHelper & find_helper)
bool found = true;
bool all_fields_known = (find_helper.field_index == find_helper.fields.size());
bool last_field_not_known = (find_helper.field_index + 1 == find_helper.fields.size());
pt::Date * date = nullptr;
if( find_helper.baseval.type == Val::TYPE_DATE && find_helper.baseval.pointer )
{
date = reinterpret_cast<pt::Date*>(find_helper.baseval.pointer);
}
if( all_fields_known )
{
PrintDate(find_helper, find_helper.current.date);
if( date )
{
PrintDate(find_helper, date);
}
}
else
if( last_field_not_known )
{
if( !PrintDatePart(find_helper, find_helper.current.date) )
if( date )
{
if( !IsTestingFunctionExistence() )
if( !PrintDatePart(find_helper, date) )
{
CreateMsg(L"cannot find ", find_helper.fun_name, find_helper.fields, L", unknown property ",
find_helper.fields[find_helper.field_index].c_str(), L" of a Date object");
}
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find ", find_helper.fun_name, find_helper.fields, L", unknown property ",
find_helper.fields[find_helper.field_index].c_str(), L" of a Date object");
}
found = false;
found = false;
}
}
}
else
@@ -1551,7 +1568,7 @@ void Generator::CallSpaceTableForLastField(
// we are in [for...]statement, increment iterator and check the range
space_wrapper.increment_iterator(model_wrapper_space_table_index, table->size());
space_wrapper.invalidate_iterators(model_wrapper_space_table_index + 1);
size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
//size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
//last_res = (iterator_value < table->size());
}
else
@@ -1631,7 +1648,7 @@ void Generator::PrintLastSpaceField(FindHelper & find_helper, pt::Space * space)
bool Generator::CallSpace(FindHelper & find_helper)
{
morm::SpaceWrapper * space_wrapper = find_helper.current.space_wrapper;
morm::SpaceWrapper * space_wrapper = reinterpret_cast<morm::SpaceWrapper*>(find_helper.baseval.pointer);
pt::Space * space = space_wrapper->get_space();
//last_res = false;
size_t field_index = find_helper.field_index;
@@ -1733,16 +1750,11 @@ bool Generator::CallSpace(FindHelper & find_helper)
bool Generator::CallModelField(FindHelper & find_helper, morm::Model & model)
{
const std::wstring & field = find_helper.fields[find_helper.field_index];
/*
* if 'field' is a POD type then 'str' will be used in get_raw_value()
* if 'field' is a getter method with pt::Stream then 'str' will be used too
* if 'field' is a getter method which takes FunInfo<> then out_stream will be used and 'str' will be empty
*
*/
pt::WTextStream str;
bool found = false;
const std::wstring & field = find_helper.fields[find_helper.field_index];
bool no_escape = HasParam(find_helper.parameters, L"raw", L"noescape");
find_helper.result.output_stream->escape_input(!no_escape);
if( find_helper.parameters.empty() )
{
@@ -1750,21 +1762,13 @@ bool Generator::CallModelField(FindHelper & find_helper, morm::Model & model)
Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
PrepareEnvStruct(env);
found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, str, false);
//last_res = env.res;
found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, find_helper.out_stream, false);
}
else
{
Env env(find_helper.out_stream, find_helper.parameters, find_helper.result, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
PrepareEnvStruct(env);
found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, str, false);
//last_res = env.res;
}
if( found && !str.empty())
{
bool no_escape = HasParam(find_helper.parameters, L"raw", L"noescape");
CopyStream(str, find_helper.out_stream, !no_escape);
found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, find_helper.out_stream, false);
}
return found;
@@ -1816,28 +1820,50 @@ bool Generator::CallModel(FindHelper & find_helper, morm::Model & model)
}
Val Generator::WrapperToVal(morm::Wrapper & wrapper)
{
Val child(output_stream);
if( wrapper.model )
child.set(*wrapper.model);
else
if( wrapper.model_container_wrapper )
child.set(*wrapper.model_container_wrapper);
else
if( wrapper.space_wrapper )
child.set(*wrapper.space_wrapper);
else
if( wrapper.date )
child.set(*wrapper.date);
return child;
}
void Generator::FindLastModelWrapper(FindHelper & find_helper)
{
for(find_helper.field_index = 0 ; find_helper.field_index < find_helper.fields.size() && find_helper.current.has_model_object() ; ++find_helper.field_index)
for(find_helper.field_index = 0 ; find_helper.field_index < find_helper.fields.size() && find_helper.currentval->has_model_object() ; ++find_helper.field_index)
{
std::wstring & field = find_helper.fields[find_helper.field_index];
Val * child_wrapper = find_helper.current.find_child(field);
Val * child_wrapper = find_helper.currentval->find_child(field);
if( !child_wrapper )
{
morm::Model * model = nullptr;
if( find_helper.current.type == Val::TYPE_MODEL && find_helper.current.model )
if( find_helper.currentval->pointer )
{
model = find_helper.current.model;
}
else
if( find_helper.current.type == Val::TYPE_MODEL_CONTAINER_WRAPPER && find_helper.current.model_container_wrapper )
{
model = find_helper.current.model_container_wrapper->get_model();
// this can return null for lists/vectors in a case when the iterator is not pointing to a valid item
if( find_helper.currentval->type == Val::TYPE_MODEL )
{
model = reinterpret_cast<morm::Model*>(find_helper.currentval->pointer);
}
else
if( find_helper.currentval->type == Val::TYPE_MODEL_CONTAINER_WRAPPER )
{
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(find_helper.currentval->pointer);
model = model_container_wrapper->get_model();
// this can return null for lists/vectors in a case when the iterator is not pointing to a valid item
}
}
if( model )
@@ -1848,24 +1874,10 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper)
if( new_wrapper.has_object() )
{
//child_wrapper = find_helper.wrapper->add_child(field, new_wrapper);
Val child;
if( new_wrapper.model )
child.set(model);
else
if( new_wrapper.model_container_wrapper )
child.set(new_wrapper.model_container_wrapper);
else
if( new_wrapper.space_wrapper )
child.set(new_wrapper.space_wrapper);
else
if( new_wrapper.date )
child.set(new_wrapper.date);
Val child = WrapperToVal(new_wrapper);
if( child.type != Val::TYPE_VOID )
child_wrapper = find_helper.current.add_child(field, child);
child_wrapper = find_helper.currentval->add_child(field, child);
}
}
}
@@ -1874,21 +1886,24 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper)
break;
//find_helper.wrapper = child_wrapper;
find_helper.current.set(*child_wrapper);
find_helper.currentval = child_wrapper;
}
}
bool Generator::CallModel(FindHelper & find_helper)
{
morm::Model * model = reinterpret_cast<morm::Model*>(find_helper.currentval->pointer);
return CallModel(find_helper, *model);
}
bool Generator::CallWrapper(FindHelper & find_helper)
bool Generator::CallModelContainerWrapper(FindHelper & find_helper)
{
bool found = true;
//last_res = false;
// this should be moved to Reduce() method
// and here should be only a calling
FindLastModelWrapper(find_helper);
// if:
// helper.field_index == fields.size() - all fields items are either models, models containers, space or a date
// helper.field_index == fields.size()-1 - only the last field is not known
@@ -1897,52 +1912,35 @@ bool Generator::CallWrapper(FindHelper & find_helper)
bool all_fields_known = (find_helper.field_index == find_helper.fields.size());
bool last_field_not_known = (find_helper.field_index + 1 == find_helper.fields.size());
if( find_helper.current.space_wrapper )
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(find_helper.currentval->pointer);
morm::Model * model = model_container_wrapper->get_model();
if( model )
{
found = CallSpace(find_helper);
found = CallModel(find_helper, *model);
}
if( find_helper.current.date )
else
{
found = CallDate(find_helper);
}
if( find_helper.current.model )
{
found = CallModel(find_helper, *find_helper.current.model);
}
if( find_helper.current.model_container_wrapper )
{
morm::Model * model = find_helper.current.model_container_wrapper->get_model();
if( model )
if( last_field_not_known )
{
found = CallModel(find_helper, *model);
// can be printed even for [if-def...]
CreateMsg(L"model ", find_helper.fun_name, find_helper.fields, L" is not initialized, have you forgotten to use [for ...] statement?");
found = false;
}
}
if( all_fields_known )
{
if( is_generating_for )
{
model_container_wrapper->increment_iterator();
find_helper.currentval->clear_childs(); // or current?
//last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct();
}
else
{
if( last_field_not_known )
{
// can be printed even for [if-def...]
CreateMsg(L"model ", find_helper.fun_name, find_helper.fields, L" is not initialized, have you forgotten to use [for ...] statement?");
found = false;
}
}
if( all_fields_known )
{
if( is_generating_for )
{
find_helper.current.model_container_wrapper->increment_iterator();
find_helper.current.clear_childs();
//last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct();
}
else
{
// for [if-def...] last_res will be set later
//last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty();
}
// for [if-def...] last_res will be set later
//last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty();
}
}
@@ -1991,10 +1989,11 @@ bool Generator::CallBlock(FindHelper & find_helper)
ClearStream(*output_stream);
block_stack_index += 1;
MakeText(*find_helper.current.item_block);
Item * item_block = reinterpret_cast<Item*>(find_helper.baseval.pointer);
MakeText(*item_block);
//CopyStream(*output_stream, find_helper.out_stream);
// last_res is set by [return ...] statement or other last evaluated function
// last_res is set by [return ...] statement or other last evaluated function IMPROVE ME now it is changed?
ClearStream(*output_stream);
output_stream = old_stream;
@@ -2026,7 +2025,7 @@ bool Generator::CallBlock(FindHelper & find_helper)
// }
bool Generator::PrepareParameters(FindHelper & find_helper)
void Generator::PrepareParameters(FindHelper & find_helper)
{
find_helper.parameters.resize(find_helper.item_fun.parameters.size());
@@ -2053,43 +2052,66 @@ bool Generator::PrepareParameters(FindHelper & find_helper)
}
// give me a better name
bool Generator::ReduceFields(FindHelper & find_helper)
{
if( find_helper.baseval.has_model_object() )
{
#ifdef EZC_HAS_MORM_LIBRARY
FindLastModelWrapper(find_helper);
#endif
}
else
{
// space ?
}
return true;
}
bool Generator::CallValue(FindHelper & find_helper)
{
#ifdef EZC_HAS_MORM_LIBRARY
if( find_helper.current.type == Val::TYPE_MODEL && find_helper.current.model )
return CallWrapper(find_helper);
else
if( find_helper.current.type == Val::TYPE_MODEL_CONTAINER_WRAPPER && find_helper.current.model_container_wrapper )
return CallWrapper(find_helper);
else
if( find_helper.current.type == Val::TYPE_DATE && find_helper.current.date )
return CallWrapper(find_helper);
else
if( find_helper.current.type == Val::TYPE_SPACE_WRAPPER && find_helper.current.space_wrapper )
return CallWrapper(find_helper);
else
#endif
// if( find_helper.base_obj ) // OBJECTS WILL BE REMOVED
// CallObject(*find_helper.base_obj, find_helper.method_index, parameters, result, out_stream, in_stream);
//else
if( find_helper.current.type == Val::TYPE_FUNCTION && find_helper.current.user_function )
CallFunction(find_helper);
else
if( find_helper.current.type == Val::TYPE_ITEM_BLOCK && find_helper.current.item_block )
return CallBlock(find_helper); // result?
// else
// if( find_helper.variable )
// return CallVariable(item_fun, *find_helper.variable, parameters, result, out_stream, in_stream);
if( find_helper.baseval.pointer && find_helper.currentval->pointer )
{
#ifdef EZC_HAS_MORM_LIBRARY
if( find_helper.baseval.type == Val::TYPE_MODEL )
{
//return CallWrapper(find_helper);
return CallModel(find_helper);
}
else
if( find_helper.baseval.type == Val::TYPE_MODEL_CONTAINER_WRAPPER )
return CallModelContainerWrapper(find_helper);
else
if( find_helper.baseval.type == Val::TYPE_DATE )
//return CallWrapper(find_helper);
return CallDate(find_helper);
else
if( find_helper.baseval.type == Val::TYPE_SPACE_WRAPPER )
return CallSpace(find_helper);
//return CallWrapper(find_helper);
else
#endif
// if( find_helper.base_obj ) // OBJECTS WILL BE REMOVED
// CallObject(*find_helper.base_obj, find_helper.method_index, parameters, result, out_stream, in_stream);
//else
if( find_helper.baseval.type == Val::TYPE_FUNCTION )
{
CallFunction(find_helper);
return true;
}
else
if( find_helper.baseval.type == Val::TYPE_ITEM_BLOCK )
return CallBlock(find_helper);
// else
// if( find_helper.variable )
// return CallVariable(item_fun, *find_helper.variable, parameters, result, out_stream, in_stream);
}
return false;
}
@@ -2133,7 +2155,6 @@ bool Generator::Call(Item::Function & item_fun,
// out_stream.Escape(true);
//out_stream.escape_input(true);
if( !Find(find_helper) )
return false;
@@ -2608,6 +2629,7 @@ void Generator::MakeTextFunction(Item & item)
// does we need both seperate: result and output_stream?
if( Call(item.function, nullptr, result, *output_stream, *empty_stream) )
{
output_stream->escape_input(true);
result.serialize_to(*output_stream);
}
}