284 lines
6.8 KiB
C++
284 lines
6.8 KiB
C++
/*
|
|
* This file is a part of EZC -- Easy templating in C++ library
|
|
* and is distributed under the BSD 3-Clause licence.
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2007-2016, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
|
* project may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
|
|
#ifndef headerfile_ezc_funinfo
|
|
#define headerfile_ezc_funinfo
|
|
|
|
#include <vector>
|
|
#include "item.h"
|
|
|
|
|
|
|
|
namespace Ezc
|
|
{
|
|
|
|
/*
|
|
a variable
|
|
*/
|
|
struct Var
|
|
{
|
|
std::wstring str; // a string value
|
|
bool res; // a boolean value
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
a base class for your own function data class
|
|
*/
|
|
struct FunData
|
|
{
|
|
FunData()
|
|
{
|
|
}
|
|
|
|
virtual ~FunData()
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
a generator's stack item
|
|
each statement ([if ...] [for ...] [normal_funcion]) have its own stack item
|
|
iter - is used only in [for...] - it is the current iteration (start from zero)
|
|
for other statements it is always zero
|
|
fun_data - by default this is null pointer, you can set it to a pointer
|
|
to an object derived from FunData
|
|
(this have sense only in [for...] statement because in other statements
|
|
this object would be immediately removed)
|
|
auto_remove - when true it means that object pointing by fun_data and for_name should be automatically
|
|
removed -- (by using delete fun_data and delete for_name)
|
|
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 auto_remove;
|
|
bool is_for;
|
|
const Item * item;
|
|
|
|
|
|
Stack()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
~Stack()
|
|
{
|
|
if( auto_remove )
|
|
{
|
|
if( fun_data )
|
|
{
|
|
delete fun_data;
|
|
fun_data = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
iter = 0;
|
|
fun_data = 0;
|
|
auto_remove = true;
|
|
is_for = false;
|
|
item = 0;
|
|
}
|
|
};
|
|
|
|
|
|
// !! IMPROVE ME
|
|
// the name is bad
|
|
// may it should be called Env (environment) or FunEnv
|
|
template<class StreamType>
|
|
struct FunInfo
|
|
{
|
|
// a result consists of a string and a boolean value
|
|
// output stream
|
|
StreamType & out;
|
|
// return value from a user's function (default false if not set directly by the function)
|
|
bool res;
|
|
|
|
// table of parameters
|
|
// the table can be empty
|
|
std::vector<Var> & params;
|
|
|
|
// the first parameter
|
|
// you can always use it even if there are not any parameters (params is empty)
|
|
// in such a way the reference points to an empty string
|
|
const std::wstring & par;
|
|
|
|
// an input stream used in [filter] statement
|
|
// if there is other statement than [filter] then this is an empty stream
|
|
const StreamType & in;
|
|
|
|
// indicates that this function is from [for ...] statement
|
|
bool is_for;
|
|
|
|
// indicates that this function is from [if ...] statement
|
|
// it is true for all kind of if's: if-one, if-any, if-no....
|
|
bool is_if;
|
|
|
|
// 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)
|
|
// it indicates the number of a current iteration for the [for] statement (the first iteration is 0)
|
|
// for other statements than [for] this is always zero
|
|
size_t iter;
|
|
|
|
//
|
|
const Item & item;
|
|
|
|
|
|
|
|
// arguments: output_stream, table_of_parameters, the_first_parameter
|
|
FunInfo(StreamType & o,
|
|
std::vector<Var> & pars,
|
|
const std::wstring & first_par,
|
|
const StreamType & input_stream,
|
|
Stack & s,
|
|
const Item & item_) : out(o), params(pars), par(first_par), in(input_stream), stack(s), item(item_)
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
|
|
void Clear()
|
|
{
|
|
res = false; // result is false by default
|
|
is_for = false;
|
|
is_if = false;
|
|
is_normal = false;
|
|
is_filter = false;
|
|
iter = 0;
|
|
stack_tab = 0;
|
|
stack_index = 0;
|
|
}
|
|
|
|
/*
|
|
* CHECK ME can it be done only for [for] statements?
|
|
*
|
|
* can return a null pointer if there is no such an item on the stack
|
|
*
|
|
* add a function with const wchar_t *
|
|
*/
|
|
Stack * FindLastFor(const std::wstring & name)
|
|
{
|
|
for(size_t i = stack_index ; i > 0 ; --i)
|
|
{
|
|
if( stack_tab[i-1].is_for && stack_tab[i-1].item->has_function )
|
|
{
|
|
if( stack_tab[i-1].item->function.name == name )
|
|
{
|
|
return &stack_tab[i-1];
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix)
|
|
{
|
|
for(size_t i = stack_index ; i > 0 ; --i)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
template<class FunUserObject>
|
|
FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0)
|
|
{
|
|
Stack * stack;
|
|
|
|
if( item.has_function && item.function.is_function )
|
|
stack = FindLastFor(function_name, item.function.postfix);
|
|
else
|
|
stack = FindLastFor(function_name);
|
|
|
|
if( ezc_stack )
|
|
*ezc_stack = stack;
|
|
|
|
if( stack && stack->fun_data )
|
|
return dynamic_cast<FunUserObject*>(stack->fun_data);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace Ezc
|
|
|
|
|
|
#endif
|