WIP: add a Val struct as an input/output when calling a function
This commit is contained in:
226
src/generator.h
226
src/generator.h
@@ -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() )
|
||||
|
Reference in New Issue
Block a user