X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fparser%2Fdefault_reader.tpl;h=2018e04a0660e66b9faf2fe15f1c59b6e09bbf37;hp=244074fa17fb731ff49e6f448ff8f905fd114911;hb=aa1afbbdb118846cfc266a1d7a8d5188ac214e0e;hpb=5fc9d1ab7fa870e78070bf412a28bfcf497c05b9 diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index 244074fa..2018e04a 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -19,6 +19,12 @@ COMMENT a part of GiNaC parser -- construct functions from a byte stream. #include "power.h" #include "operators.h" #include "inifcns.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_STDINT_H +#include // for uintptr_t +#endif namespace GiNaC { @@ -31,28 +37,52 @@ static ex [+ (get "name") +]_reader(const exvector& ev) (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]); }[+ ENDFOR +] +// function::registered_functions() is protected, but we need to access it +class registered_functions_hack : public function +{ +public: + static const std::vector& get_registered_functions() + { + return function::registered_functions(); + } +private: + registered_functions_hack(); + registered_functions_hack(const registered_functions_hack&); + registered_functions_hack& operator=(const registered_functions_hack&); +}; + +// Encode an integer into a pointer to a function. Since functions +// are aligned (the minimal alignment depends on CPU architecture) +// we can distinguish between pointers and integers. +static reader_func encode_serial_as_reader_func(unsigned serial) +{ + uintptr_t u = (uintptr_t)serial; + u = (u << 1) | (uintptr_t)1; + reader_func ptr = reinterpret_cast((void *)u); + return ptr; +} + const prototype_table& get_default_reader() { using std::make_pair; static bool initialized = false; static prototype_table reader; if (!initialized) { - 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 ) { } - } - } + [+ FOR function +] + reader[make_pair("[+ (get "name") +]", [+ + (if (exist? "args") (get "args") "1") + +])] = [+ (get "name") +]_reader;[+ + ENDFOR +] + std::vector::const_iterator it = + registered_functions_hack::get_registered_functions().begin(); + std::vector::const_iterator end = + registered_functions_hack::get_registered_functions().end(); + unsigned serial = 0; + for (; it != end; ++it) { + prototype proto = make_pair(it->get_name(), it->get_nparams()); + reader[proto] = encode_serial_as_reader_func(serial); + ++serial; } - catch ( std::runtime_error ) { } initialized = true; } return reader;