including the user defined ones.
To this end a method has been added to class function to allow the
modified get_default_reader() function to build up a complete prototype
table. The autogen tool is no longer required.
is missing there.
If you install from git, you also need GNU autoconf (>=2.59), automake (>=1.8),
-libtool (>= 1.5), bison (>= 2.3), flex (>= 2.5.33), autogen (>= 5.6.0) to be
-installed.
+libtool (>= 1.5), bison (>= 2.3), flex (>= 2.5.33) to be installed.
INSTALLATION
AC_PATH_PROG(FIG2DEV, fig2dev, "")
AM_CONDITIONAL(CONFIG_FIG2DEV, [test ! -z "$FIG2DEV"])
-dnl generate boilerplate code for the (new) parser.
-dnl Only developers need this tool.
-AC_PATH_PROG(AUTOGEN, autogen, "")
-
dnl Output makefiles etc.
AC_CONFIG_FILES([
Makefile
parser/parse_binop_rhs.cpp \
parser/parser.cpp \
parser/parse_context.cpp \
- parser/builtin_fcns.cpp \
parser/lexer.cpp \
parser/lexer.h \
parser/parser_compat.cpp \
parser/parser.h \
parser/parse_context.h
-EXTRA_DIST = function.pl version.h.in \
-parser/default_reader.tpl parser/builtin_fcns.def
-
-# Files produced by autogen(1) from templates
-$(srcdir)/parser/builtin_fcns.cpp: $(srcdir)/parser/builtin_fcns.def $(srcdir)/parser/default_reader.tpl
- set -e; if [ -n "$(AUTOGEN)" ]; then \
- cd $(srcdir)/parser; \
- $(AUTOGEN) -T default_reader.tpl builtin_fcns.def; \
- elif [ -f $@ ]; then \
- echo "WARNING: AutoGen is not available, the \"$@\" file WON'T be re-generated"; \
- else \
- echo "*** ERROR: the \"$@\" file does not exist, and AutoGen is not installed on your system"; \
- echo "*** Please install AutoGen (http://www.gnu.org/software/autogen)"; \
- exit 1; \
- fi
-
+EXTRA_DIST = function.pl version.h.in
# Files which are generated by perl scripts
$(srcdir)/function.h $(srcdir)/function.cpp: $(srcdir)/function.pl
static unsigned register_new(function_options const & opt);
static unsigned current_serial;
static unsigned find_function(const std::string &name, unsigned nparams);
+ static std::vector<function_options> get_registered_functions() { return registered_functions(); };
unsigned get_serial() const {return serial;}
std::string get_name() const;
+++ /dev/null
-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 = "pow";
- args = 2;
-};
-
-function = {
- name = "power";
- args = 2;
-};
+++ /dev/null
-[+ AutoGen5 template .cpp +][+
-COMMENT a part of GiNaC parser -- construct functions from a byte stream.
-+][+
-(use-modules (ice-9 format))
-
-(define (sequence start end . step)
- (let ((step (if (null? step) 1 (car step))))
- (let loop ((n start))
- (if (> n end) '() (cons n (loop (+ step n)))))))
-+]/*
-[+ (dne " * " " * " ) +]
- *
- * If you want to change this file, edit either `[+ (def-file) +]' or
- * `[+ (tpl-file) +]' file, and run the following command:
- *
- * autogen -T [+ (tpl-file) +] [+ (def-file) +]
- */
-#include "parse_context.h"
-#include "power.h"
-#include "operators.h"
-#include "inifcns.h"
-
-namespace GiNaC
-{
-[+ FOR function +]
-static ex [+ (get "name") +]_reader(const exvector& ev)
-{
- return GiNaC::[+ (get "name") +]([+
- (let ((nargs (if (exist? "args")
- (string->number (get "args")) 1)))
- (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
-}[+ ENDFOR +]
-
-const prototype_table& get_default_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 +]
- initialized = true;
- }
- return reader;
-}
-} // namespace GiNaC
-
#include "parse_context.h"
+#include "function.h"
+
#include <sstream>
#include <stdexcept>
return sy;
}
+const prototype_table& get_default_reader(bool force_init)
+{
+ using std::make_pair;
+ static bool initialized = false;
+ static prototype_table reader;
+ if ( !initialized || force_init ) {
+ std::vector<function_options> flist = function::get_registered_functions();
+ std::vector<function_options>::iterator i = flist.begin(), end = flist.end();
+ for ( ; i != end; ++i ) {
+ std::string name = i->get_name();
+ unsigned narg = i->get_nparams();
+ reader[make_pair(name, narg)] = function::find_function(name, narg);
+ }
+ initialized = true;
+ }
+ return reader;
+}
+
} // namespace GiNaC
* foo(x+y, z^2, t)), it looks up such a table to find out which
* function (or class) corresponds to the given name and has the given
* number of the arguments.
- *
- * N.B.
- *
- * 1. The function don't have to return a (GiNaC) function or class, it
- * can return any expression.
- * 2. Overloaded functions/ctors are paritally supported, i.e. there might
- * be several functions with the same name, but they should take different
- * number of arguments.
- * 3. User can extend the parser via custom prototype tables. It's possible
- * to read user defined classes, create abbreviations, etc.
*/
-typedef std::map<prototype, reader_func> prototype_table;
+typedef std::map<prototype, unsigned> prototype_table;
/**
- * Default prototype table.
+ * Creates a default prototype table containing all defined GiNaC functions.
*
- * It supports most of builtin GiNaC functions.
+ * The data referenced by the return value is only created once when this
+ * function is called for the first time. This might cause problems in very
+ * rare stituations (i.e. if functions are added after this first call). In
+ * that case, a new initialization can be forced with an "true" argument.
*/
-extern const prototype_table& get_default_reader();
+extern const prototype_table& get_default_reader(bool force_init = false);
} // namespace GiNaC
#include "lexer.h"
#include "debug.h"
#include "mul.h"
+#include "function.h"
#include "constant.h"
#include <sstream>
Parse_error_("no function \"" << name << "\" with " <<
args.size() << " arguments");
}
- ex ret = reader->second(args);
+ ex ret = function(reader->second, args);
return ret;
}