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