/** Return the print name of the function. */
std::string function::get_name() const
{
- GINAC_ASSERT(serial<registered_functions().size());
+ if ( serial >= registered_functions().size() ) {
+ throw std::runtime_error("unknown function");
+ }
return registered_functions()[serial].name;
}
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<std::string, std::size_t>(name, nargs);
+ std::pair<prototype_table::iterator, bool> ins = reader.insert(std::pair<prototype,reader_func>(proto, (reader_func)ser));
+ if ( ins.second ) break;
+ }
+ catch ( std::runtime_error ) { }
+ }
+ }
+ }
+ catch ( std::runtime_error ) { }
initialized = true;
}
return reader;
* 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, reader_func> prototype_table;
#include "debug.h"
#include "mul.h"
#include "constant.h"
+#include "function.h"
#include <sstream>
#include <stdexcept>
Parse_error_("no function \"" << name << "\" with " <<
args.size() << " arguments");
}
- ex ret = reader->second(args);
+ ex ret = GiNaC::function((unsigned)reader->second, args);
return ret;
}