From d6ab150eb3016ddb416f0533606ae3a393003e9e Mon Sep 17 00:00:00 2001 From: Jens Vollinga Date: Wed, 15 Jul 2009 08:26:33 +0200 Subject: [PATCH] Allow user defined functions to be parsed. This patch is an ugly hack that does the same as the commit f38cbcd651246fb5c1294705d29399f3cbfddaf5 but without changing the ABI (so it can be used in ginac_1-5). --- ginac/function.pl | 4 +++- ginac/parser/default_reader.tpl | 21 ++++++++++++++++----- ginac/parser/parse_context.h | 5 +++++ ginac/parser/parser.cpp | 3 ++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ginac/function.pl b/ginac/function.pl index 1c6ce297..495432bb 100644 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -1388,7 +1388,9 @@ unsigned function::find_function(const std::string &name, unsigned nparams) /** Return the print name of the function. */ std::string function::get_name() const { - GINAC_ASSERT(serial= registered_functions().size() ) { + throw std::runtime_error("unknown function"); + } return registered_functions()[serial].name; } diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index 3ae6ff83..244074fa 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -37,11 +37,22 @@ const prototype_table& get_default_reader() 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 +] + try { + for ( unsigned ser=0; ; ++ser ) { + GiNaC::function f(ser); + std::string name = f.get_name(); + for ( std::size_t nargs=0; ; ++nargs ) { + try { + function::find_function(name, nargs); + prototype proto = std::pair(name, nargs); + std::pair ins = reader.insert(std::pair(proto, (reader_func)ser)); + if ( ins.second ) break; + } + catch ( std::runtime_error ) { } + } + } + } + catch ( std::runtime_error ) { } initialized = true; } return reader; diff --git a/ginac/parser/parse_context.h b/ginac/parser/parse_context.h index 35163209..81b2cd15 100644 --- a/ginac/parser/parse_context.h +++ b/ginac/parser/parse_context.h @@ -82,6 +82,11 @@ typedef ex (*reader_func)(const exvector& args); * number of arguments. * 3. User can extend the parser via custom prototype tables. It's possible * to read user defined classes, create abbreviations, etc. + * + * NOTE: due to a hack that allows user defined functions to be parsed, the map + * value of type reader_func is internally treated as an unsigned and not as a + * function pointer!! The unsigned has to correspond to the serial number of + * the defined GiNaC function. */ typedef std::map prototype_table; diff --git a/ginac/parser/parser.cpp b/ginac/parser/parser.cpp index 42a7ae2b..6bfaf002 100644 --- a/ginac/parser/parser.cpp +++ b/ginac/parser/parser.cpp @@ -25,6 +25,7 @@ #include "debug.h" #include "mul.h" #include "constant.h" +#include "function.h" #include #include @@ -65,7 +66,7 @@ ex parser::parse_identifier_expr() Parse_error_("no function \"" << name << "\" with " << args.size() << " arguments"); } - ex ret = reader->second(args); + ex ret = GiNaC::function((unsigned)reader->second, args); return ret; } -- 2.44.0