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