removed: statements: [if-index ...] [is ...] and [is-no ...]

we can provide a user definied function which does the same
added:   to FunInfo<>:
         Stack * stack_tab
         size_t stack_index
         a stack table and an index to the current stack item



git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@988 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2014-11-02 17:26:56 +00:00
parent 6f1e2eb518
commit b519c79a3e
7 changed files with 30 additions and 226 deletions

View File

@ -61,17 +61,11 @@ void Cache(Blocks & blocks, Item::Function & function)
}
void Cache(Blocks & blocks, Item & item)
{
// one exception (if_index is putting its argument on the functions stack)
/*
!! IMPROVE ME we need to change the parser and the index take as a string
*/
if( item.type != Item::item_ifindex )
{
for(size_t f=0; f < item.functions.size() ; ++f)
Cache(blocks, item.functions[f]);
}
for(size_t f=0; f < item.functions.size() ; ++f)
Cache(blocks, item.functions[f]);
for(size_t i=0; i < item.item_tab.size() ; ++i)
Cache(blocks, *item.item_tab[i]);

View File

@ -71,15 +71,8 @@ void Cache(Functions<StreamType> & fun, Item::Function & function)
template<class StreamType>
void Cache(Functions<StreamType> & fun, Item & item)
{
// one exception (if_index is putting its argument on the functions stack)
/*
!! IMPROVE ME we need to change the parser and the index take as a string
*/
if( item.type != Item::item_ifindex )
{
for(size_t f=0; f < item.functions.size() ; ++f)
Cache(fun, item.functions[f]);
}
for(size_t f=0; f < item.functions.size() ; ++f)
Cache(fun, item.functions[f]);
for(size_t i=0; i < item.item_tab.size() ; ++i)
Cache(fun, *item.item_tab[i]);

View File

@ -151,19 +151,23 @@ struct FunInfo
// it is true for all kind of if's: if-one, if-any, if-no....
bool is_if;
// indicates that this function is from [is ...] or [is-no ...] statements
bool is_is;
// indicates that this funcion is a normal statement e.g.: [funcion_name]
bool is_normal;
// indicates that this function is from a filter statement [filter ...]
bool is_filter;
// a pointer to the stack
Stack * stack_tab;
// current stack item
size_t stack_index;
// a stack's item from generator's stack
// each function has a new stack item
// on this stack you have iter (description below) and fun_data pointer
// you can assign to it your own object derived from FunData
// 'stack' is a reference to stack_tab[stack_index]
Stack & stack;
// the same as stack.iter (this is mainly for backward compatibility)
@ -188,10 +192,11 @@ struct FunInfo
res = false; // result is false by default
is_for = false;
is_if = false;
is_is = false;
is_normal = false;
is_filter = false;
iter = 0;
stack_tab = 0;
stack_index = 0;
}
};

View File

@ -199,9 +199,9 @@ private:
// used in [0] [1] [2] when there is no such argument defined
std::wstring empty_argument;
// temporary streams used in [if..] [is...] or [for...]
// temporary streams used in [if..] [for...] or [def ...]
// or if output_stream is null and an ezc function should be called
StreamType stream_temp1, stream_temp2, stream_temp_define;
StreamType stream_temp1, stream_temp_define;
// last result from a user function (FunInfo::res)
bool last_res;
@ -212,7 +212,6 @@ private:
// true if the Generator is working with [for ...], [if ...] etc.
bool is_generating_for;
bool is_generating_if;
bool is_generating_is;
bool is_generating_normal;
bool is_generating_filter;
@ -242,8 +241,6 @@ private:
template<class CharType>
CharType ToLower(CharType c);
bool AreStreamsEqual(StreamType & str1, StreamType & str2);
bool FindInCache(const Item::Function & item_fun,
typename Functions<StreamType>::UserFunction ** function,
Item ** item_block,
@ -288,7 +285,6 @@ private:
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
void SkipWhite(const wchar_t *& str);
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0);
bool LookForLastForStatement(size_t & last_for_index);
void WriteTmpStreamToStreams();
@ -300,21 +296,16 @@ private:
bool LimitAchieved();
void MakeTextIf_go(Item & item, bool result);
bool MakeTextIfindexnumber(Item & item, size_t for_index, bool & result);
void MakeTextIf(Item & item);
void MakeTextIfno(Item & item);
void MakeTextIfany(Item & item);
void MakeTextIfone(Item & item);
void MakeTextIfanyno(Item & item);
void MakeTextIfoneno(Item & item);
void MakeTextIfindex(Item & item);
void MakeTextFor(Item & item);
void MakeItemText(Item & item);
void MakeTextContainer(Item & item);
void MakeTextNormal(Item & item);
void MakeTextIs(Item & item, bool equal);
void MakeTextIs(Item & item);
void MakeTextIsno(Item & item);
void MakeTextDefine(Item & item);
void MakeTextFilter(Item & item);
void MakeTextEzc(Item & item);
@ -629,18 +620,6 @@ return c;
template<class StreamType>
bool Generator<StreamType>::AreStreamsEqual(StreamType & str1, StreamType & str2)
{
#ifdef EZC_HAS_SPECIAL_STREAM
return str1.Str() == str2.Str();
#else
return str1.str() == str2.str();
#endif
}
template<class StreamType>
void Generator<StreamType>::SetMax(size_t max_items_, size_t max_for_items_)
{
@ -910,12 +889,13 @@ void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFun
{
info.Clear();
info.is_for = is_generating_for;
info.is_if = is_generating_if;
info.is_is = is_generating_is;
info.is_normal = is_generating_normal;
info.is_filter = is_generating_filter;
info.iter = info.stack.iter;
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.data();
info.stack_index = stack_index-1;
(*function)(info);
@ -1496,121 +1476,6 @@ void Generator<StreamType>::MakeTextIfoneno(Item & item)
template<class StreamType>
void Generator<StreamType>::MakeTextIs(Item & item, bool equal)
{
if( item.functions.size() != 2 )
return;
is_generating_is = true;
if( !Call(item.functions[0], stream_temp1, true, empty_stream) )
return;
if( !Call(item.functions[1], stream_temp2, true, empty_stream) )
return;
bool res = AreStreamsEqual(stream_temp1, stream_temp2);
if( !equal )
res = !res;
MakeTextIf_go(item, res);
}
template<class StreamType>
void Generator<StreamType>::MakeTextIs(Item & item)
{
MakeTextIs(item, true);
}
template<class StreamType>
void Generator<StreamType>::MakeTextIsno(Item & item)
{
MakeTextIs(item, false);
}
template<class StreamType>
bool Generator<StreamType>::LookForLastForStatement(size_t & last_for_index)
{
last_for_index = stack_index;
while( last_for_index-- > 0 )
{
if( stack_tab[last_for_index].is_for )
return true;
}
return false;
}
template<class StreamType>
bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, size_t for_index, bool & result)
{
if( item.functions.size() != 1 )
return false;
const wchar_t * number_text = item.functions[0].name.c_str();
const wchar_t * last_char;
size_t number = StrToSize(number_text, &last_char);
if( *last_char != '\0' )
{
CreateMsg(L"if-index: syntax error");
return false;
}
result = (stack_tab[for_index].iter == number);
return true;
}
template<class StreamType>
void Generator<StreamType>::MakeTextIfindex(Item & item)
{
size_t for_index;
if( item.functions.size() != 1 || !LookForLastForStatement(for_index) )
return;
bool result = false;
if( item.functions[0].name == L"odd" )
{
result = (stack_tab[for_index].iter & 1) == 1;
}
else
if( item.functions[0].name == L"even" )
{
result = (stack_tab[for_index].iter & 1) == 0;
}
else
if( item.functions[0].name == L"first" )
{
result = stack_tab[for_index].iter == 0;
}
else
{
if( !MakeTextIfindexnumber(item, for_index, result) )
return;
}
MakeTextIf_go(item, result);
}
template<class StreamType>
void Generator<StreamType>::MakeTextFor(Item & item)
{
@ -1879,7 +1744,6 @@ void Generator<StreamType>::MakeText(Item & item)
stack_index += 1;
is_generating_for = false;
is_generating_if = false;
is_generating_is = false;
is_generating_normal = false;
is_generating_filter = false;
@ -1894,9 +1758,6 @@ void Generator<StreamType>::MakeText(Item & item)
else if( item.type == Item::item_ifone ) MakeTextIfone(item);
else if( item.type == Item::item_ifanyno ) MakeTextIfanyno(item);
else if( item.type == Item::item_ifoneno ) MakeTextIfoneno(item);
else if( item.type == Item::item_ifindex ) MakeTextIfindex(item);
else if( item.type == Item::item_is ) MakeTextIs(item);
else if( item.type == Item::item_isno ) MakeTextIsno(item);
else if( item.type == Item::item_def ) MakeTextDefine(item);
else if( item.type == Item::item_for ) MakeTextFor(item);
else if( item.type == Item::item_filter ) MakeTextFilter(item);
@ -1916,3 +1777,5 @@ void Generator<StreamType>::MakeText(Item & item)
#endif

View File

@ -54,10 +54,10 @@ struct Item
{
enum Type
{
item_none, item_container, item_text, item_normal, item_is, item_isno,
item_if, item_ifno, item_ifany, item_ifone, item_ifanyno, item_ifoneno, item_ifindex,
item_for, item_else, item_end, item_err, item_include, item_comment, item_def, item_filter,
item_ezc, item_block, item_return
item_none, item_container, item_text, item_normal,
item_if, item_ifno, item_ifany, item_ifone, item_ifanyno, item_ifoneno,
item_for, item_else, item_end, item_err, item_include, item_comment,
item_def, item_filter, item_ezc, item_block, item_return
};

View File

@ -685,28 +685,6 @@ void PatternParser::ReadDirectiveIfoneno(Item & item)
void PatternParser::ReadDirectiveIs(Item & item)
{
item.type = Item::item_is;
ReadFunctions(item);
if( item.functions.size() != 2 )
item.type = Item::item_err;
}
void PatternParser::ReadDirectiveIsno(Item & item)
{
item.type = Item::item_isno;
ReadFunctions(item);
if( item.functions.size() != 2 )
item.type = Item::item_err;
}
void PatternParser::ReadDirectiveEnd(Item & item)
{
item.type = Item::item_end;
@ -721,26 +699,6 @@ void PatternParser::ReadDirectiveElse(Item & item)
void PatternParser::ReadDirectiveIfindex(Item & item)
{
item.type = Item::item_err;
item.functions.clear();
temp_function.Clear();
// reading: odd, even, first or a number (without quotes)
if( !ReadName(temp_function.name) )
return;
if( temp_function.name != L"odd" && temp_function.name != L"even" &&
temp_function.name != L"first" && !IsPositiveNumber(temp_function.name) )
return;
item.functions.push_back(temp_function);
item.type = Item::item_ifindex;
}
void PatternParser::ReadDirectiveFor(Item & item)
{
item.type = Item::item_for;
@ -869,9 +827,6 @@ std::wstring name;
else if( name == L"if-one" ) ReadDirectiveIfone(item);
else if( name == L"if-any-no" ) ReadDirectiveIfanyno(item);
else if( name == L"if-one-no" ) ReadDirectiveIfoneno(item);
else if( name == L"if-index" ) ReadDirectiveIfindex(item);
else if( name == L"is" ) ReadDirectiveIs(item);
else if( name == L"is-no" ) ReadDirectiveIsno(item);
else if( name == L"end" ) ReadDirectiveEnd(item);
else if( name == L"else" ) ReadDirectiveElse(item);
else if( name == L"for" ) ReadDirectiveFor(item);
@ -1043,10 +998,7 @@ void PatternParser::CreateTree(Item & item)
pitem->type == Item::item_ifany ||
pitem->type == Item::item_ifone ||
pitem->type == Item::item_ifanyno ||
pitem->type == Item::item_ifoneno ||
pitem->type == Item::item_ifindex ||
pitem->type == Item::item_is ||
pitem->type == Item::item_isno )
pitem->type == Item::item_ifoneno )
CreateTreeReadIf(*pitem);
if( pitem->type == Item::item_for ||

View File

@ -168,11 +168,8 @@ private:
void ReadDirectiveIfone(Item & item);
void ReadDirectiveIfanyno(Item & item);
void ReadDirectiveIfoneno(Item & item);
void ReadDirectiveIs(Item & item);
void ReadDirectiveIsno(Item & item);
void ReadDirectiveEnd(Item & item);
void ReadDirectiveElse(Item & item);
void ReadDirectiveIfindex(Item & item);
void ReadDirectiveFor(Item & item);
void ReadDirectiveComment(Item & item);
void ReadDirectiveInclude(Item & item);