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

This commit is contained in:
2024-12-13 15:47:54 +01:00
parent 6f75664400
commit 345e1870e3
6 changed files with 523 additions and 286 deletions

View File

@@ -147,7 +147,7 @@ private:
Val & result,
pt::Stream & out_stream,
const pt::Stream & in_stream) :
item_fun(item_fun), fun_name(fun_name), fields(fields), baseval(baseval), currentval(&baseval),
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
@@ -157,10 +157,22 @@ private:
FindHelper(const FindHelper &) = delete;
// RENAMEME
void set_base_val(Val * val)
{
baseval = val;
currentval = val;
}
void set_base_val(Val & val)
{
set_base_val(&val);
}
Item::Function & item_fun;
const std::wstring & fun_name;
std::vector<std::wstring> & fields;
Val & baseval;
Val * baseval;
Val * currentval;
std::vector<Val> & parameters;
Val & result;
@@ -168,6 +180,20 @@ private:
const pt::Stream & in_stream;
// if:
// field_index == size() - all fields items are either models, models containers, space or a date
// field_index == size()-1 - only the last field is not known
// field_index < size()-1 - there are more not known fields
bool all_fields_known()
{
return (field_index == fields.size());
}
bool last_field_not_known()
{
return (field_index + 1 == fields.size());
}
//std::wstring * fun_name;
//BaseObj * base_obj;
@@ -328,7 +354,8 @@ private:
bool FindInModels(FindHelper & find_helper);
#endif
bool FindInFunctionsAndBlocks(FindHelper & find_helper);
bool FindInFunctions(FindHelper & find_helper);
bool FindInBlocks(FindHelper & find_helper);
bool FindInVariables(FindHelper & find_helper);
bool Find(FindHelper & find_helper);
@@ -338,6 +365,7 @@ private:
void CallFunction(FindHelper & find_helper);
bool CallBlock(FindHelper & find_helper);
bool CallPodType(FindHelper & find_helper);
void CallObject(BaseObj & base_obj, int method_index, Env & info);
@@ -360,7 +388,6 @@ 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 CallModel(FindHelper & find_helper);
bool CallModelContainerWrapper(FindHelper & find_helper);
@@ -380,7 +407,7 @@ private:
// pt::Stream & out_stream,
// const pt::Stream & in_stream);
void PrepareParameters(FindHelper & find_helper);
void EvaluateParameters(FindHelper & find_helper);
bool ReduceFields(FindHelper & find_helper);
bool CallValue(FindHelper & find_helper);
void CleanupParameters(std::vector<Val> & parameters);
@@ -1061,7 +1088,7 @@ bool Generator::CheckBlockArgument(FindHelper & find_helper)
if( size_t(find_helper.item_fun.arg) < block_stack.args.size() )
{
find_helper.baseval.set(block_stack.args[find_helper.item_fun.arg]);
find_helper.set_base_val(block_stack.args[find_helper.item_fun.arg]);
return true;
}
}
@@ -1112,34 +1139,12 @@ bool Generator::FindInModels(FindHelper & find_helper)
if( pmodels )
{
// morm::Wrapper probably will be removed....
morm::Wrapper * m = pmodels->Find(find_helper.fun_name);
Val * val = pmodels->Find(find_helper.fun_name);
if( m )
if( val )
{
if( m->model )
{
find_helper.baseval.set(*m->model);
found = true;
}
else
if( m->model_container_wrapper )
{
find_helper.baseval.set(*m->model_container_wrapper);
found = true;
}
else
if( m->date )
{
find_helper.baseval.set(*m->date);
found = true;
}
else
if( m->space_wrapper )
{
find_helper.baseval.set(*m->space_wrapper);
found = true;
}
find_helper.set_base_val(val);
found = true;
}
}
@@ -1150,47 +1155,40 @@ bool Generator::FindInModels(FindHelper & find_helper)
// IMPROVEME split me into two functions
bool Generator::FindInFunctionsAndBlocks(FindHelper & find_helper)
bool Generator::FindInFunctions(FindHelper & find_helper)
{
// Objects will be removed in the future
// if( pobjects )
// {
// typename Objects::Iterator i = pobjects->Find(name, find_helper.method_index);
// if( i != pobjects->End() )
// {
// find_helper.base_obj = *i;
// return true;
// }
// }
if( pfunctions )
{
typename Functions::Iterator i = pfunctions->Find(find_helper.fun_name);
if( i != pfunctions->End() )
{
find_helper.baseval.set(i->second);
find_helper.baseval->set(i->second);
return true;
}
}
return false;
}
bool Generator::FindInBlocks(FindHelper & find_helper)
{
if( pblocks )
{
Blocks::Iterator i = pblocks->Find(find_helper.fun_name);
if( i != pblocks->End() )
{
find_helper.baseval.set(i->second);
find_helper.baseval->set_pointer_to(&i->second);
return true;
}
}
return false;
return false;
}
bool Generator::FindInVariables(FindHelper & find_helper)
{
if( pvals )
@@ -1199,7 +1197,7 @@ bool Generator::FindInVariables(FindHelper & find_helper)
if( i != pvals->end() )
{
find_helper.baseval.set(i->second);
find_helper.set_base_val(i->second);
return true;
}
}
@@ -1237,7 +1235,10 @@ bool Generator::Find(FindHelper & find_helper)
// if( FindInCache(item_fun, find_helper) )
// return true;
if( FindInFunctionsAndBlocks(find_helper) )
if( FindInFunctions(find_helper) )
return true;
if( FindInBlocks(find_helper) )
return true;
if( FindInVariables(find_helper) )
@@ -1281,10 +1282,10 @@ void Generator::CallFunction(FindHelper & find_helper)
{
if( !IsTestingFunctionExistence() )
{
if( find_helper.baseval.type == Val::TYPE_FUNCTION && find_helper.baseval.pointer )
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);
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);
@@ -1479,9 +1480,9 @@ bool Generator::CallDate(FindHelper & find_helper)
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 )
if( find_helper.currentval->type == Val::TYPE_DATE && find_helper.currentval->pointer )
{
date = reinterpret_cast<pt::Date*>(find_helper.baseval.pointer);
date = reinterpret_cast<pt::Date*>(find_helper.currentval->pointer);
}
if( all_fields_known )
@@ -1648,7 +1649,7 @@ void Generator::PrintLastSpaceField(FindHelper & find_helper, pt::Space * space)
bool Generator::CallSpace(FindHelper & find_helper)
{
morm::SpaceWrapper * space_wrapper = reinterpret_cast<morm::SpaceWrapper*>(find_helper.baseval.pointer);
morm::SpaceWrapper * space_wrapper = reinterpret_cast<morm::SpaceWrapper*>(find_helper.currentval->pointer);
pt::Space * space = space_wrapper->get_space();
//last_res = false;
size_t field_index = find_helper.field_index;
@@ -1771,6 +1772,12 @@ bool Generator::CallModelField(FindHelper & find_helper, morm::Model & model)
found = model.get_raw_value(nullptr, field.c_str(), nullptr, env, find_helper.out_stream, false);
}
if( found )
{
// set type to TYPE_OUTPUT_STREAM?
// find_helper.result.type ==
}
return found;
}
@@ -1820,26 +1827,6 @@ 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.currentval->has_model_object() ; ++find_helper.field_index)
@@ -1868,16 +1855,11 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper)
if( model )
{
// IMPROVEME improve the morm library
// return a Val instead of a Wrapper
morm::Wrapper new_wrapper = model->get_wrapper(nullptr, field.c_str());
Val val = model->get_ezc_val(nullptr, field.c_str());
if( new_wrapper.has_object() )
if( val.has_object() )
{
Val child = WrapperToVal(new_wrapper);
if( child.type != Val::TYPE_VOID )
child_wrapper = find_helper.currentval->add_child(field, child);
child_wrapper = find_helper.currentval->add_child(field, val);
}
}
}
@@ -1885,8 +1867,8 @@ void Generator::FindLastModelWrapper(FindHelper & find_helper)
if( !child_wrapper )
break;
//find_helper.wrapper = child_wrapper;
find_helper.currentval = child_wrapper;
find_helper.currentval->set_output_stream(find_helper.out_stream);
}
}
@@ -1904,14 +1886,6 @@ bool Generator::CallModelContainerWrapper(FindHelper & find_helper)
bool found = true;
//last_res = false;
// 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
// helper.field_index < fields.size()-1 - there are more not known fields
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());
morm::ModelContainerWrapper * model_container_wrapper = reinterpret_cast<morm::ModelContainerWrapper*>(find_helper.currentval->pointer);
morm::Model * model = model_container_wrapper->get_model();
@@ -1921,7 +1895,7 @@ bool Generator::CallModelContainerWrapper(FindHelper & find_helper)
}
else
{
if( last_field_not_known )
if( find_helper.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?");
@@ -1929,18 +1903,20 @@ bool Generator::CallModelContainerWrapper(FindHelper & find_helper)
}
}
if( all_fields_known )
if( find_helper.all_fields_known() )
{
if( is_generating_for )
{
model_container_wrapper->increment_iterator();
find_helper.currentval->clear_childs(); // or current?
find_helper.currentval->clear_childs();
find_helper.result.set(model_container_wrapper->is_iterator_correct());
//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();
find_helper.result.set(model_container_wrapper->is_container_empty());
}
}
@@ -1989,7 +1965,7 @@ bool Generator::CallBlock(FindHelper & find_helper)
ClearStream(*output_stream);
block_stack_index += 1;
Item * item_block = reinterpret_cast<Item*>(find_helper.baseval.pointer);
Item * item_block = reinterpret_cast<Item*>(find_helper.currentval->pointer);
MakeText(*item_block);
//CopyStream(*output_stream, find_helper.out_stream);
@@ -2025,19 +2001,33 @@ bool Generator::CallBlock(FindHelper & find_helper)
// }
void Generator::PrepareParameters(FindHelper & find_helper)
bool Generator::CallPodType(FindHelper & find_helper)
{
if( !IsTestingFunctionExistence() )
{
find_helper.currentval->put_pod_type_to_stream();
}
return true;
}
void Generator::EvaluateParameters(FindHelper & find_helper)
{
find_helper.parameters.resize(find_helper.item_fun.parameters.size());
for(size_t i=0 ; i < find_helper.item_fun.parameters.size() ; ++i)
{
// IMPROVEME use a pooler of streams?
find_helper.parameters[i].set_output_stream(main_stream->new_empty());
pt::Stream * tmp_stream = main_stream->new_empty();
tmp_stream->escape_input(true);
find_helper.parameters[i].set_output_stream(tmp_stream);
Item::Function & fun_child = *find_helper.item_fun.parameters[i];
if( fun_child.is_function )
{
Call(fun_child, nullptr, find_helper.parameters[i], *find_helper.parameters[i].output_stream, *empty_stream);
Call(fun_child, nullptr, find_helper.parameters[i], *tmp_stream, *empty_stream);
//CopyStreamToString(*local_temp_stream, parameters[i].str);
//parameters[i].res = last_res;
@@ -2056,7 +2046,9 @@ void Generator::PrepareParameters(FindHelper & find_helper)
// give me a better name
bool Generator::ReduceFields(FindHelper & find_helper)
{
if( find_helper.baseval.has_model_object() )
bool reduced = true;
if( find_helper.baseval->has_model_object() )
{
#ifdef EZC_HAS_MORM_LIBRARY
FindLastModelWrapper(find_helper);
@@ -2074,23 +2066,23 @@ bool Generator::ReduceFields(FindHelper & find_helper)
bool Generator::CallValue(FindHelper & find_helper)
{
if( find_helper.baseval.pointer && find_helper.currentval->pointer )
if( find_helper.baseval->pointer && find_helper.currentval->pointer )
{
#ifdef EZC_HAS_MORM_LIBRARY
if( find_helper.baseval.type == Val::TYPE_MODEL )
if( find_helper.currentval->type == Val::TYPE_MODEL )
{
//return CallWrapper(find_helper);
return CallModel(find_helper);
}
else
if( find_helper.baseval.type == Val::TYPE_MODEL_CONTAINER_WRAPPER )
if( find_helper.currentval->type == Val::TYPE_MODEL_CONTAINER_WRAPPER )
return CallModelContainerWrapper(find_helper);
else
if( find_helper.baseval.type == Val::TYPE_DATE )
if( find_helper.currentval->type == Val::TYPE_DATE )
//return CallWrapper(find_helper);
return CallDate(find_helper);
else
if( find_helper.baseval.type == Val::TYPE_SPACE_WRAPPER )
if( find_helper.currentval->type == Val::TYPE_SPACE_WRAPPER )
return CallSpace(find_helper);
//return CallWrapper(find_helper);
else
@@ -2098,17 +2090,19 @@ bool Generator::CallValue(FindHelper & find_helper)
// 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 )
if( find_helper.currentval->type == Val::TYPE_FUNCTION )
{
CallFunction(find_helper);
return true;
}
else
if( find_helper.baseval.type == Val::TYPE_ITEM_BLOCK )
if( find_helper.currentval->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);
if( find_helper.currentval->has_pod_type() )
return CallPodType(find_helper);
}
return false;
@@ -2139,7 +2133,7 @@ bool Generator::Call(Item::Function & item_fun,
pt::Stream & out_stream,
const pt::Stream & in_stream)
{
Val current;
Val current(&out_stream);
std::vector<Val> parameters;
if( !fun_name )
@@ -2151,14 +2145,12 @@ bool Generator::Call(Item::Function & item_fun,
// if( clear_out_stream )
// ClearStream(out_stream);
// if constexpr(is_autoescape_stream)
// out_stream.Escape(true);
//out_stream.escape_input(true);
if( !Find(find_helper) )
return false;
PrepareParameters(find_helper);
out_stream.escape_input(true);
EvaluateParameters(find_helper);
ReduceFields(find_helper);
bool status = false;
@@ -2681,7 +2673,7 @@ void Generator::MakeTextIf(Item & item)
return;
}
MakeTextIf_go(item, result.to_bool());
MakeTextIf_go(item, result.to_bool(false));
}
@@ -2754,7 +2746,7 @@ void Generator::MakeTextFor(Item & item)
return;
}
if( !result.to_bool() )
if( !result.to_bool(true) )
break;
if( !item.item_tab.empty() )