X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fparser%2Fdefault_reader.tpl;h=006fb908c28402f2d61fa5cacdee904788a091b7;hp=3ae6ff832c06ec49a4a662c1d340ca34b8440069;hb=c0fcba137d26486085ed5d4104b34d2c44978693;hpb=3aec0ba298693329c1194e547043fef1a78b1b0d diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index 3ae6ff83..006fb908 100644 --- a/ginac/parser/default_reader.tpl +++ b/ginac/parser/default_reader.tpl @@ -19,6 +19,13 @@ 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,20 +38,108 @@ 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 = (reader_func)((void *)u); + return ptr; +} + const prototype_table& get_default_reader() { using std::make_pair; static bool initialized = false; static prototype_table reader; if (!initialized) { -[+ FOR function +] + [+ FOR function +] reader[make_pair("[+ (get "name") +]", [+ - (if (exist? "args") (get "args") "1") - +])] = [+ (get "name") +]_reader;[+ - ENDFOR +] + (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; + } initialized = true; } return reader; } -} // namespace GiNaC +const prototype_table& get_builtin_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 +] + enum { + log, + exp, + sin, + cos, + tan, + asin, + acos, + atan, + sinh, + cosh, + tanh, + asinh, + acosh, + atanh, + atan2, + Li2, + Li3, + zetaderiv, + Li, + S, + H, + lgamma, + tgamma, + beta, + factorial, + binomial, + Order, + NFUNCTIONS + }; + std::vector::const_iterator it = + registered_functions_hack::get_registered_functions().begin(); + unsigned serial = 0; + for ( ; serialget_name(), it->get_nparams()); + reader[proto] = encode_serial_as_reader_func(serial); + } + initialized = true; + } + return reader; +} + +} // namespace GiNaC