added: now ezc functions can be methods of a special object

added: objects.h with a base class for the object
       and Objects container (similar as Functions container)



git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@1011 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2015-06-14 18:20:00 +00:00
parent 6b42cdf76e
commit 76490d4c19
10 changed files with 543 additions and 65 deletions

View File

@@ -42,6 +42,7 @@
#include "blocks.h"
#include "pattern.h"
#include "functions.h"
#include "objects.h"
#include <sstream>
#include <fstream>
#include <vector>
@@ -69,6 +70,8 @@ public:
void SetPattern(Pattern & pattern);
void SetBlocks(Blocks & blocks);
void SetFunctions(Functions<StreamType> & functions);
void SetObjects(Objects<StreamType> & objects);
void SetMax(size_t max_items_, size_t max_for_items_);
@@ -155,6 +158,7 @@ private:
Pattern * ppattern;
Blocks * pblocks;
Functions<StreamType> * pfunctions;
Objects<StreamType> * pobjects;
// output_tmp_stream is used when outputting to more than one stream
// (first we output to output_tmp_stream and then the content is copied
@@ -242,19 +246,28 @@ private:
template<class CharType>
CharType ToLower(CharType c);
bool FindInCache(const Item::Function & item_fun,
bool CheckBlockArgument(Item::Function & item_fun, std::wstring ** variable);
bool FindInCache(Item::Function & item_fun,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block,
std::wstring ** variable);
Item ** item_block);
bool FindInFunctionsAndBlocks(const std::wstring & name,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block);
bool FindInVariables(const std::wstring & name,
std::wstring ** variable);
bool Find(const Item::Function & item_fun,
bool Find(Item::Function & item_fun,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block,
std::wstring ** variable);
@@ -271,6 +284,17 @@ private:
std::vector<Var> & parameters,
StreamType & out_stream);
void CallObject(BaseObj<StreamType> * base_obj, int method_index, FunInfo<StreamType> & info);
void CallObject(BaseObj<StreamType> * base_obj,
int method_index,
std::vector<Var> & parameters,
StreamType & out_stream,
const StreamType & in_stream);
bool Call(Item::Function & item_fun,
StreamType & out_stream,
bool clear_out_stream,
@@ -328,6 +352,7 @@ Generator<StreamType>::Generator() : empty_stream()
ppattern = 0;
pblocks = 0;
pfunctions = 0;
pobjects = 0;
max_items = 50000;
max_for_items = 5000;
@@ -364,6 +389,7 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
ppattern = n.ppattern;
pblocks = n.pblocks;
pfunctions = n.pfunctions;
pobjects = n.pobjects;
max_items = n.max_items;
max_for_items = n.max_for_items;
@@ -462,6 +488,12 @@ void Generator<StreamType>::SetFunctions(Functions<StreamType> & functions)
}
template<class StreamType>
void Generator<StreamType>::SetObjects(Objects<StreamType> & objects)
{
pobjects = &objects;
}
template<class StreamType>
void Generator<StreamType>::CanUseCache(bool can_use_cache)
{
@@ -766,34 +798,50 @@ void Generator<StreamType>::Generate(std::vector<StreamType*> & o)
}
template<class StreamType>
bool Generator<StreamType>::FindInCache(const Item::Function & item_fun,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block,
std::wstring ** variable)
bool Generator<StreamType>::CheckBlockArgument(Item::Function & item_fun, std::wstring ** variable)
{
if( item_fun.arg >= 0 )
if( item_fun.arg < 0 )
return false;
empty_argument.clear();
*variable = &empty_argument;
last_res = ConvertToBool(empty_argument);
// it's a numeric function -- an argument to a block e.g.: [1]
if( block_stack_index > 0 )
{
empty_argument.clear();
*variable = &empty_argument;
BlockStack & block_stack = block_stack_tab[block_stack_index-1];
// it's a numeric function -- an argument to a block e.g.: [1]
if( block_stack_index > 0 )
if( size_t(item_fun.arg) < block_stack.args.size() )
{
BlockStack & block_stack = block_stack_tab[block_stack_index-1];
if( size_t(item_fun.arg) < block_stack.args.size() )
{
*variable = &block_stack.args[item_fun.arg].str;
last_res = block_stack.args[item_fun.arg].res;
}
*variable = &block_stack.args[item_fun.arg].str;
last_res = block_stack.args[item_fun.arg].res;
}
return true;
}
return true;
}
template<class StreamType>
bool Generator<StreamType>::FindInCache(Item::Function & item_fun,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block)
{
if( can_find_in_cache )
{
if( item_fun.base_obj )
{
*base_obj = reinterpret_cast<BaseObj<StreamType> * >(item_fun.base_obj);
*method_index = item_fun.method_index;
return true;
}
if( item_fun.fun_cache )
{
*function = reinterpret_cast<typename Functions<StreamType>::UserFunction*>(item_fun.fun_cache);
@@ -814,9 +862,22 @@ return false;
template<class StreamType>
bool Generator<StreamType>::FindInFunctionsAndBlocks(const std::wstring & name,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block)
{
if( pobjects )
{
typename Objects<StreamType>::Iterator i = pobjects->Find(name, *method_index);
if( i != pobjects->End() )
{
*base_obj = *i;
return true;
}
}
if( pfunctions )
{
typename Functions<StreamType>::Iterator i = pfunctions->Find(name);
@@ -863,19 +924,26 @@ return false;
template<class StreamType>
bool Generator<StreamType>::Find(const Item::Function & item_fun,
bool Generator<StreamType>::Find(Item::Function & item_fun,
BaseObj<StreamType> ** base_obj,
int * method_index,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block,
std::wstring ** variable)
{
*base_obj = 0;
*method_index = -1;
*function = 0;
*item_block = 0;
*variable = 0;
if( FindInCache(item_fun, function, item_block, variable) )
if( CheckBlockArgument(item_fun, variable) )
return true;
if( FindInFunctionsAndBlocks(item_fun.name, function, item_block) )
if( FindInCache(item_fun, base_obj, method_index, function, item_block) )
return true;
if( FindInFunctionsAndBlocks(item_fun.name, base_obj, method_index, function, item_block) )
return true;
if( FindInVariables(item_fun.name, variable) )
@@ -928,6 +996,51 @@ void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFun
template<class StreamType>
void Generator<StreamType>::CallObject(BaseObj<StreamType> * base_obj, int method_index, FunInfo<StreamType> & info)
{
info.Clear();
info.is_for = is_generating_for;
info.is_if = is_generating_if;
info.is_normal = is_generating_normal;
info.is_filter = is_generating_filter;
info.iter = info.stack.iter;
info.stack_tab = &stack_tab[0];//stack_tab.data();/////////////////////////////////////////////////////////
info.stack_index = stack_index-1;
base_obj->CallFun(method_index, info);
last_res = info.res;
}
template<class StreamType>
void Generator<StreamType>::CallObject(BaseObj<StreamType> * base_obj,
int method_index,
std::vector<Var> & parameters,
StreamType & out_stream,
const StreamType & in_stream)
{
if( parameters.empty() )
{
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1]);
CallObject(base_obj, method_index, info);
}
else
{
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1]);
CallObject(base_obj, method_index, info);
}
}
template<class StreamType>
bool Generator<StreamType>::CallBlock(Item & item_block,
std::vector<Var> & parameters,
@@ -975,6 +1088,8 @@ bool Generator<StreamType>::Call(Item::Function & item_fun,
bool clear_out_stream,
const StreamType & in_stream)
{
BaseObj<StreamType> * base_obj;
int method_index;
typename Functions<StreamType>::UserFunction * fun;
Item * item_block;
std::wstring * variable;
@@ -983,7 +1098,7 @@ std::vector<Var> parameters;
if( clear_out_stream )
ClearStream(out_stream);
if( !Find(item_fun, &fun, &item_block, &variable) )
if( !Find(item_fun, &base_obj, &method_index, &fun, &item_block, &variable) )
return false;
parameters.resize(item_fun.parameters.size());
@@ -1012,6 +1127,9 @@ std::vector<Var> parameters;
}
}
if( base_obj )
CallObject(base_obj, method_index, parameters, out_stream, in_stream);
else
if( fun )
CallFunction(fun, parameters, out_stream, in_stream);
else
@@ -1446,26 +1564,11 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
template<class StreamType>
void Generator<StreamType>::MakeTextFilter(Item & item)
{
typename Functions<StreamType>::UserFunction * function;
Item * item_block;
std::wstring * variable;
if( !Find(item.function, &function, &item_block, &variable) )
return;
// IMPROVE ME
// what about blocks and variables?
// may when there is a block we can get the whole content from filter
// and put it as the first argument to the block?
if( !function )
return;
if( filter_index >= filter_tab.size() )
{
CreateMsg(L"Generator exceeded allowed number of filters");
return;
}
StreamType * old_stream = output_stream;
output_stream = filter_tab[filter_index];