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(); return blocks_tab.size();
} }
void Blocks::Clear()
{
blocks_tab.clear();
}
void Blocks::ClearCache() void Blocks::ClearCache()
{ {
BlocksTable::iterator i = blocks_tab.begin(); BlocksTable::iterator i = blocks_tab.begin();

View File

@ -62,7 +62,8 @@ public:
Iterator Begin(); Iterator Begin();
Iterator End(); Iterator End();
size_t Size(); size_t Size() const;
void Clear();
template<class StreamType> void CacheFunctions(Functions<StreamType> & fun); template<class StreamType> void CacheFunctions(Functions<StreamType> & fun);
void CacheBlocks(Blocks & blocks); 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) void Cache(Blocks & blocks, Item & item)
{ {
// one exception (if_index is putting its argument on the functions stack) // 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 ) if( item.type != Item::item_ifindex )
{ {
for(size_t f=0; f < item.functions.size() ; ++f) for(size_t f=0; f < item.functions.size() ; ++f)
{ Cache(blocks, item.functions[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;
}
}
} }
for(size_t i=0; i < item.item_tab.size() ; ++i) for(size_t i=0; i < item.item_tab.size() ; ++i)

View File

@ -50,6 +50,23 @@ namespace Ezc
class Blocks; 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> template<class StreamType>
void Cache(Functions<StreamType> & fun, Item & item) void Cache(Functions<StreamType> & fun, Item & item)
@ -61,19 +78,7 @@ void Cache(Functions<StreamType> & fun, Item & item)
if( item.type != Item::item_ifindex ) if( item.type != Item::item_ifindex )
{ {
for(size_t f=0; f < item.functions.size() ; ++f) for(size_t f=0; f < item.functions.size() ; ++f)
{ Cache(fun, item.functions[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;
}
}
} }
for(size_t i=0; i < item.item_tab.size() ; ++i) for(size_t i=0; i < item.item_tab.size() ; ++i)

View File

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

View File

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