81f89bf49788fc1811133e5d1b9b9c4d18ad5bd3
[ginac.git] / ginac / parser / default_reader.tpl
1 [+ AutoGen5 template .cpp +][+ 
2 COMMENT a part of GiNaC parser -- construct functions from a byte stream.
3 +][+
4 (use-modules (ice-9 format))
5
6 (define (sequence start end . step)
7   (let ((step (if (null? step) 1 (car step))))
8     (let loop ((n start))
9       (if (> n end) '() (cons n (loop (+ step n)))))))
10 +]/*
11 [+ (dne " * " " * " ) +]
12  *
13  * If you want to change this file, edit either `[+ (def-file) +]' or
14  * `[+ (tpl-file) +]' file, and run the following command:
15  *
16  * autogen -T [+ (tpl-file) +] [+ (def-file) +]
17  */
18 #include "parse_context.h"
19 #include "power.h"
20 #include "operators.h"
21 #include "inifcns.h"
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #ifdef HAVE_STDINT_H
27 #include <stdint.h> // for uintptr_t
28 #endif
29
30 namespace GiNaC
31 {
32 [+ FOR function +]
33 static ex [+ (get "name") +]_reader(const exvector& ev)
34 {
35         return GiNaC::[+ (get "name") +]([+
36                 (let ((nargs (if (exist? "args")
37                                  (string->number (get "args")) 1)))
38                   (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
39 }[+ ENDFOR +]
40
41 // function::registered_functions() is protected, but we need to access it
42 class registered_functions_hack : public function
43 {
44 public:
45         static const std::vector<function_options>& get_registered_functions()
46         {
47                 return function::registered_functions();
48         }
49 private:
50         registered_functions_hack();
51         registered_functions_hack(const registered_functions_hack&);
52         registered_functions_hack& operator=(const registered_functions_hack&);
53 };
54
55 // Encode an integer into a pointer to a function. Since functions
56 // are aligned (the minimal alignment depends on CPU architecture)
57 // we can distinguish between pointers and integers.
58 static reader_func encode_serial_as_reader_func(unsigned serial)
59 {
60         uintptr_t u = (uintptr_t)serial;
61         u = (u << 1) | (uintptr_t)1;
62         reader_func ptr = reinterpret_cast<reader_func>((void *)u);
63         return ptr;
64 }
65
66 const prototype_table& get_default_reader()
67 {
68         using std::make_pair;
69         static bool initialized = false;
70         static prototype_table reader;
71         if (!initialized) {
72                 [+ FOR function +]
73                 reader[make_pair("[+ (get "name") +]", [+ 
74                         (if (exist? "args") (get "args") "1")
75                         +])] = [+ (get "name") +]_reader;[+
76                 ENDFOR +]
77                 std::vector<function_options>::const_iterator it =
78                         registered_functions_hack::get_registered_functions().begin();
79                 std::vector<function_options>::const_iterator end =
80                         registered_functions_hack::get_registered_functions().end();
81                 unsigned serial = 0;
82                 for (; it != end; ++it) {
83                         prototype proto = make_pair(it->get_name(), it->get_nparams());
84                         reader[proto] = encode_serial_as_reader_func(serial);
85                         ++serial;
86                 }
87                 initialized = true;
88         }
89         return reader;
90 }
91
92 } // namespace GiNaC