Line data Source code
1 : // Snap Websites Server -- C-like parser and running environment
2 : // Copyright (c) 2014-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 : #pragma once
18 :
19 : // snapwebsites lib
20 : //
21 : #include "snapwebsites/snap_exception.h"
22 :
23 : // libQtCassandra lib
24 : //
25 : #include <libdbproxy/value.h>
26 : #include <libdbproxy/context.h>
27 :
28 : // C++ lib
29 : //
30 : #include <cmath>
31 :
32 : // Qt lib
33 : //
34 : #include <QMap>
35 : #include <QSharedPointer>
36 :
37 :
38 : namespace snap
39 : {
40 : namespace snap_expr
41 : {
42 :
43 :
44 0 : class snap_expr_exception : public snap_exception
45 : {
46 : public:
47 0 : explicit snap_expr_exception(char const * what_msg) : snap_exception("snap_expr", what_msg) {}
48 : explicit snap_expr_exception(std::string const & what_msg) : snap_exception("snap_expr", what_msg) {}
49 0 : explicit snap_expr_exception(QString const & what_msg) : snap_exception("snap_expr", what_msg) {}
50 : };
51 :
52 0 : class snap_expr_exception_unknown_function : public snap_expr_exception
53 : {
54 : public:
55 0 : explicit snap_expr_exception_unknown_function(char const * what_msg) : snap_expr_exception(what_msg) {}
56 : explicit snap_expr_exception_unknown_function(std::string const & what_msg) : snap_expr_exception(what_msg) {}
57 0 : explicit snap_expr_exception_unknown_function(QString const & what_msg) : snap_expr_exception(what_msg) {}
58 : };
59 :
60 0 : class snap_expr_exception_invalid_number_of_parameters : public snap_expr_exception
61 : {
62 : public:
63 0 : explicit snap_expr_exception_invalid_number_of_parameters(char const * what_msg) : snap_expr_exception(what_msg) {}
64 : explicit snap_expr_exception_invalid_number_of_parameters(std::string const & what_msg) : snap_expr_exception(what_msg) {}
65 : explicit snap_expr_exception_invalid_number_of_parameters(QString const & what_msg) : snap_expr_exception(what_msg) {}
66 : };
67 :
68 0 : class snap_expr_exception_invalid_parameter_type : public snap_expr_exception
69 : {
70 : public:
71 : explicit snap_expr_exception_invalid_parameter_type(char const * what_msg) : snap_expr_exception(what_msg) {}
72 : explicit snap_expr_exception_invalid_parameter_type(std::string const & what_msg) : snap_expr_exception(what_msg) {}
73 0 : explicit snap_expr_exception_invalid_parameter_type(QString const & what_msg) : snap_expr_exception(what_msg) {}
74 : };
75 :
76 : class snap_expr_exception_invalid_parameter_value : public snap_expr_exception
77 : {
78 : public:
79 : explicit snap_expr_exception_invalid_parameter_value(char const * what_msg) : snap_expr_exception(what_msg) {}
80 : explicit snap_expr_exception_invalid_parameter_value(std::string const & what_msg) : snap_expr_exception(what_msg) {}
81 : explicit snap_expr_exception_invalid_parameter_value(QString const & what_msg) : snap_expr_exception(what_msg) {}
82 : };
83 :
84 0 : class snap_expr_exception_not_accessible : public snap_expr_exception
85 : {
86 : public:
87 : explicit snap_expr_exception_not_accessible(char const * what_msg) : snap_expr_exception(what_msg) {}
88 : explicit snap_expr_exception_not_accessible(std::string const & what_msg) : snap_expr_exception(what_msg) {}
89 0 : explicit snap_expr_exception_not_accessible(QString const & what_msg) : snap_expr_exception(what_msg) {}
90 : };
91 :
92 0 : class snap_expr_exception_not_ready : public snap_expr_exception
93 : {
94 : public:
95 0 : explicit snap_expr_exception_not_ready(char const * what_msg) : snap_expr_exception(what_msg) {}
96 : explicit snap_expr_exception_not_ready(std::string const & what_msg) : snap_expr_exception(what_msg) {}
97 : explicit snap_expr_exception_not_ready(QString const & what_msg) : snap_expr_exception(what_msg) {}
98 : };
99 :
100 0 : class snap_expr_exception_invalid_data : public snap_expr_exception
101 : {
102 : public:
103 0 : explicit snap_expr_exception_invalid_data(char const * what_msg) : snap_expr_exception(what_msg) {}
104 : explicit snap_expr_exception_invalid_data(std::string const & what_msg) : snap_expr_exception(what_msg) {}
105 : explicit snap_expr_exception_invalid_data(QString const & what_msg) : snap_expr_exception(what_msg) {}
106 : };
107 :
108 0 : class snap_expr_exception_division_by_zero : public snap_expr_exception
109 : {
110 : public:
111 0 : explicit snap_expr_exception_division_by_zero(char const * what_msg) : snap_expr_exception(what_msg) {}
112 : explicit snap_expr_exception_division_by_zero(std::string const & what_msg) : snap_expr_exception(what_msg) {}
113 : explicit snap_expr_exception_division_by_zero(QString const & what_msg) : snap_expr_exception(what_msg) {}
114 : };
115 :
116 :
117 :
118 0 : constexpr double pi_number()
119 : {
120 0 : return std::acos(-1.0);
121 : }
122 :
123 :
124 :
125 0 : class variable_t
126 : {
127 : public:
128 : typedef QMap<QString, variable_t> variable_map_t;
129 : typedef QVector<variable_t> variable_vector_t;
130 :
131 : enum class variable_type_t
132 : {
133 : // Variables
134 : // WARNING: the order is VERY important
135 : EXPR_VARIABLE_TYPE_NULL,
136 : EXPR_VARIABLE_TYPE_BOOL,
137 : EXPR_VARIABLE_TYPE_INT8,
138 : EXPR_VARIABLE_TYPE_UINT8,
139 : EXPR_VARIABLE_TYPE_INT16,
140 : EXPR_VARIABLE_TYPE_UINT16,
141 : EXPR_VARIABLE_TYPE_INT32,
142 : EXPR_VARIABLE_TYPE_UINT32,
143 : EXPR_VARIABLE_TYPE_INT64,
144 : EXPR_VARIABLE_TYPE_UINT64,
145 : EXPR_VARIABLE_TYPE_FLOAT,
146 : EXPR_VARIABLE_TYPE_DOUBLE,
147 : EXPR_VARIABLE_TYPE_STRING,
148 : EXPR_VARIABLE_TYPE_BINARY
149 : };
150 :
151 : variable_t(QString const & name = "");
152 :
153 : QString get_name() const;
154 :
155 : variable_type_t get_type() const;
156 : void set_value(variable_type_t type, libdbproxy::value const & value);
157 : void set_value(); // set to NULL
158 : void set_value(bool value);
159 : void set_value(char value);
160 : void set_value(signed char value);
161 : void set_value(unsigned char value);
162 : void set_value(int16_t value);
163 : void set_value(uint16_t value);
164 : void set_value(int32_t value);
165 : void set_value(uint32_t value);
166 : void set_value(int64_t value);
167 : void set_value(uint64_t value);
168 : void set_value(float value);
169 : void set_value(double value);
170 : void set_value(char const * value);
171 : void set_value(wchar_t const * value);
172 : void set_value(QString const & value);
173 : void set_value(QByteArray const & value);
174 :
175 : libdbproxy::value const & get_value() const;
176 : bool get_bool(QString const & name) const;
177 : int64_t get_integer(QString const & name) const;
178 : double get_floating_point(QString const & name) const;
179 : QString get_string(QString const & name) const;
180 :
181 : bool is_true() const;
182 :
183 : QString to_string() const;
184 :
185 : private:
186 : QString f_name = QString();
187 : variable_type_t f_type = variable_type_t::EXPR_VARIABLE_TYPE_NULL;
188 : libdbproxy::value f_value = libdbproxy::value();
189 : };
190 :
191 :
192 0 : class functions_t
193 : {
194 : public:
195 : typedef void (*function_call_t)(variable_t & result, variable_t::variable_vector_t const & parameters);
196 : struct function_call_table_t
197 : {
198 : char const * f_name = nullptr;
199 : function_call_t f_function = function_call_t();
200 : };
201 : typedef QMap<QString, function_call_t> expr_node_functions_map_t;
202 :
203 0 : void add_functions(function_call_table_t const *functions)
204 : {
205 0 : for(; functions->f_name != nullptr; ++functions)
206 : {
207 : #ifdef DEBUG
208 0 : if(f_functions.contains(functions->f_name))
209 : {
210 0 : throw snap_logic_exception(QString("functions_t::add_functions() function \"%s\" already defined")
211 0 : .arg(functions->f_name));
212 : }
213 : #endif
214 0 : f_functions[functions->f_name] = functions->f_function;
215 : }
216 0 : }
217 :
218 0 : function_call_t get_function(QString const & name)
219 : {
220 0 : if(f_functions.contains(name))
221 : {
222 0 : return f_functions[name];
223 : }
224 0 : return nullptr;
225 : }
226 :
227 : //set_request_internal_functions(int flags)
228 : //{
229 : // f_flags = flags;
230 : // // and when adding internal functions, check the flags and
231 : // // add this or that accordingly (i.e. trigonometry,
232 : // // statistics, strings, etc.)
233 : // if((flags & ...) != 0)
234 : // {
235 : //
236 : // }
237 : //}
238 :
239 0 : void set_has_internal_functions()
240 : {
241 0 : f_has_internal_functions = true;
242 0 : }
243 :
244 0 : bool get_has_internal_functions() const
245 : {
246 0 : return f_has_internal_functions;
247 : }
248 :
249 : private:
250 : expr_node_functions_map_t f_functions = expr_node_functions_map_t();
251 : bool f_has_internal_functions = false;
252 : };
253 :
254 :
255 :
256 3 : class expr_node_base
257 : {
258 : public:
259 0 : virtual ~expr_node_base() {}
260 : };
261 :
262 :
263 2 : class expr
264 : {
265 : public:
266 : typedef QSharedPointer<expr> expr_pointer_t;
267 : typedef QMap<QString, expr_pointer_t> expr_map_t;
268 :
269 : bool compile(QString const & expression);
270 : QByteArray serialize() const;
271 : void unserialize(QByteArray const & serialized_code);
272 : void execute(variable_t & result, variable_t::variable_map_t & variables, functions_t & functions);
273 :
274 : // some Snap! specialization
275 : static void set_cassandra_context(libdbproxy::context::pointer_t context);
276 :
277 : private:
278 : QSharedPointer<expr_node_base> f_program_tree = QSharedPointer<expr_node_base>();
279 : };
280 :
281 :
282 :
283 :
284 : } // namespace snap_expr
285 : } // namespace snap
286 : // vim: ts=4 sw=4 et
|