Update copyright statements.
[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-2014 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                 std::vector<function_options>::const_iterator it =
100                         registered_functions_hack::get_registered_functions().begin();
101                 std::vector<function_options>::const_iterator end =
102                         registered_functions_hack::get_registered_functions().end();
103                 unsigned serial = 0;
104                 for (; it != end; ++it) {
105                         prototype proto = make_pair(it->get_name(), it->get_nparams());
106                         reader[proto] = encode_serial_as_reader_func(serial);
107                         ++serial;
108                 }
109                 initialized = true;
110         }
111         return reader;
112 }
113
114 const prototype_table& get_builtin_reader()
115 {
116         using std::make_pair;
117         static bool initialized = false;
118         static prototype_table reader;
119         if (!initialized) {
120                 
121                 reader[make_pair("sqrt", 1)] = sqrt_reader;
122                 reader[make_pair("pow", 2)] = pow_reader;
123                 reader[make_pair("power", 2)] = power_reader;
124                 reader[make_pair("lst", 0)] = lst_reader;
125                 enum {
126                         log,
127                         exp,
128                         sin,
129                         cos,
130                         tan,
131                         asin,
132                         acos,
133                         atan,
134                         sinh,
135                         cosh,
136                         tanh,
137                         asinh,
138                         acosh,
139                         atanh,
140                         atan2,
141                         Li2,
142                         Li3,
143                         zetaderiv,
144                         Li,
145                         S,
146                         H,
147                         lgamma,
148                         tgamma,
149                         beta,
150                         factorial,
151                         binomial,
152                         Order,
153                         NFUNCTIONS
154                 };
155                 std::vector<function_options>::const_iterator it =
156                         registered_functions_hack::get_registered_functions().begin();
157                 unsigned serial = 0;
158                 for ( ; serial<NFUNCTIONS; ++it, ++serial ) {
159                         prototype proto = make_pair(it->get_name(), it->get_nparams());
160                         reader[proto] = encode_serial_as_reader_func(serial);
161                 }
162                 initialized = true;
163         }
164         return reader;
165 }
166
167 } // namespace GiNaC