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) to be installed.
+libtool (>= 1.5), bison (>= 2.3), flex (>= 2.5.33), autogen (>= 5.6.0) 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
+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
+
# 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, unsigned> prototype_table;
+typedef std::map<prototype, reader_func> prototype_table;
/**
- * Creates a default prototype table containing all defined GiNaC functions.
+ * Default prototype table.
*
- * 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.
+ * It supports most of builtin GiNaC functions.
*/
-extern const prototype_table& get_default_reader(bool force_init = false);
+extern const prototype_table& get_default_reader();
} // 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 = function(reader->second, args);
+ ex ret = reader->second(args);
return ret;
}