[PATCH] Fix get_builtin_reader() and make it a bit simpler.
The code below seems to be too incorrect or at least too fragile enum { log, exp, // skipped NFUNCTIONS }; std::vector<function_options>::const_iterator it = registered_functions_hack::get_registered_functions().begin(); unsigned serial = 0; for ( ; serial<NFUNCTIONS; ++it, ++serial ) { prototype proto = make_pair(it->get_name(), it->get_nparams()); reader[proto] = encode_serial_as_reader_func(serial); } What happens if a user-defined function(s) get registered *before* "official" ones (so serials of built-in functions won't start from 0)? This can easily happen because the order of initialization in different compilation units is implementation defined. Or someone adds a built-in function and inserts REGISTER_FUNCTION_*P between REGISTER_FUNCTION_1P(log, ...) and REGISTER_FUNCTION_1P(exp, ...)? Or compiler decides to swap REGISTER_FUNCTION_1P(log, ...) and REGISTER_FUNCTION_1P(exp, ...)? The fix is simple: don't fiddle with serials, use the old (pre 1.5.2) approach, that is, let autogen produce the `reader functions' and use them to make a prototype_table. --- ginac/parser/builtin_fcns.def | 84 ++++++++++++++++++++++++++++++++++++++- ginac/parser/default_reader.tpl | 56 ++++---------------------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/ginac/parser/builtin_fcns.def b/ginac/parser/builtin_fcns.def index 96cd0a2..a7379d0 100644 --- a/ginac/parser/builtin_fcns.def +++ b/ginac/parser/builtin_fcns.def @@ -1,14 +1,96 @@ Autogen definitions ginacfcns; +function = { name = "log"; }; +function = { name = "exp"; }; +function = { name = "sin"; }; +function = { name = "cos"; }; +function = { name = "tan"; }; +function = { name = "asin"; }; +function = { name = "acos"; }; +function = { name = "atan"; }; + +function = { name = "sinh"; }; +function = { name = "cosh"; }; +function = { name = "tanh"; }; +function = { name = "asinh"; }; +function = { name = "acosh"; }; +function = { name = "atanh"; }; + +function = { + name = "atan2"; + args = 2; +}; + +function = { + name = "Li2"; + comment = "Dilogarithm"; +}; + +function = { + name = "Li3"; + comment = "Trilogarithm"; +}; + +function = { + name = "zetaderiv"; + comment = "Derivatives of Riemann's Zeta-function"; + args = 2; +}; + +function = { + name = "Li"; + args = 2; + comment = "Polylogarithm and multiple polylogarithm"; +}; + +function = { + name = "S"; + args = 3; + comment = "Nielsen's generalized polylogarithm"; +}; + +function = { + name = "H"; + args = 2; + comment = "Harmonic polylogarithm"; +}; + +function = { name = "lgamma"; }; +function = { name = "tgamma"; }; + +function = { + name = "beta"; + args = 2; + comment = "Beta-function"; +}; + +function = { name = "factorial"; }; + +function = { + name = "binomial"; + args = 2; +}; + +function = { + name = "Order"; + comment = "Order term function (for truncated power series)"; +}; + /* Thease are not functions, but anyway ... */ -function = { name = "sqrt"; }; +function = { + name = "sqrt"; + quasi = 1; +}; function = { name = "pow"; args = 2; + quasi = 1; }; function = { name = "power"; args = 2; + quasi = 1; }; + diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index e65802a..32f20f4 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -62,10 +62,10 @@ const prototype_table& get_default_reader() static bool initialized = false; static prototype_table reader; if (!initialized) { - [+ FOR function +] + [+ FOR function +][+ IF (exist? "quasi") +] reader[make_pair("[+ (get "name") +]", [+ (if (exist? "args") (get "args") "1") - +])] = [+ (get "name") +]_reader;[+ + +])] = [+ (get "name") +]_reader;[+ ENDIF +][+ ENDFOR +] std::vector<function_options>::const_iterator it = registered_functions_hack::get_registered_functions().begin(); @@ -87,51 +87,13 @@ const prototype_table& get_builtin_reader() using std::make_pair; static bool initialized = false; static prototype_table reader; - if (!initialized) { - [+ FOR function +] - reader[make_pair("[+ (get "name") +]", [+ - (if (exist? "args") (get "args") "1") - +])] = [+ (get "name") +]_reader;[+ - ENDFOR +] - enum { - log, - exp, - sin, - cos, - tan, - asin, - acos, - atan, - sinh, - cosh, - tanh, - asinh, - acosh, - atanh, - atan2, - Li2, - Li3, - zetaderiv, - Li, - S, - H, - lgamma, - tgamma, - beta, - factorial, - binomial, - Order, - NFUNCTIONS - }; - std::vector<function_options>::const_iterator it = - registered_functions_hack::get_registered_functions().begin(); - unsigned serial = 0; - for ( ; serial<NFUNCTIONS; ++it, ++serial ) { - prototype proto = make_pair(it->get_name(), it->get_nparams()); - reader[proto] = encode_serial_as_reader_func(serial); - } - initialized = true; - } + if (initialized) + return reader; + [+ FOR function +] + reader[make_pair("[+ (get "name") +]", [+ + (if (exist? "args") (get "args") "1") + +])] = [+ (get "name") +]_reader;[+ + ENDFOR +] return reader; } -- 1.6.3.3
participants (1)
-
Alexei Sheplyakov