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:
Tomasz Sowa 2016-04-04 15:53:11 +00:00
parent 18696d412b
commit 363605bde5
6 changed files with 71 additions and 36 deletions

View File

@ -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

View File

@ -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 )
{
if( stack_tab[i-1].item->function.name == name )
{
return &stack_tab[i-1]; 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;
} }
}; };

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);