Parser: don't bother to generate 3 (C++) functions with autogen.
[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 static ex pow_reader(const exvector& ev)
44 {
45         return GiNaC::pow(ev[0], ev[1]);
46 }
47 static ex power_reader(const exvector& ev)
48 {
49         return GiNaC::power(ev[0], ev[1]);
50 }
51
52
53 // function::registered_functions() is protected, but we need to access it
54 // TODO: add a proper const method to the `function' class, so we don't
55 // need this silly hack any more.
56 class registered_functions_hack : public function
57 {
58 public:
59         static const std::vector<function_options>& get_registered_functions()
60         {
61                 return function::registered_functions();
62         }
63 private:
64         registered_functions_hack();
65         registered_functions_hack(const registered_functions_hack&);
66         registered_functions_hack& operator=(const registered_functions_hack&);
67 };
68
69 // Encode an integer into a pointer to a function. Since functions
70 // are aligned (the minimal alignment depends on CPU architecture)
71 // we can distinguish between pointers and integers.
72 static reader_func encode_serial_as_reader_func(unsigned serial)
73 {
74         uintptr_t u = (uintptr_t)serial;
75         u = (u << 1) | (uintptr_t)1;
76         reader_func ptr = (reader_func)((void *)u);
77         return ptr;
78 }
79
80 const prototype_table& get_default_reader()
81 {
82         using std::make_pair;
83         static bool initialized = false;
84         static prototype_table reader;
85         if (!initialized) {
86                 
87                 reader[make_pair("sqrt", 1)] = sqrt_reader;
88                 reader[make_pair("pow", 2)] = pow_reader;
89                 reader[make_pair("power", 2)] = power_reader;
90                 std::vector<function_options>::const_iterator it =
91                         registered_functions_hack::get_registered_functions().begin();
92                 std::vector<function_options>::const_iterator end =
93                         registered_functions_hack::get_registered_functions().end();
94                 unsigned serial = 0;
95                 for (; it != end; ++it) {
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                 enum {
116                         log,
117                         exp,
118                         sin,
119                         cos,
120                         tan,
121                         asin,
122                         acos,
123                         atan,
124                         sinh,
125                         cosh,
126                         tanh,
127                         asinh,
128                         acosh,
129                         atanh,
130                         atan2,
131                         Li2,
132                         Li3,
133                         zetaderiv,
134                         Li,
135                         S,
136                         H,
137                         lgamma,
138                         tgamma,
139                         beta,
140                         factorial,
141                         binomial,
142                         Order,
143                         NFUNCTIONS
144                 };
145                 std::vector<function_options>::const_iterator it =
146                         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