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

This commit is contained in:
2025-01-15 09:19:24 +01:00
parent dc2ee61a23
commit ec45ae971e
3 changed files with 282 additions and 55 deletions

View File

@@ -366,9 +366,13 @@ private:
void PrepareEnvStruct(Env & env);
void CallFunction(typename Functions::UserFunction & function, Env & env);
void CallFunction(Functions::UserFunction & function, Env & env);
void CallFunction(FindHelper & find_helper);
void CallMethod(morm::Model * model, Val::ModelMethod1 method, Env & env);
void CallMethod(morm::Model * model, Val::ModelMethod2 method, Val & res);
bool CallMethod(morm::Model * model, Val::ModelMethod3 method);
bool CallBlock(FindHelper & find_helper);
bool CallPodType(FindHelper & find_helper);
@@ -394,11 +398,14 @@ private:
#ifdef EZC_HAS_MORM_LIBRARY
bool CallModelField(FindHelper & find_helper, morm::Model & model);
bool CallModel(FindHelper & find_helper, morm::Model & model);
void FindLastModelWrapper(FindHelper & find_helper);
bool FindLastModelWrapper(FindHelper & find_helper);
bool CallModel(FindHelper & find_helper);
bool CallModelContainerWrapper(FindHelper & find_helper);
#endif
bool EvaluateFunctionOrMethod(pt::Stream & out_stream, Val & val, Val & result);
bool ReduceFields(FindHelper & find_helper);
void CallObject(BaseObj & base_obj,
int method_index,
std::vector<Val> & parameters,
@@ -414,7 +421,7 @@ private:
// const pt::Stream & in_stream);
void EvaluateParameters(FindHelper & find_helper);
bool ReduceFields(FindHelper & find_helper);
bool Evaluate(FindHelper & find_helper);
bool CallValue(FindHelper & find_helper);
void CleanupParameters(std::vector<Val> & parameters);
@@ -1277,11 +1284,10 @@ void Generator::PrepareEnvStruct(Env & env)
void Generator::CallFunction(typename Functions::UserFunction & function, Env & env)
void Generator::CallFunction(Functions::UserFunction & function, Env & env)
{
PrepareEnvStruct(env);
(function)(env);
//last_res = env.res;
}
@@ -1301,6 +1307,26 @@ void Generator::CallFunction(FindHelper & find_helper)
}
void Generator::CallMethod(morm::Model * model, Val::ModelMethod1 method, Env & env)
{
PrepareEnvStruct(env);
(model->*method)(env);
}
void Generator::CallMethod(morm::Model * model, Val::ModelMethod2 method, Val & res)
{
res.clear();
(model->*method)(res);
}
bool Generator::CallMethod(morm::Model * model, Val::ModelMethod3 method)
{
return (model->*method)();
}
void Generator::CallObject(BaseObj & base_obj, int method_index, Env & info)
{
PrepareEnvStruct(info);
@@ -1839,48 +1865,188 @@ bool Generator::CallModel(FindHelper & find_helper, morm::Model & model)
}
void Generator::FindLastModelWrapper(FindHelper & find_helper)
Val * Generator::FindLastModelWrapperEvaluateMiddleFunction(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)
}
Val * Generator::FindLastModelWrapperEvalueateMiddleModel(FindHelper & find_helper)
{
Val * child_val = nullptr;
morm::Model * model = nullptr;
std::wstring & field = find_helper.fields[find_helper.field_index];
if( find_helper.currentval->pointer )
{
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 )
{
Val val = model->get_ezc_val(nullptr, field.c_str());
if( val.has_object() )
{
child_val = find_helper.currentval->add_child(field, val);
}
}
return child_val;
}
Val * Generator::FindLastModelWrapperEvalueateFunctionsRenameMe(FindHelper & find_helper, Val * child_val)
{
std::wstring & field = find_helper.fields[find_helper.field_index];
size_t function_call_limit = 2; // set me to 16;
size_t current_call = 1;
Val val;
while( child_val && child_val->has_function() )
{
if( current_call > function_call_limit )
{
// IMPROVEME put some error msg
return nullptr;
}
Val::UserFunction function = reinterpret_cast<Val::UserFunction>(child_val->pointer);
val.clear();
val.set_output_stream(&find_helper.out_stream);
// a current find_helper.in_stream used here? or rather an empty_stream of some kind?
Env env(find_helper.out_stream, find_helper.parameters, val, find_helper.in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, env);
child_val = &val;
current_call += 1;
}
child_val = find_helper.currentval->add_child(field, val);
return child_val;
}
bool Generator::EvaluateFunctionOrMethod(pt::Stream & out_stream, Val & val, Val & result)
{
size_t max_calls = 2; // change me to something reasnoable
size_t current_call = 1;
std::vector<Val> no_parameters; // make me some kind of a static
Val * current_val = &val;
result.clear();
result.set_output_stream(out_stream);
while( current_val->has_function() || current_val->has_method() )
{
if( current_call > max_calls )
{
// put some error msg
return false;
}
if( current_val->has_function() )
{
Val::UserFunction function = reinterpret_cast<Val::UserFunction>(current_val->pointer);
Env env(out_stream, no_parameters, result, *empty_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, env);
}
#ifdef EZC_HAS_MORM_LIBRARY
else
if( current_val->has_method() )
{
morm::Model * model = reinterpret_cast<morm::Model*>(current_val->pointer);
if( current_val->model_method1 )
{
Val::ModelMethod1 method = current_val->model_method1; // current_val can point to result so copy the value (Env cctor calls a clear() method on the result)
Env env(out_stream, no_parameters, result, *empty_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallMethod(model, method, env);
}
else
if( current_val->model_method2 )
{
Val::ModelMethod2 method = current_val->model_method2;
CallMethod(model, method, result);
}
else
if( current_val->model_method3 )
{
bool res = CallMethod(model, current_val->model_method3);
result.set(res);
}
}
#endif
current_val = &result;
current_call += 1;
}
return true;
}
// may we should return a bool value?
bool Generator::FindLastModelWrapper(FindHelper & find_helper)
{
find_helper.field_index = 0;
Val res(&find_helper.out_stream);
if( !EvaluateFunctionOrMethod(find_helper.out_stream, *find_helper.currentval, res) )
{
return false;
}
while( find_helper.field_index < find_helper.fields.size() &&
(find_helper.currentval->has_function() || find_helper.currentval->has_method() || find_helper.currentval->has_model_object()) )
{
std::wstring & field = find_helper.fields[find_helper.field_index];
Val * child_wrapper = find_helper.currentval->find_child(field);
Val * child_val = find_helper.currentval->find_child(field);
if( !child_wrapper )
if( !child_val )
{
morm::Model * model = nullptr;
Val val(&find_helper.out_stream);
if( find_helper.currentval->pointer )
//if( find_helper.currentval->has_function() || find_helper.currentval->has_method() )
if( find_helper.currentval->has_function() )
{
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
}
child_val = FindLastModelWrapperEvaluateMiddleFunction(find_helper);
}
else
if( find_helper.currentval->has_model_object() )
{
child_val = FindLastModelWrapperEvalueateMiddleModel(find_helper, val);
}
if( model )
if( find_helper.field_index + 1 < find_helper.fields.size() )
{
Val val = model->get_ezc_val(nullptr, field.c_str());
if( val.has_object() )
if( child_val && child_val->has_function() )
{
child_wrapper = find_helper.currentval->add_child(field, val);
child_val = FindLastModelWrapperEvalueateFunctionsRenameMe(find_helper, child_val);
}
}
}
if( !child_wrapper )
if( !child_val )
break;
find_helper.currentval = child_wrapper;
find_helper.currentval = child_val;
find_helper.currentval->set_output_stream(find_helper.out_stream);
find_helper.field_index += 1;
}
}
@@ -1941,6 +2107,18 @@ bool Generator::CallModelContainerWrapper(FindHelper & find_helper)
// give me a better name
bool Generator::ReduceFields(FindHelper & find_helper)
{
bool reduced = true;
#ifdef EZC_HAS_MORM_LIBRARY
reduced = FindLastModelWrapper(find_helper);
#endif
return reduced;
}
void Generator::CallObject(BaseObj & base_obj,
int method_index,
@@ -2057,22 +2235,15 @@ void Generator::EvaluateParameters(FindHelper & find_helper)
// give me a better name
bool Generator::ReduceFields(FindHelper & find_helper)
// i cos takiego bedzie wykorzystane przy aliasach
// tylko tam evaluujemy od pierwszego parametru dopiero
bool Generator::Evaluate(FindHelper & find_helper)
{
bool reduced = true;
if( find_helper.baseval->has_model_object() )
{
#ifdef EZC_HAS_MORM_LIBRARY
FindLastModelWrapper(find_helper);
#endif
}
else
{
// space ?
}
if( !Find(find_helper) )
return false;
EvaluateParameters(find_helper);
ReduceFields(find_helper);
return true;
}
@@ -2140,7 +2311,6 @@ void Generator::CleanupParameters(std::vector<Val> & parameters)
}
/*
* fun_name can be null, it is used only with [let ...] statements
* and if not null then means: as a funcion name we are not using item_fun.name but fun_name
@@ -2171,8 +2341,10 @@ bool Generator::Call(Item::Function & item_fun,
out_stream.escape_input(true);
if( !ReduceFields(find_helper) )
return false;
EvaluateParameters(find_helper);
ReduceFields(find_helper);
bool status = false;
try

View File

@@ -152,18 +152,10 @@ void Val::initialize_empty()
{
type = TYPE_VOID;
pointer = nullptr;
model_method1 = nullptr;
model_method2 = nullptr;
space_wrapper = nullptr;
space_table_index = 0;
// user_function = nullptr;
// model = nullptr;
// model_container_wrapper = nullptr;
// date = nullptr;
// space_wrapper = nullptr;
// space = nullptr;
// stream = nullptr;
// item_block = nullptr;
}
@@ -241,6 +233,18 @@ bool Val::has_object()
}
bool Val::has_function()
{
return type == Type::TYPE_FUNCTION && pointer;
}
bool Val::has_method()
{
return type == Type::TYPE_MODEL_METHOD && pointer && (model_method1 || model_method2 || model_method3);
}
bool Val::has_model_object()
{
return (type == Type::TYPE_MODEL || type == Type::TYPE_MODEL_CONTAINER_WRAPPER) && pointer;
@@ -460,6 +464,35 @@ void Val::set_pointer_to(UserFunction user_function)
}
#ifdef EZC_HAS_MORM_LIBRARY
void Val::set_pointer_to(morm::Model * model, ModelMethod1 model_method1)
{
clear();
type = TYPE_MODEL_METHOD;
this->pointer = model;
this->model_method1 = model_method1;
}
void Val::set_pointer_to(morm::Model * model, ModelMethod2 model_method2)
{
clear();
type = TYPE_MODEL_METHOD;
this->pointer = model;
this->model_method2 = model_method2;
}
void Val::set_pointer_to(morm::Model * model, ModelMethod3 model_method3)
{
clear();
type = TYPE_MODEL_METHOD;
this->pointer = model;
this->model_method3 = model_method3;
}
#endif
void Val::set_pointer_to(pt::Date * date)
{
clear();

View File

@@ -66,12 +66,20 @@ public:
using UserFunction = void (*)(Env &);
#ifdef EZC_HAS_MORM_LIBRARY
using ModelMethod1 = void (morm::Model::*)(Env &);
using ModelMethod2 = void (morm::Model::*)(Val &);
using ModelMethod3 = bool (morm::Model::*)();
#endif
enum Type
{
TYPE_VOID,
TYPE_SPACE_LOCAL,
TYPE_STREAM,
TYPE_FUNCTION,
TYPE_MODEL_METHOD,
TYPE_DATE,
TYPE_MODEL,
TYPE_MODEL_CONTAINER_WRAPPER,
@@ -106,6 +114,8 @@ public:
Val * find_child(const std::wstring & child_name);
bool has_object();
bool has_function();
bool has_method();
bool has_model_object();
bool has_pod_type();
@@ -138,6 +148,11 @@ public:
void set_pointer_to(pt::Stream * str);
void set_pointer_to(UserFunction user_function);
#ifdef EZC_HAS_MORM_LIBRARY
void set_pointer_to(morm::Model * model, ModelMethod1 model_method1);
void set_pointer_to(morm::Model * model, ModelMethod2 model_method2);
void set_pointer_to(morm::Model * model, ModelMethod3 model_method3);
#endif
void set_pointer_to(pt::Date * date);
void set_pointer_to(morm::Model * model);
void set_pointer_to(morm::ModelContainerWrapper * model_container_wrapper);
@@ -221,6 +236,13 @@ public:
pt::Space space_local;
void * pointer;
#ifdef EZC_HAS_MORM_LIBRARY
ModelMethod1 model_method1;
ModelMethod2 model_method2;
ModelMethod3 model_method3;
#endif
// used when pointer is pointing to a pt::Space
// but can be null
morm::SpaceWrapper * space_wrapper;