From 03fe124ad9b0b01f480247ae6877846d0c99a16a Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sun, 19 Oct 2014 21:09:34 +0000 Subject: [PATCH] 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 --- src/blocks.cpp | 8 +++- src/blocks.h | 3 +- src/cache.cpp | 30 +++++++------ src/cache.h | 31 ++++++++------ src/generator.h | 111 ++++++++++++++++++++++++++++++------------------ src/vars.cpp | 7 +++ 6 files changed, 121 insertions(+), 69 deletions(-) diff --git a/src/blocks.cpp b/src/blocks.cpp index 306c11e..544b3ae 100644 --- a/src/blocks.cpp +++ b/src/blocks.cpp @@ -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(); diff --git a/src/blocks.h b/src/blocks.h index 39a88a9..9745c3a 100644 --- a/src/blocks.h +++ b/src/blocks.h @@ -62,7 +62,8 @@ public: Iterator Begin(); Iterator End(); - size_t Size(); + size_t Size() const; + void Clear(); template void CacheFunctions(Functions & fun); void CacheBlocks(Blocks & blocks); diff --git a/src/cache.cpp b/src/cache.cpp index 0e95154..336090e 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -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) diff --git a/src/cache.h b/src/cache.h index 9bea2c2..fa09fa4 100644 --- a/src/cache.h +++ b/src/cache.h @@ -50,6 +50,23 @@ namespace Ezc class Blocks; +template +void Cache(Functions & fun, Item::Function & function) +{ + function.fun_cache = 0; + + if( !function.name.empty() && function.arg < 0 ) + { + typename Functions::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 void Cache(Functions & fun, Item & item) @@ -61,19 +78,7 @@ void Cache(Functions & 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::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) diff --git a/src/generator.h b/src/generator.h index cb867ab..827d8a6 100755 --- a/src/generator.h +++ b/src/generator.h @@ -68,7 +68,6 @@ public: ~Generator(); void SetPattern(Pattern & pattern); - void SetVars(Vars & vars); void SetBlocks(Blocks & blocks); void SetFunctions(Functions & 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 & o); @@ -140,10 +147,12 @@ private: StreamType * output_stream; Pattern * ppattern; - Vars * pvars; Blocks * pblocks; Functions * 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::Generator() : empty_stream() { output_stream = 0; ppattern = 0; - pvars = 0; pblocks = 0; pfunctions = 0; @@ -346,6 +356,8 @@ Generator::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 & Generator::operator=(const Generator & Generator::operator=(const Generator::SetPattern(Pattern & pattern) } -template -void Generator::SetVars(Vars & vars) -{ - pvars = &vars; -} template @@ -469,6 +478,20 @@ void Generator::SetFunctions(Functions & functions) } +template +void Generator::CanUseCache(bool can_use_cache) +{ + can_find_in_cache = can_use_cache; +} + + +template +void Generator::CanUseVars(bool can_use_variables) +{ + can_use_vars = can_use_variables; +} + + template void Generator::ResizeFilterTab() @@ -693,6 +716,7 @@ void Generator::Generate() filter_index = 0; stack_index = 0; block_stack_index = 0; + vars.Clear(); if( ppattern ) { @@ -704,6 +728,7 @@ void Generator::Generate() if( output_stream_index.size() > 1 ) WriteTmpStreamToStreams(); + vars.Clear(); is_generator_working = false; } catch(...) @@ -773,16 +798,19 @@ bool Generator::FindInCache(const Item::Function & item_fun, return true; } - if( item_fun.fun_cache ) + if( can_find_in_cache ) { - *function = reinterpret_cast::UserFunction*>(item_fun.fun_cache); - return true; - } + if( item_fun.fun_cache ) + { + *function = reinterpret_cast::UserFunction*>(item_fun.fun_cache); + return true; + } - if( item_fun.item_block ) - { - *item_block = item_fun.item_block; - return true; + if( item_fun.item_block ) + { + *item_block = item_fun.item_block; + return true; + } } return false; @@ -827,24 +855,21 @@ bool Generator::FindInVariables(const std::wstring & name, Item ** item_block, 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; - - if( var.type == Vars::variable_string ) - { - *variable = &var.val; - return true; - } - else - { - // this is an alias to a function or to a block - return FindInFunctionsAndBlocks(var.val, function, item_block); - } + *variable = &var.val; + return true; + } + 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::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,7 +1031,9 @@ std::wstring * variable; { // in c++11 we can use std::move here 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 if( variable ) { - out_stream << *variable; + out_stream.write(variable->c_str(), variable->size()); last_res = !variable->empty(); } @@ -1636,7 +1663,7 @@ void Generator::MakeTextFor(Item & item) template void Generator::MakeTextDefine(Item & item) { - if( !pvars ) + if( !can_use_vars ) { CreateMsg(L"[def] statement not available"); return; @@ -1648,7 +1675,7 @@ void Generator::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::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::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 diff --git a/src/vars.cpp b/src/vars.cpp index 7c6ae31..25c3681 100644 --- a/src/vars.cpp +++ b/src/vars.cpp @@ -77,4 +77,11 @@ size_t Vars::Size() } +void Vars::Clear() +{ + vars_tab.clear(); +} + + + } // namespace