changed: a function can have a postfix now e.g. [my_function:my_postfix]
this will be mainly used in conjuction with [for ...] statements [for my_function:xxx] [for my_function] [my_function_value] [my_function_valu:xxx] (references the first loop) [end] [end] added: to FunInfo<>: a reference to current item from a pattern (const Item & item) similary on the stack is added a pointer to an item by having this reference you can compare a function's name and its postfix added methods: Stack * FindLastFor(const std::wstring & name); Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix); template<class FunUserObject> FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0); git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@1038 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
18696d412b
commit
363605bde5
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2007-2015, Tomasz Sowa
|
Copyright (c) 2007-2016, 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
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#define headerfile_ezc_funinfo
|
#define headerfile_ezc_funinfo
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "item.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,8 +95,8 @@ struct Stack
|
||||||
FunData * fun_data;
|
FunData * fun_data;
|
||||||
bool auto_remove;
|
bool auto_remove;
|
||||||
bool is_for;
|
bool is_for;
|
||||||
|
const Item * item;
|
||||||
|
|
||||||
std::wstring * for_name; // !! IMPROVE ME give a better name
|
|
||||||
|
|
||||||
Stack()
|
Stack()
|
||||||
{
|
{
|
||||||
|
@ -111,12 +112,6 @@ struct Stack
|
||||||
delete fun_data;
|
delete fun_data;
|
||||||
fun_data = 0;
|
fun_data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( for_name )
|
|
||||||
{
|
|
||||||
delete for_name;
|
|
||||||
for_name = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,9 +119,9 @@ struct Stack
|
||||||
{
|
{
|
||||||
iter = 0;
|
iter = 0;
|
||||||
fun_data = 0;
|
fun_data = 0;
|
||||||
for_name = 0;
|
|
||||||
auto_remove = true;
|
auto_remove = true;
|
||||||
is_for = false;
|
is_for = false;
|
||||||
|
item = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,13 +182,18 @@ struct FunInfo
|
||||||
// for other statements than [for] this is always zero
|
// for other statements than [for] this is always zero
|
||||||
size_t iter;
|
size_t iter;
|
||||||
|
|
||||||
|
//
|
||||||
|
const Item & item;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// arguments: output_stream, table_of_parameters, the_first_parameter
|
// arguments: output_stream, table_of_parameters, the_first_parameter
|
||||||
FunInfo(StreamType & o,
|
FunInfo(StreamType & o,
|
||||||
std::vector<Var> & pars,
|
std::vector<Var> & pars,
|
||||||
const std::wstring & first_par,
|
const std::wstring & first_par,
|
||||||
const StreamType & input_stream,
|
const StreamType & input_stream,
|
||||||
Stack & s) : out(o), params(pars), par(first_par), in(input_stream), stack(s)
|
Stack & s,
|
||||||
|
const Item & item_) : out(o), params(pars), par(first_par), in(input_stream), stack(s), item(item_)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -222,32 +222,56 @@ struct FunInfo
|
||||||
{
|
{
|
||||||
for(size_t i = stack_index ; i > 0 ; --i)
|
for(size_t i = stack_index ; i > 0 ; --i)
|
||||||
{
|
{
|
||||||
if( stack_tab[i-1].for_name && *stack_tab[i-1].for_name == name )
|
if( stack_tab[i-1].is_for && stack_tab[i-1].item->has_function )
|
||||||
return &stack_tab[i-1];
|
{
|
||||||
|
if( stack_tab[i-1].item->function.name == name )
|
||||||
|
{
|
||||||
|
return &stack_tab[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack * FindLastFor()
|
|
||||||
|
Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix)
|
||||||
{
|
{
|
||||||
if( !params.empty() )
|
for(size_t i = stack_index ; i > 0 ; --i)
|
||||||
return FindLastFor(params[0].str); // or last item?
|
{
|
||||||
|
if( stack_tab[i-1].is_for && stack_tab[i-1].item->has_function )
|
||||||
|
{
|
||||||
|
if( stack_tab[i-1].item->function.name == name && stack_tab[i-1].item->function.postfix == postfix )
|
||||||
|
{
|
||||||
|
return &stack_tab[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack * FindLastFor(const std::wstring & first_name, const std::wstring & second_name)
|
|
||||||
|
template<class FunUserObject>
|
||||||
|
FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0)
|
||||||
{
|
{
|
||||||
if( !first_name.empty() )
|
Stack * stack;
|
||||||
return FindLastFor(first_name);
|
|
||||||
|
if( item.has_function && item.function.is_function )
|
||||||
|
stack = FindLastFor(function_name, item.function.postfix);
|
||||||
else
|
else
|
||||||
if( !second_name.empty() )
|
stack = FindLastFor(function_name);
|
||||||
return FindLastFor(second_name);
|
|
||||||
|
if( ezc_stack )
|
||||||
|
*ezc_stack = stack;
|
||||||
|
|
||||||
|
if( stack && stack->fun_data )
|
||||||
|
return dynamic_cast<FunUserObject*>(stack->fun_data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -963,12 +963,12 @@ void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFun
|
||||||
{
|
{
|
||||||
if( parameters.empty() )
|
if( parameters.empty() )
|
||||||
{
|
{
|
||||||
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1]);
|
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||||
CallFunction(function, info);
|
CallFunction(function, info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1]);
|
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||||
CallFunction(function, info);
|
CallFunction(function, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1008,12 +1008,12 @@ void Generator<StreamType>::CallObject(BaseObj<StreamType> * base_obj,
|
||||||
{
|
{
|
||||||
if( parameters.empty() )
|
if( parameters.empty() )
|
||||||
{
|
{
|
||||||
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1]);
|
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||||
CallObject(base_obj, method_index, info);
|
CallObject(base_obj, method_index, info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1]);
|
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||||
CallObject(base_obj, method_index, info);
|
CallObject(base_obj, method_index, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1734,6 +1734,7 @@ void Generator<StreamType>::MakeText(Item & item)
|
||||||
is_generating_filter = false;
|
is_generating_filter = false;
|
||||||
|
|
||||||
stack_tab[stack_index-1].Clear();
|
stack_tab[stack_index-1].Clear();
|
||||||
|
stack_tab[stack_index-1].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);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Tomasz Sowa
|
* Copyright (c) 2007-2016, 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
|
||||||
|
@ -63,6 +63,8 @@ struct Item
|
||||||
{
|
{
|
||||||
bool is_function; // if true then we have a function parameter, if false then we have a string parameter
|
bool is_function; // if true then we have a function parameter, if false then we have a string parameter
|
||||||
std::wstring name; // a function or parameter name
|
std::wstring name; // a function or parameter name
|
||||||
|
std::wstring postfix; // a function can have an additional postfix in its name
|
||||||
|
// e.g. [my_function:my_postfix]
|
||||||
std::vector<Function*> parameters; // if is_function is true then it is a function and can have 'parameters'
|
std::vector<Function*> parameters; // if is_function is true then it is a function and can have 'parameters'
|
||||||
// if is_functino is empty then 'parameters' is empty too
|
// if is_functino is empty then 'parameters' is empty too
|
||||||
void * fun_cache; // only valid if is_function is true
|
void * fun_cache; // only valid if is_function is true
|
||||||
|
@ -122,6 +124,7 @@ struct Item
|
||||||
|
|
||||||
parameters.clear();
|
parameters.clear();
|
||||||
name.clear();
|
name.clear();
|
||||||
|
postfix.clear();
|
||||||
fun_cache = 0;
|
fun_cache = 0;
|
||||||
item_block = 0;
|
item_block = 0;
|
||||||
base_obj = 0;
|
base_obj = 0;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Tomasz Sowa
|
* Copyright (c) 2007-2016, 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
|
||||||
|
@ -499,7 +499,6 @@ return true;
|
||||||
bool PatternParser::ReadName(std::wstring & name)
|
bool PatternParser::ReadName(std::wstring & name)
|
||||||
{
|
{
|
||||||
name.clear();
|
name.clear();
|
||||||
SkipWhite();
|
|
||||||
|
|
||||||
while( IsNameChar(*itext) )
|
while( IsNameChar(*itext) )
|
||||||
{
|
{
|
||||||
|
@ -638,15 +637,26 @@ return res;
|
||||||
/*
|
/*
|
||||||
returns true if it correctly reads all parameters
|
returns true if it correctly reads all parameters
|
||||||
*/
|
*/
|
||||||
bool PatternParser::ReadFunction(Item::Function & function, bool with_params)
|
bool PatternParser::ReadFunction(Item::Function & function, bool with_params, const std::wstring * function_name)
|
||||||
{
|
{
|
||||||
SkipWhite();
|
SkipWhite();
|
||||||
function.Clear();
|
function.Clear();
|
||||||
function.is_function = true;
|
function.is_function = true;
|
||||||
|
|
||||||
|
if( function_name )
|
||||||
|
{
|
||||||
|
function.name = *function_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
if( !ReadName(function.name) )
|
if( !ReadName(function.name) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if( *itext == ':' )
|
||||||
|
{
|
||||||
|
itext += 1;
|
||||||
|
ReadName(function.postfix); // we allow the postfix to be empty
|
||||||
|
}
|
||||||
|
|
||||||
CheckFunctionIsNumber(function);
|
CheckFunctionIsNumber(function);
|
||||||
|
|
||||||
if( with_params )
|
if( with_params )
|
||||||
|
@ -707,12 +717,7 @@ void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
||||||
item.type = Item::item_function;
|
item.type = Item::item_function;
|
||||||
item.has_function = true;
|
item.has_function = true;
|
||||||
|
|
||||||
item.function.Clear();
|
if( !ReadFunction(item.function, true, &name) )
|
||||||
item.function.name = name;
|
|
||||||
item.function.is_function = true;
|
|
||||||
CheckFunctionIsNumber(item.function);
|
|
||||||
|
|
||||||
if( !ReadParams(item.function) )
|
|
||||||
{
|
{
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_err;
|
||||||
item.function.Clear();
|
item.function.Clear();
|
||||||
|
@ -840,6 +845,7 @@ void PatternParser::CreateTreeReadItemDirective(Item & item)
|
||||||
std::wstring name;
|
std::wstring name;
|
||||||
|
|
||||||
++itext;
|
++itext;
|
||||||
|
SkipWhite();
|
||||||
ReadName(name);
|
ReadName(name);
|
||||||
|
|
||||||
if ( name == L"if" ) ReadDirectiveIf(item);
|
if ( name == L"if" ) ReadDirectiveIf(item);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2015, Tomasz Sowa
|
* Copyright (c) 2007-2016, 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
|
||||||
|
@ -152,11 +152,12 @@ private:
|
||||||
bool IsPositiveNumber(const std::wstring & str);
|
bool IsPositiveNumber(const std::wstring & str);
|
||||||
|
|
||||||
bool ReadName(std::wstring & name);
|
bool ReadName(std::wstring & name);
|
||||||
|
bool ReadFunctionName(std::wstring & name, std::wstring & postfix);
|
||||||
bool ReadString(std::wstring & str);
|
bool ReadString(std::wstring & str);
|
||||||
bool ReadNestedFunction(Item::Function & function);
|
bool ReadNestedFunction(Item::Function & function);
|
||||||
bool ReadParamString(Item::Function & function);
|
bool ReadParamString(Item::Function & function);
|
||||||
bool ReadParams(Item::Function & function);
|
bool ReadParams(Item::Function & function);
|
||||||
bool ReadFunction(Item::Function & function, bool with_params);
|
bool ReadFunction(Item::Function & function, bool with_params, const std::wstring * function_name = 0);
|
||||||
bool ReadFunction(Item & item);
|
bool ReadFunction(Item & item);
|
||||||
|
|
||||||
void ReadDirectiveIf(Item & item);
|
void ReadDirectiveIf(Item & item);
|
||||||
|
|
Loading…
Reference in New Issue