20996f97435a20a63e6389ac6a273e0085535a4e
[ginac.git] / ginac / parser / default_reader.cpp
1 /** @file default_reader.cpp
2  *
3  *  Implementation of the default and builtin readers (part of GiNaC's parser).
4  **/
5
6 /*
7  *  GiNaC Copyright (C) 1999-2016 Johannes Gutenberg University Mainz, Germany
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 #include "parse_context.h"
25 #include "power.h"
26 #include "lst.h"
27 #include "operators.h"
28 #include "inifcns.h"
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h> // for uintptr_t
35 #endif
36
37 namespace GiNaC
38 {
39
40 static ex sqrt_reader(const exvector& ev)
41 {
42         return GiNaC::sqrt(ev[0]);
43 }
44
45 static ex pow_reader(const exvector& ev)
46 {
47         return GiNaC::pow(ev[0], ev[1]);
48 }
49
50 static ex power_reader(const exvector& ev)
51 {
52         return GiNaC::power(ev[0], ev[1]);
53 }
54
55 static ex lst_reader(const exvector& ev)
56 {
57         return GiNaC::lst(ev.begin(), ev.end());
58 }
59
60
61 // function::registered_functions() is protected, but we need to access it
62 // TODO: add a proper const method to the `function' class, so we don't
63 // need this silly hack any more.
64 class registered_functions_hack : public function
65 {
66 public:
67         static const std::vector<function_options>& get_registered_functions()
68         {
69                 return function::registered_functions();
70         }
71 private:
72         registered_functions_hack();
73         registered_functions_hack(const registered_functions_hack&);
74         registered_functions_hack& operator=(const registered_functions_hack&);
75 };
76
77 // Encode an integer into a pointer to a function. Since functions
78 // are aligned (the minimal alignment depends on CPU architecture)
79 // we can distinguish between pointers and integers.
80 static reader_func encode_serial_as_reader_func(unsigned serial)
81 {
82         uintptr_t u = (uintptr_t)serial;
83         u = (u << 1) | (uintptr_t)1;
84         reader_func ptr = (reader_func)((void *)u);
85         return ptr;
86 }
87
88 const prototype_table& get_default_reader()
89 {
90         using std::make_pair;
91         static bool initialized = false;
92         static prototype_table reader;
93         if (!initialized) {
94                 
95                 reader[make_pair("sqrt", 1)] = sqrt_reader;
96                 reader[make_pair("pow", 2)] = pow_reader;
97                 reader[make_pair("power", 2)] = power_reader;
98                 reader[make_pair("lst", 0)] = lst_reader;
99                 unsigned serial = 0;
100                 for (auto & it : registered_functions_hack::get_registered_functions()) {
101                         prototype proto = make_pair(it.get_name(), it.get_nparams());
102                         reader[proto] = encode_serial_as_reader_func(serial);
103                         ++serial;
104                 }
105                 initialized = true;
106         }
107         return reader;
108 }
109
110 const prototype_table& get_builtin_reader()
111 {
112         using std::make_pair;
113         static bool initialized = false;
114         static prototype_table reader;
115         if (!initialized) {
116                 
117                 reader[make_pair("sqrt", 1)] = sqrt_reader;
118                 reader[make_pair("pow", 2)] = pow_reader;
119                 reader[make_pair("power", 2)] = power_reader;
120                 reader[make_pair("lst", 0)] = lst_reader;
121                 enum {
122                         log,
123                         exp,
124                         sin,
125                         cos,
126                         tan,
127                         asin,
128                         acos,
129                         atan,
130                         sinh,
131                         cosh,
132                         tanh,
133                         asinh,
134                         acosh,
135                         atanh,
136                         atan2,
137                         Li2,
138                         Li3,
139                         zetaderiv,
140                         Li,
141                         S,
142                         H,
143                         lgamma,
144                         tgamma,
145                         beta,
146                         factorial,
147                         binomial,
148                         Order,
149                         NFUNCTIONS
150                 };
151                 std::vector<function_options>::const_iterator it =
152                         registered_functions_hack::get_registered_functions().begin();
153                 unsigned serial = 0;
154                 for ( ; serial<NFUNCTIONS; ++it, ++serial ) {
155                         prototype proto = make_pair(it->get_name(), it->get_nparams());
156                         reader[proto] = encode_serial_as_reader_func(serial);
157                 }
158                 initialized = true;
159         }
160         return reader;
161 }
162
163 } // namespace GiNaC