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:
parent
6f9f274e08
commit
03fe124ad9
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
31
src/cache.h
31
src/cache.h
|
@ -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)
|
||||||
|
|
111
src/generator.h
111
src/generator.h
|
@ -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
|
||||||
|
|
|
@ -77,4 +77,11 @@ size_t Vars::Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Vars::Clear()
|
||||||
|
{
|
||||||
|
vars_tab.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue