changed: the way how functions' arguments are parsed
now this [fun1 fun2 "something" fun3] will call fun1 with three arguments: fun2, "something" and fun3 and this [fun1 [fun2 "something"] fun3] will call fun1 with two arguments: [fun2 "something] and fun3 "something" is an argument for fun2 function removed: statements: [if-one] [if-any] [if-no] [if-any-no] [if-one-no] git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@1004 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
b519c79a3e
commit
6b42cdf76e
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Tomasz Sowa
|
* Copyright (c) 2014-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -64,8 +64,7 @@ void Cache(Blocks & blocks, Item::Function & function)
|
||||||
|
|
||||||
void Cache(Blocks & blocks, Item & item)
|
void Cache(Blocks & blocks, Item & item)
|
||||||
{
|
{
|
||||||
for(size_t f=0; f < item.functions.size() ; ++f)
|
Cache(blocks, item.function);
|
||||||
Cache(blocks, item.functions[f]);
|
|
||||||
|
|
||||||
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
||||||
Cache(blocks, *item.item_tab[i]);
|
Cache(blocks, *item.item_tab[i]);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Tomasz Sowa
|
* Copyright (c) 2014-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -71,8 +71,7 @@ void Cache(Functions<StreamType> & fun, Item::Function & function)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Cache(Functions<StreamType> & fun, Item & item)
|
void Cache(Functions<StreamType> & fun, Item & item)
|
||||||
{
|
{
|
||||||
for(size_t f=0; f < item.functions.size() ; ++f)
|
Cache(fun, item.function);
|
||||||
Cache(fun, item.functions[f]);
|
|
||||||
|
|
||||||
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
||||||
Cache(fun, *item.item_tab[i]);
|
Cache(fun, *item.item_tab[i]);
|
||||||
|
|
257
src/generator.h
257
src/generator.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
* Copyright (c) 2007-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -130,7 +130,6 @@ private:
|
||||||
typedef std::map<std::wstring, Var> Vars;
|
typedef std::map<std::wstring, Var> Vars;
|
||||||
Vars vars;
|
Vars vars;
|
||||||
|
|
||||||
Var temp_var;
|
|
||||||
|
|
||||||
struct BlockStack
|
struct BlockStack
|
||||||
{
|
{
|
||||||
|
@ -238,6 +237,8 @@ private:
|
||||||
void ClearStream(StreamType & str);
|
void ClearStream(StreamType & str);
|
||||||
void RemoveStackFunData(Stack & sitem);
|
void RemoveStackFunData(Stack & sitem);
|
||||||
|
|
||||||
|
bool ConvertToBool(const std::wstring & str);
|
||||||
|
|
||||||
template<class CharType>
|
template<class CharType>
|
||||||
CharType ToLower(CharType c);
|
CharType ToLower(CharType c);
|
||||||
|
|
||||||
|
@ -297,11 +298,6 @@ private:
|
||||||
|
|
||||||
void MakeTextIf_go(Item & item, bool result);
|
void MakeTextIf_go(Item & item, bool result);
|
||||||
void MakeTextIf(Item & item);
|
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 MakeTextFor(Item & item);
|
void MakeTextFor(Item & item);
|
||||||
void MakeItemText(Item & item);
|
void MakeItemText(Item & item);
|
||||||
void MakeTextContainer(Item & item);
|
void MakeTextContainer(Item & item);
|
||||||
|
@ -619,6 +615,15 @@ return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
bool Generator<StreamType>::ConvertToBool(const std::wstring & str)
|
||||||
|
{
|
||||||
|
if( str == L"true" )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::SetMax(size_t max_items_, size_t max_for_items_)
|
void Generator<StreamType>::SetMax(size_t max_items_, size_t max_for_items_)
|
||||||
|
@ -715,7 +720,6 @@ void Generator<StreamType>::Generate()
|
||||||
WriteTmpStreamToStreams();
|
WriteTmpStreamToStreams();
|
||||||
|
|
||||||
vars.clear();
|
vars.clear();
|
||||||
temp_var.str.clear();
|
|
||||||
is_generator_working = false;
|
is_generator_working = false;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -894,7 +898,7 @@ void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFun
|
||||||
info.is_normal = is_generating_normal;
|
info.is_normal = is_generating_normal;
|
||||||
info.is_filter = is_generating_filter;
|
info.is_filter = is_generating_filter;
|
||||||
info.iter = info.stack.iter;
|
info.iter = info.stack.iter;
|
||||||
info.stack_tab = stack_tab.data();
|
info.stack_tab = &stack_tab[0];//stack_tab.data();/////////////////////////////////////////////////////////
|
||||||
info.stack_index = stack_index-1;
|
info.stack_index = stack_index-1;
|
||||||
|
|
||||||
(*function)(info);
|
(*function)(info);
|
||||||
|
@ -954,7 +958,7 @@ bool Generator<StreamType>::CallBlock(Item & item_block,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
out_stream.write(str.c_str(), str.size());
|
out_stream.write(str.c_str(), str.size());
|
||||||
// last_res is set by [return ...] statement
|
// last_res is set by [return ...] statement or other last evaluated function
|
||||||
|
|
||||||
ClearStream(*output_stream);
|
ClearStream(*output_stream);
|
||||||
output_stream = old_stream;
|
output_stream = old_stream;
|
||||||
|
@ -964,7 +968,7 @@ return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// return: true if a function or variable was found and called
|
// return: true if a function, variable or block was found and called
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
bool Generator<StreamType>::Call(Item::Function & item_fun,
|
bool Generator<StreamType>::Call(Item::Function & item_fun,
|
||||||
StreamType & out_stream,
|
StreamType & out_stream,
|
||||||
|
@ -988,7 +992,7 @@ std::vector<Var> parameters;
|
||||||
{
|
{
|
||||||
Item::Function & fun_child = *item_fun.parameters[i];
|
Item::Function & fun_child = *item_fun.parameters[i];
|
||||||
|
|
||||||
if( !fun_child.name.empty() )
|
if( fun_child.is_function )
|
||||||
{
|
{
|
||||||
StreamType local_temp_stream;
|
StreamType local_temp_stream;
|
||||||
Call(fun_child, local_temp_stream, true, empty_stream);
|
Call(fun_child, local_temp_stream, true, empty_stream);
|
||||||
|
@ -1003,8 +1007,8 @@ std::vector<Var> parameters;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parameters[i].str = fun_child.par;
|
parameters[i].str = fun_child.name;
|
||||||
parameters[i].res = !fun_child.par.empty();
|
parameters[i].res = ConvertToBool(fun_child.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,18 +1323,15 @@ void Generator<StreamType>::MakeTextContainer(Item & item)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextNormal(Item & item)
|
void Generator<StreamType>::MakeTextNormal(Item & item)
|
||||||
{
|
{
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
is_generating_normal = true;
|
is_generating_normal = true;
|
||||||
|
|
||||||
if( output_stream )
|
if( output_stream )
|
||||||
{
|
{
|
||||||
Call(item.functions[0], *output_stream, false, empty_stream);
|
Call(item.function, *output_stream, false, empty_stream);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Call(item.functions[0], stream_temp1, false, empty_stream);
|
Call(item.function, stream_temp1, false, empty_stream);
|
||||||
ClearStream(stream_temp1);
|
ClearStream(stream_temp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1358,137 +1359,27 @@ void Generator<StreamType>::MakeTextIf_go(Item & item, bool result)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextIf(Item & item)
|
void Generator<StreamType>::MakeTextIf(Item & item)
|
||||||
{
|
{
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
is_generating_if = true;
|
||||||
|
|
||||||
if( !Call(item.functions[0]) )
|
if( !Call(item.function) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MakeTextIf_go(item, last_res);
|
MakeTextIf_go(item, last_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::MakeTextIfno(Item & item)
|
|
||||||
{
|
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
|
||||||
|
|
||||||
if( !Call(item.functions[0]) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
MakeTextIf_go(item, !last_res);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::MakeTextIfany(Item & item)
|
|
||||||
{
|
|
||||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
|
||||||
unsigned how_many_true = 0;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
|
||||||
|
|
||||||
for( ; d != item.functions.end() ; ++d )
|
|
||||||
{
|
|
||||||
if( !Call(*d) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( last_res )
|
|
||||||
++how_many_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_true == item.functions.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::MakeTextIfone(Item & item)
|
|
||||||
{
|
|
||||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
|
||||||
unsigned how_many_true = 0;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
|
||||||
|
|
||||||
for( ; d != item.functions.end() ; ++d )
|
|
||||||
{
|
|
||||||
if( Call(*d) )
|
|
||||||
{
|
|
||||||
if( last_res )
|
|
||||||
{
|
|
||||||
++how_many_true;
|
|
||||||
break; // there is no sense to go through all functions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_true > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::MakeTextIfanyno(Item & item)
|
|
||||||
{
|
|
||||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
|
||||||
unsigned how_many_true = 0;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
|
||||||
|
|
||||||
for( ; d != item.functions.end() ; ++d )
|
|
||||||
{
|
|
||||||
if( !Call(*d) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( last_res )
|
|
||||||
++how_many_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_true == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::MakeTextIfoneno(Item & item)
|
|
||||||
{
|
|
||||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
|
||||||
unsigned how_many_false = 0;
|
|
||||||
|
|
||||||
is_generating_if = true;
|
|
||||||
|
|
||||||
for( ; d != item.functions.end() ; ++d )
|
|
||||||
{
|
|
||||||
if( Call(*d) )
|
|
||||||
{
|
|
||||||
if( !last_res )
|
|
||||||
{
|
|
||||||
++how_many_false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_false > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextFor(Item & item)
|
void Generator<StreamType>::MakeTextFor(Item & item)
|
||||||
{
|
{
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
stack_tab[stack_index-1].is_for = true;
|
stack_tab[stack_index-1].is_for = true;
|
||||||
|
|
||||||
for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 )
|
for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 )
|
||||||
{
|
{
|
||||||
if( stack_tab[stack_index-1].iter >= max_for_items )
|
if( stack_tab[stack_index-1].iter >= max_for_items )
|
||||||
{
|
{
|
||||||
CreateMsg(item.functions[0].name.c_str(),
|
CreateMsg(item.function.name.c_str(),
|
||||||
L"function exceeded a limit for a [for] statement");
|
L"function exceeded a limit for a [for] statement");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1496,7 +1387,7 @@ void Generator<StreamType>::MakeTextFor(Item & item)
|
||||||
// is_generating_for will be changed by next call to MakeText()
|
// is_generating_for will be changed by next call to MakeText()
|
||||||
// so we should set it in each iterations
|
// so we should set it in each iterations
|
||||||
is_generating_for = true;
|
is_generating_for = true;
|
||||||
Call(item.functions[0], stream_temp1, true, empty_stream);
|
Call(item.function, stream_temp1, true, empty_stream);
|
||||||
|
|
||||||
if( !last_res )
|
if( !last_res )
|
||||||
break;
|
break;
|
||||||
|
@ -1511,53 +1402,40 @@ void Generator<StreamType>::MakeTextFor(Item & item)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextDefine(Item & item)
|
void Generator<StreamType>::MakeTextDefine(Item & item)
|
||||||
{
|
{
|
||||||
Item::Function * pfun = 0;
|
|
||||||
|
|
||||||
if( !can_use_vars )
|
if( !can_use_vars )
|
||||||
{
|
{
|
||||||
CreateMsg(L"[def] statement not available");
|
CreateMsg(L"[def] statement not available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( item.functions.size() == 1 &&
|
|
||||||
item.functions[0].parameters.size() == 1 )
|
|
||||||
{
|
|
||||||
if( item.functions[0].parameters[0]->name.empty() )
|
|
||||||
{
|
|
||||||
// it is [def name "string"]
|
|
||||||
temp_var.str = item.functions[0].parameters[0]->par;
|
|
||||||
temp_var.res = !temp_var.str.empty();
|
|
||||||
vars[item.functions[0].name] = temp_var;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// it is [def name [function "funpar"]]
|
|
||||||
pfun = item.functions[0].parameters[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.functions.size() == 2 )
|
|
||||||
{
|
|
||||||
// is is [def name function "funpar"]
|
|
||||||
pfun = &item.functions[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pfun )
|
|
||||||
{
|
|
||||||
if( Call(*pfun, stream_temp_define, true, empty_stream) )
|
|
||||||
{
|
|
||||||
#ifdef EZC_HAS_SPECIAL_STREAM
|
|
||||||
temp_var.str = stream_temp_define.Str();
|
|
||||||
#else
|
|
||||||
temp_var.str = stream_temp_define.str();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
temp_var.res = last_res;
|
Var & var = vars[item.function.name];
|
||||||
vars[item.functions[0].name] = temp_var;
|
var.str.clear();
|
||||||
|
var.res = false;
|
||||||
|
|
||||||
|
for(size_t i=0 ; i < item.function.parameters.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( !item.function.parameters[i]->is_function )
|
||||||
|
{
|
||||||
|
var.str += item.function.parameters[i]->name;
|
||||||
|
var.res = ConvertToBool(item.function.parameters[i]->name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CreateMsg(L"[def] unknown function/block/variable", pfun->name);
|
// it is a function parameter
|
||||||
|
if( Call(*item.function.parameters[i], stream_temp_define, true, empty_stream) )
|
||||||
|
{
|
||||||
|
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||||
|
var.str += stream_temp_define.Str();
|
||||||
|
#else
|
||||||
|
var.str += stream_temp_define.str();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var.res = last_res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateMsg(L"[def] unknown function/block/variable", item.function.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1568,14 +1446,11 @@ Item::Function * pfun = 0;
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextFilter(Item & item)
|
void Generator<StreamType>::MakeTextFilter(Item & item)
|
||||||
{
|
{
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
typename Functions<StreamType>::UserFunction * function;
|
typename Functions<StreamType>::UserFunction * function;
|
||||||
Item * item_block;
|
Item * item_block;
|
||||||
std::wstring * variable;
|
std::wstring * variable;
|
||||||
|
|
||||||
if( !Find(item.functions[0], &function, &item_block, &variable) )
|
if( !Find(item.function, &function, &item_block, &variable) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// IMPROVE ME
|
// IMPROVE ME
|
||||||
|
@ -1605,13 +1480,11 @@ void Generator<StreamType>::MakeTextFilter(Item & item)
|
||||||
|
|
||||||
if( old_stream )
|
if( old_stream )
|
||||||
{
|
{
|
||||||
//Call(function, item.functions[0].params, *old_stream, false, *output_stream);
|
Call(item.function, *old_stream, false, *output_stream);
|
||||||
Call(item.functions[0], *old_stream, false, *output_stream);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Call(function, item.functions[0].params, stream_temp1, true, *output_stream);
|
Call(item.function, stream_temp1, true, *output_stream);
|
||||||
Call(item.functions[0], stream_temp1, true, *output_stream);
|
|
||||||
ClearStream(stream_temp1);
|
ClearStream(stream_temp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,7 +1505,7 @@ void Generator<StreamType>::MakeEzcStream(Item::Function & fun)
|
||||||
|
|
||||||
for(size_t i=0 ; i<fun.parameters.size() ; ++i)
|
for(size_t i=0 ; i<fun.parameters.size() ; ++i)
|
||||||
{
|
{
|
||||||
size_t index = StrToSize(fun.parameters[i]->par.c_str()); // !! CHECK ME or ->name ?
|
size_t index = StrToSize(fun.parameters[i]->name.c_str());
|
||||||
|
|
||||||
if( index < output_stream_tab.size() )
|
if( index < output_stream_tab.size() )
|
||||||
{
|
{
|
||||||
|
@ -1665,15 +1538,12 @@ void Generator<StreamType>::MakeEzcStream(Item::Function & fun)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeTextEzc(Item & item)
|
void Generator<StreamType>::MakeTextEzc(Item & item)
|
||||||
{
|
{
|
||||||
for(size_t i=0 ; i<item.functions.size() ; ++i)
|
if( item.function.name == L"stream" )
|
||||||
{
|
MakeEzcStream(item.function);
|
||||||
if( item.functions[i].name == L"stream" )
|
else
|
||||||
MakeEzcStream(item.functions[i]);
|
CreateMsg(L"incorrect argument to [ezc] statement");
|
||||||
else
|
|
||||||
CreateMsg(L"incorrect argument to [ezc] statement");
|
|
||||||
|
|
||||||
// in the future we can use more builtin functions
|
// in the future we can use more builtin functions
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1692,11 +1562,11 @@ void Generator<StreamType>::MakeTextReturn(Item & item)
|
||||||
BlockStack & block_stack = block_stack_tab[block_stack_index - 1];
|
BlockStack & block_stack = block_stack_tab[block_stack_index - 1];
|
||||||
block_stack.was_return = true;
|
block_stack.was_return = true;
|
||||||
|
|
||||||
if( !item.functions.empty() )
|
if( item.has_function )
|
||||||
{
|
{
|
||||||
// output stream in [return] statement is ignored
|
// output stream in [return] statement is ignored (we use only the stream produced by the whole block)
|
||||||
// this Call() sets last_res which is used later when we return to CallBlock()
|
// this Call() sets last_res which is used later when we return to CallBlock()
|
||||||
Call(item.functions[0], stream_temp1, false, empty_stream);
|
Call(item.function, stream_temp1, false, empty_stream);
|
||||||
ClearStream(stream_temp1);
|
ClearStream(stream_temp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1751,13 +1621,8 @@ void Generator<StreamType>::MakeText(Item & item)
|
||||||
|
|
||||||
if ( item.type == Item::item_text ) MakeItemText(item);
|
if ( item.type == Item::item_text ) MakeItemText(item);
|
||||||
else if( item.type == Item::item_container )MakeTextContainer(item);
|
else if( item.type == Item::item_container )MakeTextContainer(item);
|
||||||
else if( item.type == Item::item_normal ) MakeTextNormal(item);
|
else if( item.type == Item::item_function ) MakeTextNormal(item);
|
||||||
else if( item.type == Item::item_if ) MakeTextIf(item);
|
else if( item.type == Item::item_if ) MakeTextIf(item);
|
||||||
else if( item.type == Item::item_ifno ) MakeTextIfno(item);
|
|
||||||
else if( item.type == Item::item_ifany ) MakeTextIfany(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_def ) MakeTextDefine(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_for ) MakeTextFor(item);
|
||||||
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
||||||
|
|
17
src/item.cpp
17
src/item.cpp
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
* Copyright (c) 2007-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -89,7 +89,8 @@ void Item::Clear()
|
||||||
|
|
||||||
text.clear();
|
text.clear();
|
||||||
file_name.clear();
|
file_name.clear();
|
||||||
functions.clear();
|
has_function = false;
|
||||||
|
function.Clear();
|
||||||
type = item_none;
|
type = item_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +124,10 @@ Item::Item()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Item::Item(const Item & i) : type(i.type), text(i.text), file_name(i.file_name), functions(i.functions)
|
Item::Item(const Item & i) : text(i.text), file_name(i.file_name), function(i.function)
|
||||||
{
|
{
|
||||||
|
type = i.type;
|
||||||
|
has_function = i.has_function;
|
||||||
CopyItemTable(i);
|
CopyItemTable(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +137,9 @@ Item & Item::operator=(const Item & i)
|
||||||
{
|
{
|
||||||
type = i.type;
|
type = i.type;
|
||||||
text = i.text;
|
text = i.text;
|
||||||
file_name = i.file_name;
|
file_name = i.file_name;
|
||||||
functions = i.functions;
|
has_function = i.has_function;
|
||||||
|
function = i.function;
|
||||||
|
|
||||||
ClearItems();
|
ClearItems();
|
||||||
CopyItemTable(i);
|
CopyItemTable(i);
|
||||||
|
@ -173,8 +177,7 @@ void Item::ClearCache(Item::Function & function)
|
||||||
|
|
||||||
void Item::ClearCache()
|
void Item::ClearCache()
|
||||||
{
|
{
|
||||||
for(size_t f = 0; f < functions.size() ; ++f)
|
ClearCache(function);
|
||||||
ClearCache(functions[f]);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < item_tab.size() ; ++i)
|
for(size_t i = 0; i < item_tab.size() ; ++i)
|
||||||
item_tab[i]->ClearCache();
|
item_tab[i]->ClearCache();
|
||||||
|
|
46
src/item.h
46
src/item.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
* Copyright (c) 2007-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -54,8 +54,7 @@ struct Item
|
||||||
{
|
{
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
item_none, item_container, item_text, item_normal,
|
item_none, item_container, item_text, item_function, item_if,
|
||||||
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_for, item_else, item_end, item_err, item_include, item_comment,
|
||||||
item_def, item_filter, item_ezc, item_block, item_return
|
item_def, item_filter, item_ezc, item_block, item_return
|
||||||
};
|
};
|
||||||
|
@ -63,21 +62,21 @@ struct Item
|
||||||
|
|
||||||
struct Function
|
struct Function
|
||||||
{
|
{
|
||||||
std::wstring name; // function name (can be empty, means there is no any function -- only
|
bool is_function; // if true then we have a function parameter, if false then we have a string parameter
|
||||||
// a text parameter and a boolean value)
|
std::wstring name; // a function or parameter name
|
||||||
std::wstring par; // string parameter
|
std::vector<Function*> parameters; // if is_function is true then it is a function and can have 'parameters'
|
||||||
std::vector<Function*> parameters; // if name is not empty then is is a function and can have 'parameters'
|
// if is_functino is empty then 'parameters' is empty too
|
||||||
// if name is empty then parameters is empty too
|
void * fun_cache; // only valid if is_function is true
|
||||||
void * fun_cache; // only valid if name is not empty
|
|
||||||
Item * item_block;
|
Item * item_block;
|
||||||
int arg; // used if name is numeric (if no then is equal -1)
|
int arg; // used if name is numeric (if no then is equal -1)
|
||||||
|
|
||||||
|
|
||||||
Function()
|
Function()
|
||||||
{
|
{
|
||||||
fun_cache = 0;
|
is_function = false;
|
||||||
item_block = 0;
|
fun_cache = 0;
|
||||||
arg = -1;
|
item_block = 0;
|
||||||
|
arg = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Function()
|
~Function()
|
||||||
|
@ -92,11 +91,11 @@ struct Item
|
||||||
|
|
||||||
Function & operator=(const Function & f)
|
Function & operator=(const Function & f)
|
||||||
{
|
{
|
||||||
name = f.name;
|
is_function = f.is_function;
|
||||||
par = f.par;
|
name = f.name;
|
||||||
fun_cache = f.fun_cache;
|
fun_cache = f.fun_cache;
|
||||||
item_block = f.item_block;
|
item_block = f.item_block;
|
||||||
arg = f.arg;
|
arg = f.arg;
|
||||||
|
|
||||||
for(size_t i=0 ; i<f.parameters.size() ; ++i)
|
for(size_t i=0 ; i<f.parameters.size() ; ++i)
|
||||||
parameters.push_back(new Function(*f.parameters[i]));
|
parameters.push_back(new Function(*f.parameters[i]));
|
||||||
|
@ -118,10 +117,10 @@ struct Item
|
||||||
|
|
||||||
parameters.clear();
|
parameters.clear();
|
||||||
name.clear();
|
name.clear();
|
||||||
par.clear();
|
fun_cache = 0;
|
||||||
fun_cache = 0;
|
item_block = 0;
|
||||||
item_block = 0;
|
arg = -1;
|
||||||
arg = -1;
|
is_function = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -132,7 +131,8 @@ struct Item
|
||||||
std::wstring text; // used in: item_text
|
std::wstring text; // used in: item_text
|
||||||
std::wstring file_name; // used in: item_include (as a file name)
|
std::wstring file_name; // used in: item_include (as a file name)
|
||||||
std::vector<Item*> item_tab; // childs
|
std::vector<Item*> item_tab; // childs
|
||||||
std::vector<Function> functions;
|
bool has_function; // the [return] statement can be without a function
|
||||||
|
Function function;
|
||||||
|
|
||||||
Item();
|
Item();
|
||||||
Item(const Item & i);
|
Item(const Item & i);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
* Copyright (c) 2007-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -425,6 +425,22 @@ void PatternParser::SkipWhite()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PatternParser::SkipOneStatement()
|
||||||
|
{
|
||||||
|
size_t count = 1;
|
||||||
|
|
||||||
|
while( *itext != 0 && count > 0 )
|
||||||
|
{
|
||||||
|
if( *itext == '[' )
|
||||||
|
count += 1;
|
||||||
|
else
|
||||||
|
if( *itext == ']' )
|
||||||
|
count -= 1;
|
||||||
|
|
||||||
|
itext += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::CheckWhiteAndDelete(std::wstring & s)
|
void PatternParser::CheckWhiteAndDelete(std::wstring & s)
|
||||||
{
|
{
|
||||||
|
@ -440,6 +456,12 @@ size_t i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PatternParser::CheckFunctionIsNumber(Item::Function & function)
|
||||||
|
{
|
||||||
|
if( IsPositiveNumber(function.name) )
|
||||||
|
function.arg = wcstol(function.name.c_str(), 0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PatternParser::IsNameChar(wchar_t c)
|
bool PatternParser::IsNameChar(wchar_t c)
|
||||||
{
|
{
|
||||||
|
@ -522,103 +544,176 @@ bool PatternParser::ReadString(std::wstring & str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *itext == '\"' )
|
if( *itext == '\"' )
|
||||||
|
{
|
||||||
++itext;
|
++itext;
|
||||||
|
return true;
|
||||||
// if there was not a quote at the end we do not report an error
|
}
|
||||||
|
else
|
||||||
return true;
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool PatternParser::ReadNestedFunction(Item::Function & function)
|
||||||
|
{
|
||||||
|
++itext; // skipping '['
|
||||||
|
|
||||||
|
bool res = ReadFunction(function.AddNewParam(), true);
|
||||||
|
|
||||||
|
if( !res )
|
||||||
|
{
|
||||||
|
SkipOneStatement();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipWhite();
|
||||||
|
|
||||||
|
if( *itext == ']' )
|
||||||
|
{
|
||||||
|
++itext;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SkipOneStatement();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PatternParser::ReadParamString(Item::Function & function)
|
||||||
|
{
|
||||||
|
Item::Function & fun = function.AddNewParam();
|
||||||
|
fun.is_function = false;
|
||||||
|
|
||||||
|
return ReadString(fun.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
returns true if it correctly reads all parameters
|
||||||
|
*/
|
||||||
bool PatternParser::ReadParams(Item::Function & function)
|
bool PatternParser::ReadParams(Item::Function & function)
|
||||||
{
|
{
|
||||||
while( true )
|
bool res;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
SkipWhite();
|
SkipWhite();
|
||||||
|
|
||||||
if( *itext == '[' )
|
if( *itext == '[' )
|
||||||
{
|
{
|
||||||
++itext; // skipping '['
|
res = ReadNestedFunction(function);
|
||||||
ReadFunction(function.AddNewParam());
|
|
||||||
|
|
||||||
SkipWhite();
|
|
||||||
if( *itext == ']' )
|
|
||||||
++itext;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( *itext == '\"' )
|
if( *itext == '\"' )
|
||||||
{
|
{
|
||||||
if( ReadString(temp_param) )
|
res = ReadParamString(function);
|
||||||
{
|
}
|
||||||
Item::Function & fun = function.AddNewParam();
|
else
|
||||||
fun.par = temp_param;
|
if( *itext != ']' && *itext != 0 )
|
||||||
// fun.name is empty so it is treated as a text parameter
|
{
|
||||||
}
|
res = ReadFunction(function.AddNewParam(), false);
|
||||||
|
|
||||||
temp_param.clear();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// *itext is equal to ']'
|
||||||
|
res = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while( res );
|
||||||
|
|
||||||
return !function.parameters.empty();
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PatternParser::ReadFunction(Item::Function & function)
|
/*
|
||||||
|
returns true if it correctly reads all parameters
|
||||||
|
*/
|
||||||
|
bool PatternParser::ReadFunction(Item::Function & function, bool with_params)
|
||||||
{
|
{
|
||||||
SkipWhite();
|
SkipWhite();
|
||||||
function.Clear();
|
function.Clear();
|
||||||
|
function.is_function = true;
|
||||||
|
|
||||||
if( !ReadName(function.name) )
|
if( !ReadName(function.name) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// !! IMPROVE ME add skiping some white characters (at the beginning and at the end)
|
CheckFunctionIsNumber(function);
|
||||||
if( IsPositiveNumber(function.name) )
|
|
||||||
function.arg = wcstol(function.name.c_str(), 0, 10);
|
|
||||||
|
|
||||||
ReadParams(function);
|
if( with_params )
|
||||||
|
return ReadParams(function);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
returns true if it correctly reads all parameters
|
||||||
bool PatternParser::ReadFunctions(Item & item)
|
*/
|
||||||
|
bool PatternParser::ReadFunction(Item & item)
|
||||||
{
|
{
|
||||||
item.functions.clear();
|
SkipWhite();
|
||||||
|
|
||||||
while( ReadFunction(temp_function) )
|
if( *itext == ']' )
|
||||||
item.functions.push_back(temp_function);
|
{
|
||||||
|
item.has_function = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.has_function = true;
|
||||||
|
|
||||||
temp_function.Clear();
|
if( !ReadFunction(item.function, true) )
|
||||||
|
{
|
||||||
|
item.function.Clear();
|
||||||
|
item.type = Item::item_err;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return !item.functions.empty();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item)
|
void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item)
|
||||||
{
|
{
|
||||||
SkipWhite();
|
SkipWhite();
|
||||||
|
|
||||||
if( *itext != ']' )
|
if( *itext == ']' )
|
||||||
|
{
|
||||||
|
itext += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_err;
|
||||||
|
item.function.Clear();
|
||||||
while( *itext!=0 && *itext!=']' )
|
SkipOneStatement();
|
||||||
++itext;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( *itext == ']' )
|
|
||||||
++itext;
|
// user defined directive
|
||||||
|
void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
||||||
|
{
|
||||||
|
item.type = Item::item_function;
|
||||||
|
item.has_function = true;
|
||||||
|
|
||||||
|
item.function.Clear();
|
||||||
|
item.function.name = name;
|
||||||
|
item.function.is_function = true;
|
||||||
|
CheckFunctionIsNumber(item.function);
|
||||||
|
|
||||||
|
if( !ReadParams(item.function) )
|
||||||
|
{
|
||||||
|
item.type = Item::item_err;
|
||||||
|
item.function.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -626,64 +721,11 @@ void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item)
|
||||||
void PatternParser::ReadDirectiveIf(Item & item)
|
void PatternParser::ReadDirectiveIf(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_if;
|
item.type = Item::item_if;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveIfno(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifno;
|
|
||||||
ReadFunctions(item);
|
|
||||||
|
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveIfany(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifany;
|
|
||||||
|
|
||||||
if( !ReadFunctions(item) )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveIfone(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifone;
|
|
||||||
|
|
||||||
if( !ReadFunctions(item) )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveIfanyno(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifanyno;
|
|
||||||
|
|
||||||
if( !ReadFunctions(item) )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveIfoneno(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifoneno;
|
|
||||||
|
|
||||||
if( !ReadFunctions(item) )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveEnd(Item & item)
|
void PatternParser::ReadDirectiveEnd(Item & item)
|
||||||
{
|
{
|
||||||
|
@ -702,10 +744,7 @@ void PatternParser::ReadDirectiveElse(Item & item)
|
||||||
void PatternParser::ReadDirectiveFor(Item & item)
|
void PatternParser::ReadDirectiveFor(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_for;
|
item.type = Item::item_for;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -733,54 +772,32 @@ void PatternParser::ReadDirectiveInclude(Item & item)
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveDef(Item & item)
|
void PatternParser::ReadDirectiveDef(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_def;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
if( item.functions.size() == 1 && item.functions[0].parameters.size() == 1 )
|
|
||||||
{
|
|
||||||
// it is [def name "value"]
|
|
||||||
// or [def name [otherfunction]]
|
|
||||||
// or [def name [otherfunction "argument"]] etc.
|
|
||||||
|
|
||||||
item.type = Item::item_def;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( item.functions.size() == 2 &&
|
|
||||||
item.functions[0].parameters.empty() )
|
|
||||||
{
|
|
||||||
// it is:
|
|
||||||
// [def name function]
|
|
||||||
// or [def name function "funpar1" "funpar2"] etc.
|
|
||||||
|
|
||||||
item.type = Item::item_def;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveFilter(Item & item)
|
void PatternParser::ReadDirectiveFilter(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_filter;
|
item.type = Item::item_filter;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
if( item.functions.size() != 1 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveEzc(Item & item)
|
void PatternParser::ReadDirectiveEzc(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_ezc;
|
item.type = Item::item_ezc;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PatternParser::ReadDirectiveBlock(Item & item)
|
void PatternParser::ReadDirectiveBlock(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_block;
|
item.type = Item::item_block;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
// only one function without arguments
|
// only one function without arguments
|
||||||
if( item.functions.size() != 1 || !item.functions[0].parameters.empty() )
|
if( !item.function.parameters.empty() )
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,29 +805,10 @@ void PatternParser::ReadDirectiveBlock(Item & item)
|
||||||
void PatternParser::ReadDirectiveReturn(Item & item)
|
void PatternParser::ReadDirectiveReturn(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_return;
|
item.type = Item::item_return;
|
||||||
ReadFunctions(item);
|
ReadFunction(item);
|
||||||
|
|
||||||
// max one function
|
|
||||||
if( item.functions.size() > 1 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// user defined directive
|
|
||||||
void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
|
||||||
{
|
|
||||||
temp_function.Clear();
|
|
||||||
ReadParams(temp_function);
|
|
||||||
temp_function.name = name;
|
|
||||||
|
|
||||||
if( IsPositiveNumber(name) )
|
|
||||||
temp_function.arg = wcstol(name.c_str(), 0, 10);
|
|
||||||
|
|
||||||
item.functions.clear();
|
|
||||||
|
|
||||||
item.functions.push_back(temp_function);
|
|
||||||
item.type = Item::item_normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -822,11 +820,6 @@ std::wstring name;
|
||||||
ReadName(name);
|
ReadName(name);
|
||||||
|
|
||||||
if ( name == L"if" ) ReadDirectiveIf(item);
|
if ( name == L"if" ) ReadDirectiveIf(item);
|
||||||
else if( name == L"if-no" ) ReadDirectiveIfno(item);
|
|
||||||
else if( name == L"if-any" ) ReadDirectiveIfany(item);
|
|
||||||
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"end" ) ReadDirectiveEnd(item);
|
else if( name == L"end" ) ReadDirectiveEnd(item);
|
||||||
else if( name == L"else" ) ReadDirectiveElse(item);
|
else if( name == L"else" ) ReadDirectiveElse(item);
|
||||||
else if( name == L"for" ) ReadDirectiveFor(item);
|
else if( name == L"for" ) ReadDirectiveFor(item);
|
||||||
|
@ -837,8 +830,7 @@ std::wstring name;
|
||||||
else if( name == L"block" ) ReadDirectiveBlock(item);
|
else if( name == L"block" ) ReadDirectiveBlock(item);
|
||||||
else if( name == L"return" ) ReadDirectiveReturn(item);
|
else if( name == L"return" ) ReadDirectiveReturn(item);
|
||||||
else if( name == L"#" ) ReadDirectiveComment(item);
|
else if( name == L"#" ) ReadDirectiveComment(item);
|
||||||
else
|
else if( !name.empty() ) ReadDirectiveNormal(name, item);
|
||||||
ReadDirectiveNormal(name, item);
|
|
||||||
|
|
||||||
CreateTreeReadItemDirectiveCheckEnding(item);
|
CreateTreeReadItemDirectiveCheckEnding(item);
|
||||||
}
|
}
|
||||||
|
@ -950,8 +942,9 @@ Item item_block;
|
||||||
if( item_block.LastItemType() == Item::item_end )
|
if( item_block.LastItemType() == Item::item_end )
|
||||||
item_block.DeleteLastItem();
|
item_block.DeleteLastItem();
|
||||||
|
|
||||||
if( pblocks && item.functions.size()==1 )
|
//if( pblocks && item.functions.size()==1 )
|
||||||
pblocks->Insert(item.functions[0].name, item_block);
|
if( pblocks )
|
||||||
|
pblocks->Insert(item.function.name, item_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -993,13 +986,8 @@ void PatternParser::CreateTree(Item & item)
|
||||||
if( pitem->type == Item::item_end || pitem->type == Item::item_else )
|
if( pitem->type == Item::item_end || pitem->type == Item::item_else )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( pitem->type == Item::item_if ||
|
if( pitem->type == Item::item_if )
|
||||||
pitem->type == Item::item_ifno ||
|
CreateTreeReadIf(*pitem);
|
||||||
pitem->type == Item::item_ifany ||
|
|
||||||
pitem->type == Item::item_ifone ||
|
|
||||||
pitem->type == Item::item_ifanyno ||
|
|
||||||
pitem->type == Item::item_ifoneno )
|
|
||||||
CreateTreeReadIf(*pitem);
|
|
||||||
|
|
||||||
if( pitem->type == Item::item_for ||
|
if( pitem->type == Item::item_for ||
|
||||||
pitem->type == Item::item_filter )
|
pitem->type == Item::item_filter )
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
* Copyright (c) 2007-2015, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -130,9 +130,6 @@ private:
|
||||||
// temporary object for a file name
|
// temporary object for a file name
|
||||||
std::string afile_name;
|
std::string afile_name;
|
||||||
|
|
||||||
// temporary object for a EZC function's parameter
|
|
||||||
std::wstring temp_param;
|
|
||||||
|
|
||||||
// temporary object for a EZC function
|
// temporary object for a EZC function
|
||||||
Item::Function temp_function;
|
Item::Function temp_function;
|
||||||
|
|
||||||
|
@ -150,7 +147,9 @@ private:
|
||||||
int ReadCharInText();
|
int ReadCharInText();
|
||||||
bool IsWhite(wchar_t c);
|
bool IsWhite(wchar_t c);
|
||||||
void SkipWhite();
|
void SkipWhite();
|
||||||
|
void SkipOneStatement();
|
||||||
void CheckWhiteAndDelete(std::wstring & s);
|
void CheckWhiteAndDelete(std::wstring & s);
|
||||||
|
void CheckFunctionIsNumber(Item::Function & function);
|
||||||
|
|
||||||
bool IsNameChar(wchar_t c);
|
bool IsNameChar(wchar_t c);
|
||||||
bool IsDigit(wchar_t c);
|
bool IsDigit(wchar_t c);
|
||||||
|
@ -158,16 +157,13 @@ private:
|
||||||
|
|
||||||
bool ReadName(std::wstring & name);
|
bool ReadName(std::wstring & name);
|
||||||
bool ReadString(std::wstring & str);
|
bool ReadString(std::wstring & str);
|
||||||
|
bool ReadNestedFunction(Item::Function & function);
|
||||||
|
bool ReadParamString(Item::Function & function);
|
||||||
bool ReadParams(Item::Function & function);
|
bool ReadParams(Item::Function & function);
|
||||||
bool ReadFunction(Item::Function & function);
|
bool ReadFunction(Item::Function & function, bool with_params);
|
||||||
bool ReadFunctions(Item & item);
|
bool ReadFunction(Item & item);
|
||||||
|
|
||||||
void ReadDirectiveIf(Item & item);
|
void ReadDirectiveIf(Item & item);
|
||||||
void ReadDirectiveIfno(Item & item);
|
|
||||||
void ReadDirectiveIfany(Item & item);
|
|
||||||
void ReadDirectiveIfone(Item & item);
|
|
||||||
void ReadDirectiveIfanyno(Item & item);
|
|
||||||
void ReadDirectiveIfoneno(Item & item);
|
|
||||||
void ReadDirectiveEnd(Item & item);
|
void ReadDirectiveEnd(Item & item);
|
||||||
void ReadDirectiveElse(Item & item);
|
void ReadDirectiveElse(Item & item);
|
||||||
void ReadDirectiveFor(Item & item);
|
void ReadDirectiveFor(Item & item);
|
||||||
|
|
Loading…
Reference in New Issue