fixed: Generator: when making [if-index]

[if-index] statement has to look for a last [for] statement on the stack
       (because the stack is for all items now)


git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@394 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2012-03-03 20:58:55 +00:00
parent 787b5e99b2
commit 68c1fb8ef8
2 changed files with 30 additions and 8 deletions

View File

@ -74,12 +74,16 @@ struct FunData
this object would be immediately removed)
remove - when true it means that object pointing by fun_data should be automatically
removed -- (by using delete fun_data)
is_for - true if the item is from [for] statement
currently used only in [if-index]
(it has to look for the last [for] item)
*/
struct Stack
{
size_t iter;
FunData * fun_data;
bool remove;
bool is_for;
Stack()
{
@ -91,6 +95,7 @@ struct Stack
iter = 0;
fun_data = 0;
remove = true;
is_for = false;
}
};

View File

@ -189,6 +189,7 @@ 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);
bool LookForLastForStatement(size_t & last_for_index);
void CreateMsg(StreamType & out, const wchar_t * type, const wchar_t * arg = 0);
void CreateMsg(const wchar_t * type, const wchar_t * arg = 0);
@ -198,7 +199,7 @@ private:
bool LimitAchieved();
void MakeTextIf_go(Item & item, bool result);
bool MakeTextIfindexnumber(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);
@ -1064,12 +1065,24 @@ void Generator<StreamType>::MakeTextIsno(Item & item)
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, bool & result)
bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, size_t for_index, bool & result)
{
if( item.functions.size() != 1 )
return false;
@ -1085,7 +1098,7 @@ bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, bool & result)
return false;
}
result = (stack_tab[stack_index-1].iter == number);
result = (stack_tab[for_index].iter == number);
return true;
}
@ -1095,28 +1108,30 @@ return true;
template<class StreamType>
void Generator<StreamType>::MakeTextIfindex(Item & item)
{
if( item.functions.size() != 1 )
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[stack_index-1].iter & 1) == 1;
result = (stack_tab[for_index].iter & 1) == 1;
}
else
if( item.functions[0].name == L"even" )
{
result = (stack_tab[stack_index-1].iter & 1) == 0;
result = (stack_tab[for_index].iter & 1) == 0;
}
else
if( item.functions[0].name == L"first" )
{
result = stack_tab[stack_index-1].iter == 0;
result = stack_tab[for_index].iter == 0;
}
else
{
if( !MakeTextIfindexnumber(item, result) )
if( !MakeTextIfindexnumber(item, for_index, result) )
return;
}
@ -1128,6 +1143,8 @@ void Generator<StreamType>::MakeTextIfindex(Item & item)
template<class StreamType>
void Generator<StreamType>::MakeTextForLoop(Item & item, typename Functions<StreamType>::Function * function)
{
stack_tab[stack_index-1].is_for = true;
for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 )
{
if( stack_tab[stack_index-1].iter >= max_for_items )