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=3ae6ff832c06ec49a4a662c1d340ca34b8440069;hb=a6e5a7a5974dc95afe71c077f6a5e66b322c9d2c;hpb=80b1c3e0ee0e465d56e5c76bef4e52ef2dbc5197 diff --git a/ginac/parser/default_reader.tpl b/ginac/parser/default_reader.tpl index 3ae6ff83..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,17 +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) { -[+ 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;