]> www.ginac.de Git - ginac.git/blob - ginac/parser/default_reader.tpl
2018e04a0660e66b9faf2fe15f1c59b6e09bbf37
[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 #ifdef HAVE_STDINT_H
26 #include <stdint.h> // for uintptr_t
27 #endif
28
29 namespace GiNaC
30 {
31 [+ FOR function +]
32 static ex [+ (get "name") +]_reader(const exvector& ev)
33 {
34         return GiNaC::[+ (get "name") +]([+
35                 (let ((nargs (if (exist? "args")
36                                  (string->number (get "args")) 1)))
37                   (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
38 }[+ ENDFOR +]
39
40 // function::registered_functions() is protected, but we need to access it
41 class registered_functions_hack : public function
42 {
43 public:
44         static const std::vector<function_options>& get_registered_functions()
45         {
46                 return function::registered_functions();
47         }
48 private:
49         registered_functions_hack();
50         registered_functions_hack(const registered_functions_hack&);
51         registered_functions_hack& operator=(const registered_functions_hack&);
52 };
53
54 // Encode an integer into a pointer to a function. Since functions
55 // are aligned (the minimal alignment depends on CPU architecture)
56 // we can distinguish between pointers and integers.
57 static reader_func encode_serial_as_reader_func(unsigned serial)
58 {
59         uintptr_t u = (uintptr_t)serial;
60         u = (u << 1) | (uintptr_t)1;
61         reader_func ptr = reinterpret_cast<reader_func>((void *)u);
62         return ptr;
63 }
64
65 const prototype_table& get_default_reader()
66 {
67         using std::make_pair;
68         static bool initialized = false;
69         static prototype_table reader;
70         if (!initialized) {
71                 [+ FOR function +]
72                 reader[make_pair("[+ (get "name") +]", [+ 
73                         (if (exist? "args") (get "args") "1")
74                         +])] = [+ (get "name") +]_reader;[+
75                 ENDFOR +]
76                 std::vector<function_options>::const_iterator it =
77                         registered_functions_hack::get_registered_functions().begin();
78                 std::vector<function_options>::const_iterator end =
79                         registered_functions_hack::get_registered_functions().end();
80                 unsigned serial = 0;
81                 for (; it != end; ++it) {
82                         prototype proto = make_pair(it->get_name(), it->get_nparams());
83                         reader[proto] = encode_serial_as_reader_func(serial);
84                         ++serial;
85                 }
86                 initialized = true;
87         }
88         return reader;
89 }
90 } // namespace GiNaC
91