[GiNaC-devel] [PATCH] Fix get_builtin_reader() and make it a bit simpler.
Alexei Sheplyakov
varg at metalica.kh.ua
Mon Aug 10 21:22:52 CEST 2009
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
More information about the GiNaC-devel
mailing list