From 5fc9d1ab7fa870e78070bf412a28bfcf497c05b9 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 e1533be2..708d00e8 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 15dfcd63..47b150c3 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 42edf5b0..49314663 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.45.0