X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Ffunction.pl;h=6b25c70df7203cba947af9518ff7019079f4136c;hp=5397d8db703679208b51875d0cabb5e5f80bf351;hb=bb76e4b38b330365934e1b14d2feb2bad416f455;hpb=757406e244f4f257aafaa0f355d5376122cea10e diff --git a/ginac/function.pl b/ginac/function.pl index 5397d8db..6b25c70d 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -1,4 +1,24 @@ -$maxargs=13; +# This perl script automatically generates function.h and function.cpp + +# function.pl options: \$maxargs=${maxargs} +# +# GiNaC Copyright (C) 1999-2004 Johannes Gutenberg University Mainz, Germany +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +$maxargs=14; sub generate_seq { my ($seq_template,$n)=@_; @@ -54,6 +74,10 @@ $typedef_evalf_funcp=generate( 'typedef ex (* evalf_funcp_${N})(${SEQ1});'."\n", 'const ex &','',''); +$typedef_conjugate_funcp=generate( +'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n", +'const ex &','',''); + $typedef_derivative_funcp=generate( 'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n", 'const ex &','',''); @@ -62,14 +86,30 @@ $typedef_series_funcp=generate( 'typedef ex (* series_funcp_${N})(${SEQ1}, const relational &, int, unsigned);'."\n", 'const ex &','',''); +$typedef_print_funcp=generate( +'typedef void (* print_funcp_${N})(${SEQ1}, const print_context &);'."\n", +'const ex &','',''); + $eval_func_interface=generate(' function_options & eval_func(eval_funcp_${N} e);'."\n",'','',''); $evalf_func_interface=generate(' function_options & evalf_func(evalf_funcp_${N} ef);'."\n",'','',''); +$conjugate_func_interface=generate(' function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','',''); + $derivative_func_interface=generate(' function_options & derivative_func(derivative_funcp_${N} d);'."\n",'','',''); $series_func_interface=generate(' function_options & series_func(series_funcp_${N} s);'."\n",'','',''); +$print_func_interface=generate( + <<'END_OF_PRINT_FUNC_INTERFACE','','',''); + template function_options & print_func(print_funcp_${N} p) + { + test_and_set_nparams(${N}); + set_print_func(Ctx::get_class_info_static().options.get_id(), print_funcp(p)); + return *this; + } +END_OF_PRINT_FUNC_INTERFACE + $constructors_interface=generate( ' function(unsigned ser, ${SEQ1});'."\n", 'const ex & param${N}','',''); @@ -86,33 +126,46 @@ END_OF_CONSTRUCTORS_IMPLEMENTATION $eval_switch_statement=generate( <<'END_OF_EVAL_SWITCH_STATEMENT','seq[${N}-1]','',''); case ${N}: - eval_result = ((eval_funcp_${N})(registered_functions()[serial].eval_f))(${SEQ1}); + eval_result = ((eval_funcp_${N})(opt.eval_f))(${SEQ1}); break; END_OF_EVAL_SWITCH_STATEMENT $evalf_switch_statement=generate( <<'END_OF_EVALF_SWITCH_STATEMENT','eseq[${N}-1]','',''); case ${N}: - return ((evalf_funcp_${N})(registered_functions()[serial].evalf_f))(${SEQ1}); + return ((evalf_funcp_${N})(opt.evalf_f))(${SEQ1}); END_OF_EVALF_SWITCH_STATEMENT +$conjugate_switch_statement=generate( + <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); + case ${N}: + return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1}); +END_OF_DIFF_SWITCH_STATEMENT + $diff_switch_statement=generate( <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); case ${N}: - return ((derivative_funcp_${N})(registered_functions()[serial].derivative_f))(${SEQ1},diff_param); + return ((derivative_funcp_${N})(opt.derivative_f))(${SEQ1},diff_param); END_OF_DIFF_SWITCH_STATEMENT $series_switch_statement=generate( <<'END_OF_SERIES_SWITCH_STATEMENT','seq[${N}-1]','',''); case ${N}: try { - res = ((series_funcp_${N})(registered_functions()[serial].series_f))(${SEQ1},r,order,options); + res = ((series_funcp_${N})(opt.series_f))(${SEQ1},r,order,options); } catch (do_taylor) { res = basic::series(r, order, options); } return res; END_OF_SERIES_SWITCH_STATEMENT +$print_switch_statement=generate( + <<'END_OF_PRINT_SWITCH_STATEMENT','seq[${N}-1]','',''); + case ${N}: + ((print_funcp_${N})(pdt[id]))(${SEQ1}, c); + break; +END_OF_PRINT_SWITCH_STATEMENT + $eval_func_implementation=generate( <<'END_OF_EVAL_FUNC_IMPLEMENTATION','','',''); function_options & function_options::eval_func(eval_funcp_${N} e) @@ -133,6 +186,16 @@ function_options & function_options::evalf_func(evalf_funcp_${N} ef) } END_OF_EVALF_FUNC_IMPLEMENTATION +$conjugate_func_implementation=generate( + <<'END_OF_CONJUGATE_FUNC_IMPLEMENTATION','','',''); +function_options & function_options::conjugate_func(conjugate_funcp_${N} c) +{ + test_and_set_nparams(${N}); + conjugate_f = conjugate_funcp(c); + return *this; +} +END_OF_CONJUGATE_FUNC_IMPLEMENTATION + $derivative_func_implementation=generate( <<'END_OF_DERIVATIVE_FUNC_IMPLEMENTATION','','',''); function_options & function_options::derivative_func(derivative_funcp_${N} d) @@ -163,7 +226,7 @@ $interface=< function_options & print_func(print_funcp_exvector p) + { + print_use_exvector_args = true; + set_print_func(Ctx::get_class_info_static().options.get_id(), print_funcp(p)); + return *this; + } + function_options & set_return_type(unsigned rt, unsigned rtt=0); function_options & do_not_evalf_params(); function_options & remember(unsigned size, unsigned assoc_size=0, unsigned strategy=remember_strategies::delete_never); function_options & overloaded(unsigned o); function_options & set_symmetry(const symmetry & s); - void test_and_set_nparams(unsigned n); + std::string get_name() const { return name; } unsigned get_nparams() const { return nparams; } - bool has_derivative() const { return derivative_f != NULL; } protected: + bool has_derivative() const { return derivative_f != NULL; } + void test_and_set_nparams(unsigned n); + void set_print_func(unsigned id, print_funcp f); + std::string name; std::string TeX_name; @@ -265,8 +349,10 @@ protected: eval_funcp eval_f; evalf_funcp evalf_f; + conjugate_funcp conjugate_f; derivative_funcp derivative_f; series_funcp series_f; + std::vector print_dispatch_table; bool evalf_params_first; @@ -281,8 +367,10 @@ protected: bool eval_use_exvector_args; bool evalf_use_exvector_args; + bool conjugate_use_exvector_args; bool derivative_use_exvector_args; bool series_use_exvector_args; + bool print_use_exvector_args; unsigned functions_with_same_name; @@ -320,7 +408,7 @@ $constructors_interface // end of generated lines function(unsigned ser, const exprseq & es); function(unsigned ser, const exvector & v, bool discardable = false); - function(unsigned ser, exvector * vp); // vp will be deleted + function(unsigned ser, std::auto_ptr vp); // functions overriding virtual functions from base classes public: @@ -332,7 +420,8 @@ public: unsigned calchash() const; ex series(const relational & r, int order, unsigned options = 0) const; ex thiscontainer(const exvector & v) const; - ex thiscontainer(exvector * vp) const; + ex thiscontainer(std::auto_ptr vp) const; + ex conjugate() const; protected: ex derivative(const symbol & s) const; bool is_equal_same_type(const basic & other) const; @@ -396,7 +485,7 @@ $implementation=<= print_dispatch_table.size()) + print_dispatch_table.resize(id + 1); + print_dispatch_table[id] = f; +} + /** This can be used as a hook for external applications. */ unsigned function::current_serial = 0; @@ -616,7 +721,7 @@ function::function(unsigned ser, const exvector & v, bool discardable) tinfo_key = TINFO_function; } -function::function(unsigned ser, exvector * vp) +function::function(unsigned ser, std::auto_ptr vp) : exprseq(vp), serial(ser) { tinfo_key = TINFO_function; @@ -669,44 +774,67 @@ void function::archive(archive_node &n) const void function::print(const print_context & c, unsigned level) const { GINAC_ASSERT(serial &pdt = opt.print_dispatch_table; - if (is_a(c)) { - - c.s << std::string(level, ' ') << class_name() << " " - << registered_functions()[serial].name - << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec - << ", nops=" << nops() - << std::endl; - unsigned delta_indent = static_cast(c).delta_indent; - for (size_t i=0; i(c)) { +next_context: + unsigned id = pc_info->options.get_id(); + if (id >= pdt.size() || pdt[id] == NULL) { - // Print function name in lowercase - std::string lname = registered_functions()[serial].name; - size_t num = lname.size(); - for (size_t i=0; iget_parent(); + if (parent_pc_info) { + pc_info = parent_pc_info; + goto next_context; + } - // Print arguments, separated by commas - exvector::const_iterator it = seq.begin(), itend = seq.end(); - while (it != itend) { - it->print(c); - ++it; - if (it != itend) - c.s << ","; + // Method still not found, use default output + if (is_a(c)) { + + c.s << std::string(level, ' ') << class_name() << " " + << opt.name << " @" << this + << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec + << ", nops=" << nops() + << std::endl; + unsigned delta_indent = static_cast(c).delta_indent; + for (size_t i=0; i(c)) { + + // Print function name in lowercase + std::string lname = opt.name; + size_t num = lname.size(); + for (size_t i=0; i(c)) { + c.s << opt.TeX_name; + printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence()); + } else { + c.s << opt.name; + printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence()); } - c.s << ")"; - } else if (is_a(c)) { - c.s << registered_functions()[serial].TeX_name; - printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence()); } else { - c.s << registered_functions()[serial].name; - printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence()); + + // Method found, call it + current_serial = serial; + if (opt.print_use_exvector_args) + ((print_funcp_exvector)pdt[id])(seq, c); + else switch (opt.nparams) { + // the following lines have been generated for max. ${maxargs} parameters +${print_switch_statement} + // end of generated lines + default: + throw(std::logic_error("function::print(): invalid nparams")); + } } } @@ -721,13 +849,12 @@ ex function::expand(unsigned options) const ex function::eval(int level) const { - GINAC_ASSERT(serial1) { // first evaluate children, then we will end up here again return function(serial,evalchildren(level)); } + GINAC_ASSERT(serial vp) const { - return function(serial,vp); + return function(serial, vp); } /** Implementation of ex::series for functions. @@ -835,21 +961,22 @@ ex function::thiscontainer(exvector * vp) const ex function::series(const relational & r, int order, unsigned options) const { GINAC_ASSERT(serial