[PATCH] Fix get_builtin_reader() and make it a bit simpler.

View: New views
1 Messages — Rating Filter:   Alert me  

[PATCH] Fix get_builtin_reader() and make it a bit simpler.

by Alexei Sheplyakov-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

_______________________________________________
GiNaC-devel mailing list
GiNaC-devel@...
https://www.cebix.net/mailman/listinfo/ginac-devel