Happy New Year!
[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-2019 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
30 #include <cstdint> // for uintptr_t
31
32 namespace GiNaC
33 {
34
35 static ex sqrt_reader(const exvector& ev)
36 {
37         return GiNaC::sqrt(ev[0]);
38 }
39
40 static ex pow_reader(const exvector& ev)
41 {
42         return GiNaC::pow(ev[0], ev[1]);
43 }
44
45 static ex power_reader(const exvector& ev)
46 {
47         return GiNaC::power(ev[0], ev[1]);
48 }
49
50 static ex lst_reader(const exvector& ev)
51 {
52         return GiNaC::lst(ev.begin(), ev.end());
53 }
54
55
56 // function::registered_functions() is protected, but we need to access it
57 // TODO: add a proper const method to the `function' class, so we don't
58 // need this silly hack any more.
59 class registered_functions_hack : public function
60 {
61 public:
62         static const std::vector<function_options>& get_registered_functions()
63         {
64                 return function::registered_functions();
65         }
66 private:
67         registered_functions_hack();
68         registered_functions_hack(const registered_functions_hack&);
69         registered_functions_hack& operator=(const registered_functions_hack&);
70 };
71
72 // Encode an integer into a pointer to a function. Since functions
73 // are aligned (the minimal alignment depends on CPU architecture)
74 // we can distinguish between pointers and integers.
75 static reader_func encode_serial_as_reader_func(unsigned serial)
76 {
77         uintptr_t u = (uintptr_t)serial;
78         u = (u << 1) | (uintptr_t)1;
79         reader_func ptr = (reader_func)((void *)u);
80         return ptr;
81 }
82
83 const prototype_table& get_default_reader()
84 {
85         using std::make_pair;
86         static bool initialized = false;
87         static prototype_table reader;
88         if (!initialized) {
89                 
90                 reader[make_pair("sqrt", 1)] = sqrt_reader;
91                 reader[make_pair("pow", 2)] = pow_reader;
92                 reader[make_pair("power", 2)] = power_reader;
93                 reader[make_pair("lst", 0)] = lst_reader;
94                 unsigned serial = 0;
95                 for (auto & it : registered_functions_hack::get_registered_functions()) {
96                         prototype proto = make_pair(it.get_name(), it.get_nparams());
97                         reader[proto] = encode_serial_as_reader_func(serial);
98                         ++serial;
99                 }
100                 initialized = true;
101         }
102         return reader;
103 }
104
105 const prototype_table& get_builtin_reader()
106 {
107         using std::make_pair;
108         static bool initialized = false;
109         static prototype_table reader;
110         if (!initialized) {
111                 
112                 reader[make_pair("sqrt", 1)] = sqrt_reader;
113                 reader[make_pair("pow", 2)] = pow_reader;
114                 reader[make_pair("power", 2)] = power_reader;
115                 reader[make_pair("lst", 0)] = lst_reader;
116                 enum {
117                         log,
118                         exp,
119                         sin,
120                         cos,
121                         tan,
122                         asin,
123                         acos,
124                         atan,
125                         sinh,
126                         cosh,
127                         tanh,
128                         asinh,
129                         acosh,
130                         atanh,
131                         atan2,
132                         Li2,
133                         Li3,
134                         zetaderiv,
135                         Li,
136                         S,
137                         H,
138                         lgamma,
139                         tgamma,
140                         beta,
141                         factorial,
142                         binomial,
143                         Order,
144                         NFUNCTIONS
145                 };
146                 auto it = registered_functions_hack::get_registered_functions().begin();
147                 unsigned serial = 0;
148                 for ( ; serial<NFUNCTIONS; ++it, ++serial ) {
149                         prototype proto = make_pair(it->get_name(), it->get_nparams());
150                         reader[proto] = encode_serial_as_reader_func(serial);
151                 }
152                 initialized = true;
153         }
154         return reader;
155 }
156
157 } // namespace GiNaC