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:
parent
6f1e2eb518
commit
b519c79a3e
|
@ -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]);
|
||||
|
|
11
src/cache.h
11
src/cache.h
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
159
src/generator.h
159
src/generator.h
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue