From 363605bde5c81a9eb6db1d42307fcc1e027c43f6 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 4 Apr 2016 15:53:11 +0000 Subject: [PATCH] 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 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 --- COPYRIGHT | 2 +- src/funinfo.h | 62 ++++++++++++++++++++++++++++++------------- src/generator.h | 9 ++++--- src/item.h | 5 +++- src/patternparser.cpp | 24 ++++++++++------- src/patternparser.h | 5 ++-- 6 files changed, 71 insertions(+), 36 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index e1bfa3a..fc27480 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (c) 2007-2015, Tomasz Sowa +Copyright (c) 2007-2016, Tomasz Sowa All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/funinfo.h b/src/funinfo.h index 68da521..2ecc90f 100644 --- a/src/funinfo.h +++ b/src/funinfo.h @@ -40,6 +40,7 @@ #define headerfile_ezc_funinfo #include +#include "item.h" @@ -94,8 +95,8 @@ struct Stack FunData * fun_data; bool auto_remove; bool is_for; + const Item * item; - std::wstring * for_name; // !! IMPROVE ME give a better name Stack() { @@ -111,12 +112,6 @@ struct Stack delete fun_data; fun_data = 0; } - - if( for_name ) - { - delete for_name; - for_name = 0; - } } } @@ -124,9 +119,9 @@ struct Stack { iter = 0; fun_data = 0; - for_name = 0; auto_remove = true; is_for = false; + item = 0; } }; @@ -187,13 +182,18 @@ struct FunInfo // 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 & pars, const std::wstring & first_par, 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(); } @@ -222,32 +222,56 @@ struct FunInfo { for(size_t i = stack_index ; i > 0 ; --i) { - if( stack_tab[i-1].for_name && *stack_tab[i-1].for_name == name ) - return &stack_tab[i-1]; + 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() + + Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix) { - if( !params.empty() ) - return FindLastFor(params[0].str); // or last item? + 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; } - Stack * FindLastFor(const std::wstring & first_name, const std::wstring & second_name) + + template + FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0) { - if( !first_name.empty() ) - return FindLastFor(first_name); + Stack * stack; + + if( item.has_function && item.function.is_function ) + stack = FindLastFor(function_name, item.function.postfix); else - if( !second_name.empty() ) - return FindLastFor(second_name); + stack = FindLastFor(function_name); + + if( ezc_stack ) + *ezc_stack = stack; + + if( stack && stack->fun_data ) + return dynamic_cast(stack->fun_data); return 0; } + }; diff --git a/src/generator.h b/src/generator.h index e9d65ef..0ebaf04 100644 --- a/src/generator.h +++ b/src/generator.h @@ -963,12 +963,12 @@ void Generator::CallFunction(typename Functions::UserFun { if( parameters.empty() ) { - FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1]); + FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallFunction(function, info); } else { - FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1]); + FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallFunction(function, info); } } @@ -1008,12 +1008,12 @@ void Generator::CallObject(BaseObj * base_obj, { if( parameters.empty() ) { - FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1]); + FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallObject(base_obj, method_index, info); } else { - FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1]); + FunInfo 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); } } @@ -1734,6 +1734,7 @@ void Generator::MakeText(Item & item) is_generating_filter = false; stack_tab[stack_index-1].Clear(); + stack_tab[stack_index-1].item = &item; if ( item.type == Item::item_text ) MakeItemText(item); else if( item.type == Item::item_container )MakeTextContainer(item); diff --git a/src/item.h b/src/item.h index 7570880..741c44c 100644 --- a/src/item.h +++ b/src/item.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2015, Tomasz Sowa + * Copyright (c) 2007-2016, Tomasz Sowa * All rights reserved. * * 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 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 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 void * fun_cache; // only valid if is_function is true @@ -122,6 +124,7 @@ struct Item parameters.clear(); name.clear(); + postfix.clear(); fun_cache = 0; item_block = 0; base_obj = 0; diff --git a/src/patternparser.cpp b/src/patternparser.cpp index 1c2ef3f..aedb7a1 100644 --- a/src/patternparser.cpp +++ b/src/patternparser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2015, Tomasz Sowa + * Copyright (c) 2007-2016, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -499,7 +499,6 @@ return true; bool PatternParser::ReadName(std::wstring & name) { name.clear(); - SkipWhite(); while( IsNameChar(*itext) ) { @@ -638,15 +637,26 @@ return res; /* 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(); function.Clear(); function.is_function = true; + if( function_name ) + { + function.name = *function_name; + } + else if( !ReadName(function.name) ) return false; + if( *itext == ':' ) + { + itext += 1; + ReadName(function.postfix); // we allow the postfix to be empty + } + CheckFunctionIsNumber(function); if( with_params ) @@ -707,12 +717,7 @@ 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) ) + if( !ReadFunction(item.function, true, &name) ) { item.type = Item::item_err; item.function.Clear(); @@ -840,6 +845,7 @@ void PatternParser::CreateTreeReadItemDirective(Item & item) std::wstring name; ++itext; + SkipWhite(); ReadName(name); if ( name == L"if" ) ReadDirectiveIf(item); diff --git a/src/patternparser.h b/src/patternparser.h index e692d8b..fcd9b0c 100644 --- a/src/patternparser.h +++ b/src/patternparser.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2015, Tomasz Sowa + * Copyright (c) 2007-2016, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -152,11 +152,12 @@ private: bool IsPositiveNumber(const std::wstring & str); bool ReadName(std::wstring & name); + bool ReadFunctionName(std::wstring & name, std::wstring & postfix); bool ReadString(std::wstring & str); bool ReadNestedFunction(Item::Function & function); bool ReadParamString(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); void ReadDirectiveIf(Item & item);