fixed: function and blocks were incorrectly cached

(now we have a tree in Item::Function.parameters too
        and we should go through that tree as well)
fixed: in Generator: Item::Function.par should be cleared
       only if Item::Function.name is not empty
changed: in Generator: use method 'write' of an output stream
       instead of operator<<
added: Clear() method to Blocks class
changed: in Generator
       Generator has its own Vars class now
       we don't need SetVars() method
added: to Generator:
       void CanUseCache(bool can_use_cache);
       // set whether or not we can use cache for functions or blocks
       // true by default

       void CanUseVars(bool can_use_variables);
       // set whether or not we can use variables: [def ...] statement
       // true by default





git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@977 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2014-10-19 21:09:34 +00:00
parent 6f9f274e08
commit 03fe124ad9
6 changed files with 121 additions and 69 deletions

View File

@ -66,12 +66,18 @@ Blocks::Iterator Blocks::End()
}
size_t Blocks::Size()
size_t Blocks::Size() const
{
return blocks_tab.size();
}
void Blocks::Clear()
{
blocks_tab.clear();
}
void Blocks::ClearCache()
{
BlocksTable::iterator i = blocks_tab.begin();

View File

@ -62,7 +62,8 @@ public:
Iterator Begin();
Iterator End();
size_t Size();
size_t Size() const;
void Clear();
template<class StreamType> void CacheFunctions(Functions<StreamType> & fun);
void CacheBlocks(Blocks & blocks);

View File

@ -48,6 +48,23 @@ namespace Ezc
{
void Cache(Blocks & blocks, Item::Function & function)
{
function.item_block = 0;
if( !function.name.empty() && function.arg < 0 )
{
Blocks::Iterator i = blocks.Find(function.name);
if( i != blocks.End() )
function.item_block = &i->second;
}
for(size_t i=0 ; i < function.parameters.size() ; ++i)
Cache(blocks, *function.parameters[i]);
}
void Cache(Blocks & blocks, Item & item)
{
// one exception (if_index is putting its argument on the functions stack)
@ -57,18 +74,7 @@ void Cache(Blocks & blocks, Item & item)
if( item.type != Item::item_ifindex )
{
for(size_t f=0; f < item.functions.size() ; ++f)
{
Item::Function & function = item.functions[f];
function.item_block = 0;
if( function.arg < 0 )
{
Blocks::Iterator b = blocks.Find(function.name);
if( b != blocks.End() )
function.item_block = &b->second;
}
}
Cache(blocks, item.functions[f]);
}
for(size_t i=0; i < item.item_tab.size() ; ++i)

View File

@ -50,6 +50,23 @@ namespace Ezc
class Blocks;
template<class StreamType>
void Cache(Functions<StreamType> & fun, Item::Function & function)
{
function.fun_cache = 0;
if( !function.name.empty() && function.arg < 0 )
{
typename Functions<StreamType>::Iterator i = fun.Find(function.name);
if( i != fun.End() )
function.fun_cache = &i->second;
}
for(size_t i=0 ; i < function.parameters.size() ; ++i)
Cache(fun, *function.parameters[i]);
}
template<class StreamType>
void Cache(Functions<StreamType> & fun, Item & item)
@ -61,19 +78,7 @@ void Cache(Functions<StreamType> & fun, Item & item)
if( item.type != Item::item_ifindex )
{
for(size_t f=0; f < item.functions.size() ; ++f)
{
Item::Function & function = item.functions[f];
function.fun_cache = 0;
if( function.arg < 0 )
{
typename Functions<StreamType>::Iterator i = fun.Find(function.name);
if( i != fun.End() )
function.fun_cache = &i->second;
}
}
Cache(fun, item.functions[f]);
}
for(size_t i=0; i < item.item_tab.size() ; ++i)

View File

@ -68,7 +68,6 @@ public:
~Generator();
void SetPattern(Pattern & pattern);
void SetVars(Vars & vars);
void SetBlocks(Blocks & blocks);
void SetFunctions(Functions<StreamType> & functions);
@ -107,6 +106,14 @@ public:
// set stream_index to -1 to turn off (default)
void SkipStream(int stream_index);
// set whether or not we can use cache for functions or blocks
// true by default
void CanUseCache(bool can_use_cache);
// set whether or not we can use variables: [def ...] statement
// true by default
void CanUseVars(bool can_use_variables);
// the main methods for generating
void Generate(StreamType & o);
void Generate(std::vector<StreamType> & o);
@ -140,10 +147,12 @@ private:
StreamType * output_stream;
Pattern * ppattern;
Vars * pvars;
Blocks * pblocks;
Functions<StreamType> * pfunctions;
// variables set
Vars vars;
// 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
// to the correct streams)
@ -221,6 +230,8 @@ private:
std::wstring commentary_start, commentary_stop;
bool can_use_vars;
bool can_find_in_cache;
void ResizeFilterTab();
void ResizeStack();
@ -332,7 +343,6 @@ Generator<StreamType>::Generator() : empty_stream()
{
output_stream = 0;
ppattern = 0;
pvars = 0;
pblocks = 0;
pfunctions = 0;
@ -346,6 +356,8 @@ Generator<StreamType>::Generator() : empty_stream()
stack_size = 300;
block_stack_size = 64;
has_skip_stream_index = false;
can_find_in_cache = true;
can_use_vars = true;
}
@ -367,7 +379,6 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
output_stream = n.output_stream;
ppattern = n.ppattern;
pvars = n.pvars;
pblocks = n.pblocks;
pfunctions = n.pfunctions;
@ -377,12 +388,15 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
trim_white = n.trim_white;
skip_new_line = n.skip_new_line;
has_skip_stream_index = n.has_skip_stream_index;
can_find_in_cache = n.can_find_in_cache;
can_use_vars = n.can_use_vars;
// filter, stack and block_stack will be auto resized when calling Generate() method
filter_size = n.filter_size;
stack_size = n.stack_size;
block_stack_size = n.block_stack_size;
// vars doesn't have to be copied
// don't copy filter tab
// don't copy stack
@ -448,11 +462,6 @@ void Generator<StreamType>::SetPattern(Pattern & pattern)
}
template<class StreamType>
void Generator<StreamType>::SetVars(Vars & vars)
{
pvars = &vars;
}
template<class StreamType>
@ -469,6 +478,20 @@ void Generator<StreamType>::SetFunctions(Functions<StreamType> & functions)
}
template<class StreamType>
void Generator<StreamType>::CanUseCache(bool can_use_cache)
{
can_find_in_cache = can_use_cache;
}
template<class StreamType>
void Generator<StreamType>::CanUseVars(bool can_use_variables)
{
can_use_vars = can_use_variables;
}
template<class StreamType>
void Generator<StreamType>::ResizeFilterTab()
@ -693,6 +716,7 @@ void Generator<StreamType>::Generate()
filter_index = 0;
stack_index = 0;
block_stack_index = 0;
vars.Clear();
if( ppattern )
{
@ -704,6 +728,7 @@ void Generator<StreamType>::Generate()
if( output_stream_index.size() > 1 )
WriteTmpStreamToStreams();
vars.Clear();
is_generator_working = false;
}
catch(...)
@ -773,6 +798,8 @@ bool Generator<StreamType>::FindInCache(const Item::Function & item_fun,
return true;
}
if( can_find_in_cache )
{
if( item_fun.fun_cache )
{
*function = reinterpret_cast<typename Functions<StreamType>::UserFunction*>(item_fun.fun_cache);
@ -784,6 +811,7 @@ bool Generator<StreamType>::FindInCache(const Item::Function & item_fun,
*item_block = item_fun.item_block;
return true;
}
}
return false;
}
@ -827,11 +855,9 @@ bool Generator<StreamType>::FindInVariables(const std::wstring & name,
Item ** item_block,
std::wstring ** variable)
{
if( pvars )
{
Vars::Iterator i = pvars->Find(name);
Vars::Iterator i = vars.Find(name);
if( i != pvars->End() )
if( i != vars.End() )
{
Vars::Variable & var = i->second;
@ -846,7 +872,6 @@ bool Generator<StreamType>::FindInVariables(const std::wstring & name,
return FindInFunctionsAndBlocks(var.val, function, item_block);
}
}
}
return false;
}
@ -947,8 +972,8 @@ bool Generator<StreamType>::CallBlock(Item & item_block,
const std::wstring & str = output_stream->str();
#endif
out_stream.write(str.c_str(), str.size());
out_stream << str;
last_res = !str.empty();
ClearStream(*output_stream);
@ -1006,6 +1031,8 @@ std::wstring * variable;
{
// in c++11 we can use std::move here
parameters[i] = item_fun.parameters[i]->par;
if( !item_fun.parameters[i]->name.empty() )
item_fun.parameters[i]->par.clear();
}
}
@ -1022,7 +1049,7 @@ std::wstring * variable;
else
if( variable )
{
out_stream << *variable;
out_stream.write(variable->c_str(), variable->size());
last_res = !variable->empty();
}
@ -1636,7 +1663,7 @@ void Generator<StreamType>::MakeTextFor(Item & item)
template<class StreamType>
void Generator<StreamType>::MakeTextDefine(Item & item)
{
if( !pvars )
if( !can_use_vars )
{
CreateMsg(L"[def] statement not available");
return;
@ -1648,7 +1675,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
if( item.functions[0].parameters[0]->name.empty() )
{
// it is [def name "string"]
pvars->Insert(item.functions[0].name, Vars::variable_string, item.functions[0].parameters[0]->par);
vars.Insert(item.functions[0].name, Vars::variable_string, item.functions[0].parameters[0]->par);
}
else
{
@ -1661,7 +1688,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
const std::wstring & str = stream_temp_define.str();
#endif
pvars->Insert(item.functions[0].name, Vars::variable_string, str);
vars.Insert(item.functions[0].name, Vars::variable_string, str);
}
}
}
@ -1678,17 +1705,17 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
{
if( variable )
{
Vars::Iterator i = pvars->Find(*variable);
Vars::Iterator i = vars.Find(*variable);
if( i != pvars->End() )
if( i != vars.End() )
{
Vars::Variable & var = i->second;
pvars->Insert(*variable, var.type, var.val);
vars.Insert(*variable, var.type, var.val);
}
}
else
{
pvars->Insert(item.functions[0].name, Vars::variable_alias, item.functions[1].name);
vars.Insert(item.functions[0].name, Vars::variable_alias, item.functions[1].name);
}
}
else

View File

@ -77,4 +77,11 @@ size_t Vars::Size()
}
void Vars::Clear()
{
vars_tab.clear();
}
} // namespace