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

This commit is contained in:
2025-01-28 16:46:19 +01:00
parent 1f2b5c8d12
commit 32d9fdc816
8 changed files with 209 additions and 170 deletions

View File

@@ -119,4 +119,17 @@
./val.o: ../../pikotools/src/utf8/utf8.h
./val.o: item.h
./val.o: val.h
./valwrapper.o: ../../pikotools/src/convert/inttostr.h
./valwrapper.o: ../../pikotools/src/convert/misc.h
./valwrapper.o: ../../pikotools/src/date/date.h
./valwrapper.o: ../../pikotools/src/membuffer/membuffer.h
./valwrapper.o: ../../pikotools/src/space/space.h
./valwrapper.o: ../../pikotools/src/textstream/stream_private.h
./valwrapper.o: ../../pikotools/src/textstream/stream.h
./valwrapper.o: ../../pikotools/src/textstream/textstream.h
./valwrapper.o: ../../pikotools/src/textstream/types.h
./valwrapper.o: ../../pikotools/src/utf8/utf8.h
./valwrapper.o: item.h
./valwrapper.o: val.h
./valwrapper.o: valwrapper.h
# DO NOT DELETE

View File

@@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2007-2024, Tomasz Sowa
/*
* Copyright (c) 2007-2025, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -149,7 +149,7 @@ private:
item_fun(item_fun), fun_name(fun_name), fields(fields),
parameters(parameters), result(result), out_stream(out_stream), in_stream(in_stream)
{
valcache = nullptr;
valwrapper = nullptr;
currentval = nullptr;
#ifdef EZC_HAS_MORM_LIBRARY
@@ -159,28 +159,22 @@ private:
FindHelper(const FindHelper &) = delete;
void set_valcache(ValCache * valcache)
void set_valwrapper(ValWrapper * valwrapper)
{
this->valcache = valcache;
this->valwrapper = valwrapper;
this->currentval = (valwrapper->has_evaluated_val) ? &valwrapper->evaluated_val : &valwrapper->val;
}
// RENAMEME
void set_current_val(Val * val)
{
//baseval = val;
this->currentval = val;
}
void set_current_val(Val & val)
{
set_current_val(&val);
}
Item::Function & item_fun;
const std::wstring & fun_name;
std::vector<std::wstring> & fields;
//Val * baseval;
ValCache * valcache;
ValWrapper * valwrapper;
Val * currentval;
std::vector<Val> & parameters;
Val & result;
@@ -345,9 +339,10 @@ private:
void ClearTmpStreams();
void ClearStream(pt::Stream & str);
void CopyStreamToString(pt::Stream & src_stream, std::wstring & dst_string);
void CopyStreamToString(pt::Stream & src_stream, std::wstring & dst_string); // are they still needed?
void CopyStream(pt::Stream & src_stream, pt::Stream & dst_stream);
void CopyStream(pt::WTextStream & src_stream, pt::Stream & dst_stream, bool should_escape);
void copy_stream(pt::Stream & src, size_t from, size_t to, pt::Stream & dst);
void RemoveStackFunData(Stack & sitem);
@@ -363,9 +358,7 @@ private:
bool FindInCache(Item::Function & item_fun, FindHelper & find_helper);
#ifdef EZC_HAS_MORM_LIBRARY
bool FindInModels(FindHelper & find_helper);
#endif
bool FindInFunctions(FindHelper & find_helper);
bool FindInBlocks(FindHelper & find_helper);
@@ -411,11 +404,11 @@ private:
bool CallModelContainerWrapper(FindHelper & find_helper);
#endif
bool XXXRenameMe(FindHelper & find_helper, bool is_for_alias);
bool FindLastModelWrapper(FindHelper & find_helper, bool is_for_alias);
bool FindLastSpace(FindHelper & find_helper);
bool EvaluateFunctionOrMethod(pt::Stream & out_stream, Val & val, Val & result);
bool EvaluateFunctions(pt::Stream & out_stream, Val & val, Val & result);
bool EvaluateFunctions(pt::Stream & out_stream, ValWrapper & valwrapper);
void CallObject(BaseObj & base_obj,
int method_index,
@@ -935,6 +928,28 @@ void Generator::CopyStream(pt::WTextStream & src_stream, pt::Stream & dst_stream
}
void Generator::copy_stream(pt::Stream & src, size_t from, size_t to, pt::Stream & dst)
{
dst.escape_input(false);
if( src.is_char_stream() )
{
for(size_t i=from ; i < src.size() && i < to ; ++i)
{
char c = src.get_char(i);
dst << c;
}
}
else
if( src.is_wchar_stream() )
{
for(size_t i=from ; i < src.size() && i < to ; ++i)
{
wchar_t c = src.get_wchar(i);
dst << c;
}
}
}
void Generator::RemoveStackFunData(Stack & s)
@@ -1104,6 +1119,7 @@ bool Generator::IsTestingFunctionExistence()
bool Generator::CheckBlockArgument(FindHelper & find_helper)
{
/*
if( find_helper.item_fun.arg < 0 )
return false;
@@ -1118,6 +1134,7 @@ bool Generator::CheckBlockArgument(FindHelper & find_helper)
return true;
}
}
*/
return false;
}
@@ -1156,30 +1173,17 @@ return false;
#ifdef EZC_HAS_MORM_LIBRARY
bool Generator::FindInModels(FindHelper & find_helper)
{
bool found = false;
if( pmodels )
{
ValCache * valcache = pmodels->Find(find_helper.fun_name);
ValWrapper * valwrapper = pmodels->Find(find_helper.fun_name);
if( valcache )
if( valwrapper )
{
find_helper.set_valcache(valcache);
if( valcache->has_evaluated_val )
{
find_helper.set_current_val(valcache->evaluated_val);
}
else
{
find_helper.set_current_val(valcache->val);
}
find_helper.set_valwrapper(valwrapper);
found = true;
}
}
@@ -1187,7 +1191,6 @@ bool Generator::FindInModels(FindHelper & find_helper)
return found;
}
#endif
bool Generator::FindInFunctions(FindHelper & find_helper)
@@ -1211,6 +1214,7 @@ bool Generator::FindInFunctions(FindHelper & find_helper)
bool Generator::FindInBlocks(FindHelper & find_helper)
{
/*
if( pblocks )
{
Blocks::Iterator i = pblocks->Find(find_helper.fun_name);
@@ -1221,6 +1225,7 @@ bool Generator::FindInBlocks(FindHelper & find_helper)
return true;
}
}
*/
return false;
}
@@ -1228,6 +1233,7 @@ bool Generator::FindInBlocks(FindHelper & find_helper)
bool Generator::FindInVariables(FindHelper & find_helper)
{
/*
if( pvals )
{
Vals::iterator i = pvals->find(find_helper.fun_name);
@@ -1238,6 +1244,7 @@ bool Generator::FindInVariables(FindHelper & find_helper)
return true;
}
}
*/
return false;
}
@@ -1976,7 +1983,7 @@ Val * Generator::FindLastModelWrapperEvalueateFunctionsRenameMe(FindHelper & fin
bool Generator::EvaluateFunctionOrMethod(pt::Stream & out_stream, Val & val, Val & result)
bool Generator::EvaluateFunctions(pt::Stream & out_stream, Val & val, Val & result)
{
size_t max_calls = 2; // change me to something reasnoable
size_t current_call = 1;
@@ -2035,29 +2042,35 @@ bool Generator::EvaluateFunctionOrMethod(pt::Stream & out_stream, Val & val, Val
}
bool Generator::XXXRenameMe(FindHelper & find_helper, bool is_for_alias)
bool Generator::EvaluateFunctions(pt::Stream & out_stream, ValWrapper & valwrapper)
{
if( !find_helper.valcache->has_evaluated_val && (!is_for_alias || find_helper.fields.size() > 0) )
if( valwrapper.has_evaluated_val )
{
if( find_helper.valcache->val.has_function() || find_helper.valcache->val.has_method() )
if( valwrapper.evaluated_str )
{
pt::Stream * str = find_helper.out_stream.new_empty();
out_stream.escape_input(false);
out_stream << *valwrapper.evaluated_str;
}
}
else
{
if( valwrapper.val.has_function() || valwrapper.val.has_method() )
{
size_t current_size = out_stream.size();
if( EvaluateFunctionOrMethod(*str, find_helper.valcache->val, find_helper.valcache->evaluated_val) )
if( EvaluateFunctions(out_stream, valwrapper.val, valwrapper.evaluated_val) )
{
find_helper.valcache->has_evaluated_val = true;
find_helper.valcache->evaluated_str = str;
find_helper.currentval = &find_helper.valcache->evaluated_val;
valwrapper.has_evaluated_val = true;
if( !str->empty() )
if( out_stream.size() != current_size )
{
find_helper.out_stream << *str;
valwrapper.evaluated_str = out_stream.new_empty();
copy_stream(out_stream, current_size, out_stream.size(), *valwrapper.evaluated_str);
}
}
else
{
find_helper.valcache->evaluated_val.clear();
delete str;
valwrapper.evaluated_val.clear();
// put some error log?
return false;
@@ -2072,15 +2085,12 @@ bool Generator::XXXRenameMe(FindHelper & find_helper, bool is_for_alias)
// RENAMEME
bool Generator::FindLastModelWrapper(FindHelper & find_helper, bool is_for_alias)
{
find_helper.field_index = 0;
//Val res(&find_helper.out_stream);
while( find_helper.field_index < find_helper.fields.size() && find_helper.currentval->has_model_object() )
{
std::wstring & field = find_helper.fields[find_helper.field_index];
Val * child_val = find_helper.currentval->find_child(field);
ValWrapper * child_valwrapper = find_helper.valwrapper->find_child(field);
if( !child_val )
if( !child_valwrapper )
{
morm::Model * model = nullptr;
@@ -2097,68 +2107,46 @@ bool Generator::FindLastModelWrapper(FindHelper & find_helper, bool is_for_alias
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
}
else
if( find_helper.currentval->has_function() || find_helper.currentval->has_method() )
{
if( (find_helper.field_index + 1 < find_helper.fields.size()) || !is_for_alias )
{
if( EvaluateFunctionOrMethod(find_helper.out_stream, *find_helper.currentval, find_helper.result) )
{
child_val = find_helper.currentval->add_child(field, find_helper.result);
}
else
{
// put some error?
return false;
}
}
else
{
// IMPLEMENT me for alias
find_helper.result = *find_helper.currentval;
return true;
}
}
}
if( model )
{
Val val = model->get_ezc_val(nullptr, field.c_str());
ValWrapper valwrapper;
valwrapper.val = model->get_ezc_val(nullptr, field.c_str()); // may it would be better to provide a pointer to get_ezc_val() method?
if( val.has_function() || val.has_method() )
if( (find_helper.field_index + 1 < find_helper.fields.size()) || !is_for_alias )
{
if( (find_helper.field_index + 1 < find_helper.fields.size()) || !is_for_alias )
if( EvaluateFunctions(find_helper.out_stream, valwrapper) )
{
if( EvaluateFunctionOrMethod(find_helper.out_stream, val, find_helper.result) )
{
child_val = find_helper.currentval->add_child(field, find_helper.result);
}
else
{
// put some error?
return false;
}
}
else
{
// IMPLEMENT me for alias
find_helper.result = val;
return true;
child_valwrapper = find_helper.valwrapper->add_child(field, valwrapper);
}
}
else
if( val.has_object() )
if( (valwrapper.has_evaluated_val && valwrapper.evaluated_val.has_object()) ||
(!valwrapper.has_evaluated_val && valwrapper.val.has_object()) )
{
child_val = find_helper.currentval->add_child(field, val);
child_valwrapper = find_helper.valwrapper->add_child(field, valwrapper);
}
}
}
else
{
if( child_valwrapper->has_evaluated_val )
{
if( child_valwrapper->evaluated_str )
{
find_helper.out_stream.escape_input(false);
find_helper.out_stream << *child_valwrapper->evaluated_str;
}
}
}
if( !child_val )
break; //may return false;
if( !child_valwrapper )
return false;
find_helper.currentval = child_val;
find_helper.set_valwrapper(child_valwrapper);
find_helper.currentval->set_output_stream(find_helper.out_stream);
find_helper.field_index += 1;
}
@@ -2448,6 +2436,8 @@ bool Generator::Call(Item::Function & item_fun,
fun_name = &item_fun.name;
FindHelper find_helper(item_fun, *fun_name, item_fun.fields, parameters, result, out_stream, in_stream);
find_helper.field_index = 0;
// if( clear_out_stream )
// ClearStream(out_stream);
@@ -2457,8 +2447,22 @@ bool Generator::Call(Item::Function & item_fun,
out_stream.escape_input(true);
if( !XXXRenameMe(find_helper, false) )
return false;
bool is_for_alias = false;
if( !is_for_alias || find_helper.field_index < find_helper.fields.size() )
{
if( EvaluateFunctions(find_helper.out_stream, *find_helper.valwrapper) )
{
if( find_helper.valwrapper->has_evaluated_val )
{
find_helper.currentval = &find_helper.valwrapper->evaluated_val;
}
}
else
{
return false;
}
}
if( !FindLastModelWrapper(find_helper, false) )
return false;
@@ -3054,7 +3058,9 @@ bool Generator::MakeTextForEvaluate(Item & item, Val & result, bool is_empty_str
model_container_wrapper->increment_iterator();
//find_helper.currentval->clear_childs();
//find_helper.result.set(model_container_wrapper->is_iterator_correct());
result.clear_childs(); // is it ok?
//result.clear_childs(); // is it ok?, in a next iteration we need to clear the cache of old items....
status = model_container_wrapper->is_iterator_correct();
}
else

View File

@@ -61,7 +61,7 @@ void Models::Clear()
void Models::Add(const std::wstring & name, morm::Model & model)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(&model);
models_map[name] = valcache;
}
@@ -69,7 +69,7 @@ void Models::Add(const std::wstring & name, morm::Model & model)
void Models::Add(const std::wstring & name, morm::Model * model)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(model);
models_map[name] = valcache;
}
@@ -77,7 +77,7 @@ void Models::Add(const std::wstring & name, morm::Model * model)
void Models::Add(const std::wstring & name, pt::Space & space)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::SpaceWrapper(&space));
models_map[name] = valcache;
}
@@ -85,7 +85,7 @@ void Models::Add(const std::wstring & name, pt::Space & space)
void Models::Add(const std::wstring & name, pt::Space * space)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::SpaceWrapper(space));
models_map[name] = valcache;
}
@@ -93,7 +93,7 @@ void Models::Add(const std::wstring & name, pt::Space * space)
void Models::Add(const std::wstring & name, pt::Date & date)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(&date);
models_map[name] = valcache;
}
@@ -101,7 +101,7 @@ void Models::Add(const std::wstring & name, pt::Date & date)
void Models::Add(const std::wstring & name, pt::Date * date)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(date);
models_map[name] = valcache;
}
@@ -109,7 +109,7 @@ void Models::Add(const std::wstring & name, pt::Date * date)
void Models::Add(const std::wstring & name, const std::wstring & value)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set(value);
models_map[name] = valcache;
}
@@ -117,13 +117,13 @@ void Models::Add(const std::wstring & name, const std::wstring & value)
void Models::Add(const std::wstring & name, Val::UserFunction ufunction)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(ufunction);
models_map[name] = valcache;
}
ValCache * Models::Find(const std::wstring & name)
ValWrapper * Models::Find(const std::wstring & name)
{
auto iterator = models_map.find(name);

View File

@@ -37,7 +37,7 @@
#ifdef EZC_HAS_MORM_LIBRARY
#include "valcache.h"
#include "valwrapper.h"
#include "space/space.h"
@@ -54,7 +54,7 @@ class Models
{
public:
typedef std::map<std::wstring, ValCache> ModelsMap;
typedef std::map<std::wstring, ValWrapper> ModelsMap;
Models();
~Models();
@@ -75,7 +75,7 @@ public:
template<typename VectorType>
void Add(const std::wstring & name, std::vector<VectorType> & container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperVector<VectorType>(&container));
models_map[name] = valcache;
}
@@ -83,7 +83,7 @@ public:
template<typename VectorType>
void Add(const std::wstring & name, std::vector<VectorType> * container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperVector<VectorType>(container));
models_map[name] = valcache;
}
@@ -91,7 +91,7 @@ public:
template<typename VectorType>
void Add(const std::wstring & name, std::vector<VectorType*> & container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperVectorPointer<VectorType>(&container));
models_map[name] = valcache;
}
@@ -99,7 +99,7 @@ public:
template<typename VectorType>
void Add(const std::wstring & name, std::vector<VectorType*> * container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperVectorPointer<VectorType>(container));
models_map[name] = valcache;
}
@@ -107,7 +107,7 @@ public:
template<typename ListType>
void Add(const std::wstring & name, std::list<ListType> & container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperList<ListType>(&container));
models_map[name] = valcache;
}
@@ -115,7 +115,7 @@ public:
template<typename ListType>
void Add(const std::wstring & name, std::list<ListType> * container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperList<ListType>(container));
models_map[name] = valcache;
}
@@ -123,7 +123,7 @@ public:
template<typename ListType>
void Add(const std::wstring & name, std::list<ListType*> & container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperListPointer<ListType>(&container));
models_map[name] = valcache;
}
@@ -131,12 +131,12 @@ public:
template<typename ListType>
void Add(const std::wstring & name, std::list<ListType*> * container)
{
ValCache valcache;
ValWrapper valcache;
valcache.val.set_pointer_to(new morm::ModelWrapperListPointer<ListType>(container));
models_map[name] = valcache;
}
ValCache * Find(const std::wstring & name);
ValWrapper * Find(const std::wstring & name);
Val * FindVal(const std::wstring & name);

View File

@@ -171,7 +171,6 @@ void Val::clear()
clear_space_wrapper();
initialize_empty();
space_local.clear();
clear_childs();
}
@@ -205,34 +204,6 @@ void Val::clear_space_wrapper()
}
void Val::clear_childs()
{
childs_map.clear();
}
Val * Val::add_child(const std::wstring & child_name, const Val & val)
{
Val & v = childs_map[child_name];
v.clear();
v = val;
return &v;
}
Val * Val::find_child(const std::wstring & child_name)
{
auto i = childs_map.find(child_name);
if( i != childs_map.end() )
{
return &i->second;
}
return nullptr;
}
bool Val::has_object()
{
return type != TYPE_VOID;

View File

@@ -112,9 +112,6 @@ public:
void set_output_stream(pt::Stream * output_stream);
void set_output_stream(pt::Stream & output_stream);
Val * add_child(const std::wstring & child_name, const Val & val);
Val * find_child(const std::wstring & child_name);
bool has_object();
bool has_function();
@@ -127,7 +124,6 @@ public:
//bool has_space_object();
void clear();
void clear_childs();
bool to_bool() const;
@@ -283,8 +279,6 @@ public:
private:
std::map<std::wstring, Val> childs_map;
void initialize_empty();
void copy(const Val & val);
void increment_model_container_wrapper_ref();

View File

@@ -32,27 +32,27 @@
*
*/
#include "valcache.h"
#include "valwrapper.h"
namespace Ezc
{
ValCache::ValCache()
ValWrapper::ValWrapper()
{
has_evaluated_val = false;
evaluated_str = nullptr;
}
ValCache::ValCache(const ValCache & valcache)
ValWrapper::ValWrapper(const ValWrapper & valcache)
{
operator=(valcache);
}
ValCache & ValCache::operator=(const ValCache & valcache)
ValWrapper & ValWrapper::operator=(const ValWrapper & valcache)
{
val = valcache.val;
has_evaluated_val = valcache.has_evaluated_val;
@@ -77,13 +77,15 @@ ValCache & ValCache::operator=(const ValCache & valcache)
}
void ValCache::clear()
void ValWrapper::clear()
{
val.clear();
clear_cache();
clear_evaluated_value();
clear_childs();
}
void ValCache::clear_cache()
void ValWrapper::clear_evaluated_value()
{
has_evaluated_val = false;
@@ -97,6 +99,43 @@ void ValCache::clear_cache()
}
void ValWrapper::clear_childs()
{
childs_map.clear();
}
ValWrapper * ValWrapper::add_child(const std::wstring & child_name, const ValWrapper & val)
{
ValWrapper & v = childs_map[child_name];
v.clear();
v = val;
return &v;
}
ValWrapper * ValWrapper::add_child(const std::wstring & child_name, const Val & val)
{
ValWrapper & v = childs_map[child_name];
v.clear();
v.val = val;
return &v;
}
ValWrapper * ValWrapper::find_child(const std::wstring & child_name)
{
auto i = childs_map.find(child_name);
if( i != childs_map.end() )
{
return &i->second;
}
return nullptr;
}
} // namespace Ezc

View File

@@ -41,22 +41,38 @@
namespace Ezc
{
class ValCache
//ValWrapper
class ValWrapper
{
public:
ValWrapper();
ValWrapper(const ValWrapper &);
ValWrapper & operator=(const ValWrapper &);
Val val;
bool has_evaluated_val;
Val evaluated_val;
pt::Stream * evaluated_str;
pt::Stream * evaluated_str; // can be null
ValCache();
ValCache(const ValCache &);
ValCache & operator=(const ValCache &);
void clear();
void clear_cache();
void clear_evaluated_value();
void clear_childs();
ValWrapper * add_child(const std::wstring & child_name, const ValWrapper & val);
ValWrapper * add_child(const std::wstring & child_name, const Val & val);
ValWrapper * find_child(const std::wstring & child_name);
private:
std::map<std::wstring, ValWrapper> childs_map;
};