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:
185
src/generator.h
185
src/generator.h
@@ -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];
|
||||
|
Reference in New Issue
Block a user