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:
Tomasz Sowa 2015-06-14 18:20:00 +00:00
parent 6b42cdf76e
commit 76490d4c19
10 changed files with 543 additions and 65 deletions

View File

@ -1,11 +1,11 @@
# DO NOT DELETE
blocks.o: blocks.h item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
blocks.o: cache.h
cache.o: cache.h item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
cache.o: blocks.h
item.o: item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
pattern.o: pattern.h item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
pattern.o: cache.h blocks.h
patternparser.o: patternparser.h blocks.h item.h funinfo.h functions.h
patternparser.o: ../../pikotools/utf8/utf8.h cache.h pattern.h
blocks.o: blocks.h item.h cache.h functions.h ../../pikotools/utf8/utf8.h
blocks.o: funinfo.h objects.h
cache.o: cache.h item.h functions.h ../../pikotools/utf8/utf8.h funinfo.h
cache.o: objects.h blocks.h
item.o: item.h
pattern.o: pattern.h item.h cache.h functions.h ../../pikotools/utf8/utf8.h
pattern.o: funinfo.h objects.h blocks.h
patternparser.o: patternparser.h blocks.h item.h cache.h functions.h
patternparser.o: ../../pikotools/utf8/utf8.h funinfo.h objects.h pattern.h

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2014, Tomasz Sowa
* Copyright (c) 2014-2015, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -65,7 +65,9 @@ public:
size_t Size() const;
void Clear();
template<class StreamType> void CacheObjects(Objects<StreamType> & obj);
template<class StreamType> void CacheFunctions(Functions<StreamType> & fun);
void CacheBlocks(Blocks & blocks);
void ClearCache();
@ -76,6 +78,16 @@ private:
};
template<class StreamType>
void Blocks::CacheObjects(Objects<StreamType> & obj)
{
BlocksTable::iterator i = blocks_tab.begin();
for( ; i != blocks_tab.end() ; ++i)
Cache(obj, i->second);
}
template<class StreamType>
void Blocks::CacheFunctions(Functions<StreamType> & fun)
{

View File

@ -72,6 +72,12 @@ void Cache(Blocks & blocks, Item & item)
} // namespace Ezc

View File

@ -41,6 +41,8 @@
#include "item.h"
#include "functions.h"
#include "objects.h"
@ -83,6 +85,38 @@ void Cache(Blocks & blocks, Item & item);
template<class StreamType>
void Cache(Objects<StreamType> & objects, Item::Function & function)
{
function.base_obj = 0;
function.method_index = -1;
if( !function.name.empty() && function.arg < 0 )
{
typename Objects<StreamType>::Iterator i = objects.Find(function.name, function.method_index);
if( i != objects.End() )
function.base_obj = *i;
}
for(size_t i=0 ; i < function.parameters.size() ; ++i)
Cache(objects, *function.parameters[i]);
}
template<class StreamType>
void Cache(Objects<StreamType> & objects, Item & item)
{
Cache(objects, item.function);
for(size_t i=0; i < item.item_tab.size() ; ++i)
Cache(objects, *item.item_tab[i]);
}
} // namespace Ezc

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2007-2014, Tomasz Sowa
* Copyright (c) 2007-2015, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -49,6 +49,7 @@ namespace Ezc
// functions or variables
template<class StreamType>
class Functions

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];

View File

@ -167,6 +167,8 @@ Item::~Item()
void Item::ClearCache(Item::Function & function)
{
function.base_obj = 0;
function.method_index = -1;
function.fun_cache = 0;
function.item_block = 0;

View File

@ -41,8 +41,7 @@
#include <vector>
#include <string>
#include "funinfo.h"
#include "functions.h"
namespace Ezc
@ -67,16 +66,20 @@ struct Item
std::vector<Function*> parameters; // if is_function is true then it is a function and can have 'parameters'
// if is_functino is empty then 'parameters' is empty too
void * fun_cache; // only valid if is_function is true
Item * item_block;
Item * item_block;
void * base_obj;
int method_index;
int arg; // used if name is numeric (if no then is equal -1)
Function()
{
is_function = false;
fun_cache = 0;
item_block = 0;
arg = -1;
is_function = false;
fun_cache = 0;
item_block = 0;
base_obj = 0;
method_index = -1;
arg = -1;
}
~Function()
@ -95,6 +98,8 @@ struct Item
name = f.name;
fun_cache = f.fun_cache;
item_block = f.item_block;
base_obj = f.base_obj;
method_index = f.method_index;
arg = f.arg;
for(size_t i=0 ; i<f.parameters.size() ; ++i)
@ -117,10 +122,12 @@ struct Item
parameters.clear();
name.clear();
fun_cache = 0;
item_block = 0;
arg = -1;
is_function = false;
fun_cache = 0;
item_block = 0;
base_obj = 0;
method_index = -1;
arg = -1;
is_function = false;
}
};
@ -130,7 +137,7 @@ struct Item
Type type;
std::wstring text; // used in: item_text
std::wstring file_name; // used in: item_include (as a file name)
std::vector<Item*> item_tab; // childs
std::vector<Item*> item_tab; // childs
bool has_function; // the [return] statement can be without a function
Function function;

306
src/objects.h Normal file
View File

@ -0,0 +1,306 @@
/*
* This file is a part of EZC -- Easy templating in C++ library
* and is distributed under the BSD 3-Clause licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2015, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef headerfile_ezc_objects
#define headerfile_ezc_objects
#include <vector>
#include <string>
#include "utf8/utf8.h"
namespace Ezc
{
template<class StreamType>
class BaseObj
{
public:
virtual ~BaseObj() {}
/*
*
*/
virtual std::wstring & GetObjectName() = 0;
/*
*
*/
virtual int FindFun(const std::wstring & fun_name) = 0;
/*
*
*/
virtual void CallFun(int fun_index, FunInfo<StreamType> &) = 0;
/*
*
*/
virtual void ClearFunctions() = 0;
/*
*
*/
virtual size_t FunctionsSize() = 0;
/*
*
*/
virtual void AddFunctions() {};
};
#define EZC_DEFINE_OBJECT_METHODS(classname) \
\
\
protected: \
\
struct EzcTemplateMethod \
{ \
std::wstring fun_name; \
void (classname::*fun)(Info &); \
}; \
\
public: \
\
virtual std::wstring & GetObjectName() \
{ \
return ezc_object_name; \
} \
\
virtual void CallFun(int fun_index, Info & info) \
{ \
if( fun_index >=0 && (size_t)fun_index < ezc_template_method_tab.size() ) \
{ \
(this->*(ezc_template_method_tab[fun_index].fun))(info); \
} \
} \
\
virtual int FindFun(const std::wstring & fun_name) \
{ \
for(size_t i=0 ; i<ezc_template_method_tab.size() ; ++i) \
{ \
if( ezc_template_method_tab[i].fun_name == fun_name ) \
{ \
return (int)i; \
} \
} \
\
return -1; \
} \
\
\
protected: \
\
virtual void ClearFunctions() \
{ \
ezc_template_method_tab.clear(); \
} \
\
virtual size_t FunctionsSize() \
{ \
return ezc_template_method_tab.size(); \
} \
\
void Insert(const char * name, void (classname::*fun)(Info &)) \
{ \
EzcTemplateMethod item; \
\
PT::UTF8ToWide(name, item.fun_name); \
item.fun = fun; \
\
ezc_template_method_tab.push_back(item); \
} \
\
void Insert(const std::string & name, void (classname::*fun)(Info &)) \
{ \
EzcTemplateMethod item; \
\
PT::UTF8ToWide(name, item.fun_name); \
item.fun = fun; \
\
ezc_template_method_tab.push_back(item); \
} \
\
void Insert(const wchar_t * name, void (classname::*fun)(Info &)) \
{ \
EzcTemplateMethod item; \
\
item.fun_name = name; \
item.fun = fun; \
\
ezc_template_method_tab.push_back(item); \
} \
\
void Insert(const std::wstring & name, void (classname::*fun)(Info &)) \
{ \
EzcTemplateMethod item; \
\
item.fun_name = name; \
item.fun = fun; \
\
ezc_template_method_tab.push_back(item); \
} \
\
std::vector<EzcTemplateMethod> ezc_template_method_tab; \
std::wstring ezc_object_name; \
\
private:
template<class StreamType>
class Objects
{
public:
typedef std::vector<BaseObj<StreamType> * > ObjectsTable;
typedef typename ObjectsTable::iterator Iterator;
void Insert(BaseObj<StreamType> * base_fun);
void Insert(BaseObj<StreamType> & base_fun);
Iterator Begin();
Iterator End();
size_t Size() const;
void Clear();
Iterator Find(const std::wstring & key, int & method_index);
private:
ObjectsTable obj_tab;
};
template<class StreamType>
typename Objects<StreamType>::Iterator Objects<StreamType>::Find(const std::wstring & key, int & method_index)
{
Iterator i = obj_tab.begin();
method_index = -1;
for( ; i != obj_tab.end() ; ++i)
{
int index = (*i)->FindFun(key);
if( index != -1 )
{
method_index = index;
return i;
}
}
return obj_tab.end();
}
template<class StreamType>
void Objects<StreamType>::Insert(BaseObj<StreamType> * base_fun)
{
obj_tab.push_back(base_fun);
}
template<class StreamType>
void Objects<StreamType>::Insert(BaseObj<StreamType> & base_fun)
{
obj_tab.push_back(&base_fun);
}
template<class StreamType>
typename Objects<StreamType>::Iterator Objects<StreamType>::Begin()
{
return obj_tab.begin();
}
template<class StreamType>
typename Objects<StreamType>::Iterator Objects<StreamType>::End()
{
return obj_tab.end();
}
template<class StreamType>
size_t Objects<StreamType>::Size() const
{
return obj_tab.size();
}
template<class StreamType>
void Objects<StreamType>::Clear()
{
return obj_tab.clear();
}
} // namespace Ezc
#endif

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2007-2014, Tomasz Sowa
* Copyright (c) 2007-2015, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -44,6 +44,7 @@
#include "cache.h"
#include "blocks.h"
#include "functions.h"
#include "objects.h"
namespace Ezc
@ -60,6 +61,7 @@ public:
template<class StreamType> void CacheFunctions(Functions<StreamType> & fun);
void CacheBlocks(Blocks & blocks);
template<class StreamType> void CacheObjects(Objects<StreamType> & obj);
void ClearCache();
@ -77,6 +79,11 @@ void Pattern::CacheFunctions(Functions<StreamType> & fun)
}
template<class StreamType>
void Pattern::CacheObjects(Objects<StreamType> & obj)
{
Cache(obj, item_root);
}