source: nscp/include/parsers/eval.hpp @ 1ecd26f

0.4.00.4.10.4.2
Last change on this file since 1ecd26f was 1ecd26f, checked in by Michael Medin <michael@…>, 2 years ago

syncronized streams between 0.4.x and 0.3.x as well as improed the CMAke build *alot*

  • Property mode set to 100644
File size: 17.4 KB
Line 
1#pragma once
2
3namespace parsers {
4        namespace where {
5                namespace operator_impl {
6                        template<typename THandler>
7                        struct simple_bool_binary_operator_impl : public binary_operator_impl<THandler> {
8                                expression_ast<THandler> evaluate(THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
9                                        value_type ltype = left.get_type();
10                                        value_type rtype = right.get_type();
11
12                                        if ( (ltype != rtype) && (rtype != type_tbd) ) {
13                                                handler.error(_T("Invalid types (not same) for binary operator"));
14                                                return expression_ast<THandler>(int_value(FALSE));
15                                        }
16                                        value_type type = left.get_type();
17                                        if (type_is_int(type))
18                                                return eval_int(type, handler, left, right)?expression_ast<THandler>(int_value(TRUE)):expression_ast<THandler>(int_value(FALSE));
19                                        if (type == type_string)
20                                                return eval_string(type, handler, left, right)?expression_ast<THandler>(int_value(TRUE)):expression_ast<THandler>(int_value(FALSE));
21                                        handler.error(_T("missing impl for simple bool binary operator"));
22                                        return expression_ast<THandler>(int_value(FALSE));
23                                }
24                                virtual bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const = 0;
25                                virtual bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const = 0;
26                        };
27
28                        template<typename THandler>
29                        struct operator_and : public simple_bool_binary_operator_impl<THandler> {
30                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
31                                        return left.get_int(handler) && right.get_int(handler);
32                                }
33                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
34                                        handler.error(_T("missing impl for and binary operator"));
35                                        // TODO convert strings
36                                        return false;
37                                };
38                        };
39                        template<typename THandler>
40                        struct operator_or : public simple_bool_binary_operator_impl<THandler> {
41                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
42                                        return left.get_int(handler) || right.get_int(handler);
43                                }
44                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
45                                        handler.error(_T("missing impl for or binary operator"));
46                                        // TODO convert strings
47                                        return false;
48                                };
49                        };
50                        template<typename THandler>
51                        struct operator_eq : public simple_bool_binary_operator_impl<THandler> {
52                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
53                                        return left.get_int(handler) == right.get_int(handler);
54                                }
55                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
56                                        return left.get_string(handler) == right.get_string(handler);
57                                };
58                        };
59                        template<typename THandler>
60                        struct operator_ne : public simple_bool_binary_operator_impl<THandler> {
61                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
62                                        return left.get_int(handler) != right.get_int(handler);
63                                }
64                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
65                                        return left.get_string(handler) != right.get_string(handler);
66                                };
67                        };
68                        template<typename THandler>
69                        struct operator_gt : public simple_bool_binary_operator_impl<THandler> {
70                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
71                                        return left.get_int(handler) > right.get_int(handler);
72                                }
73                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
74                                        return left.get_string(handler) > right.get_string(handler);
75                                };
76                        };
77                        template<typename THandler>
78                        struct operator_lt : public simple_bool_binary_operator_impl<THandler> {
79                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
80                                        return left.get_int(handler) < right.get_int(handler);
81                                }
82                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
83                                        return left.get_string(handler) < right.get_string(handler);
84                                };
85                        };
86                        template<typename THandler>
87                        struct operator_le : public simple_bool_binary_operator_impl<THandler> {
88                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
89                                        return left.get_int(handler) <= right.get_int(handler);
90                                }
91                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
92                                        return left.get_string(handler) <= right.get_string(handler);
93                                };
94                        };
95                        template<typename THandler>
96                        struct operator_ge : public simple_bool_binary_operator_impl<THandler> {
97                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
98                                        return left.get_int(handler) >= right.get_int(handler);
99                                }
100                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
101                                        return left.get_string(handler) >= right.get_string(handler);
102                                };
103                        };
104                        template<typename THandler>
105                        struct operator_like : public simple_bool_binary_operator_impl<THandler> {
106                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
107                                        return false;
108                                }
109                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
110                                        std::wstring s1 = left.get_string(handler);
111                                        std::wstring s2 = right.get_string(handler);
112                                        bool res;
113                                        if (s1.size() > s2.size() && s2.size() > 0)
114                                                return s1.find(s2) != std::wstring::npos;
115                                        return s2.find(s1) != std::wstring::npos;
116                                        //if (res)
117                                        //      std::wcout << _T("Found: ") << s1 << _T(" in ") << s2 << std::endl;
118                                        return res;
119                                };
120                        };
121                        template<typename THandler>
122                        struct operator_not_like : public simple_bool_binary_operator_impl<THandler> {
123                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
124                                        return false;
125                                }
126                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
127                                        std::wstring s1 = left.get_string(handler);
128                                        std::wstring s2 = right.get_string(handler);
129                                        bool res;
130                                        if (s1.size() > s2.size() && s2.size() > 0)
131                                                return s1.find(s2) == std::wstring::npos;
132                                        return s2.find(s1) == std::wstring::npos;
133                                        //if (res)
134                                        //      std::wcout << _T("Found: ") << s1 << _T(" in ") << s2 << std::endl;
135                                        return res;
136                                };
137                        };
138                        template<typename THandler>
139                        struct operator_not_in : public simple_bool_binary_operator_impl<THandler> {
140
141                                typedef typename expression_ast<THandler>::list_type list_type;
142                                typedef typename expression_ast<THandler> list_item_type;
143                                typename expression_ast<THandler>::list_type list;
144                                operator_not_in(const expression_ast<THandler> &subject) : list(subject.get_list()) {}
145
146                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
147                                        long long val = left.get_int(handler);
148                                        BOOST_FOREACH(list_item_type itm, list) {
149                                                if (itm.get_int(handler) == val)
150                                                        return false;
151                                        }
152                                        return true;
153                                }
154                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
155                                        std::wstring val = left.get_string(handler);
156                                        BOOST_FOREACH(list_item_type itm, list) {
157                                                if (itm.get_string(handler) == val)
158                                                        return false;
159                                        }
160                                        return true;
161                                };
162                        };
163                        template<typename THandler>
164                        struct operator_in : public simple_bool_binary_operator_impl<THandler> {
165
166                                typedef typename expression_ast<THandler>::list_type list_type;
167                                typedef typename expression_ast<THandler> list_item_type;
168                                typename expression_ast<THandler>::list_type list;
169                                operator_in(const expression_ast<THandler> &subject) : list(subject.get_list()) {}
170
171                                bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
172                                        long long val = left.get_int(handler);
173                                        BOOST_FOREACH(list_item_type itm, list) {
174                                                if (itm.get_int(handler) == val)
175                                                        return true;
176                                        }
177                                        return false;
178                                }
179                                bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
180                                        std::wstring val = left.get_string(handler);
181                                        BOOST_FOREACH(list_item_type itm, list) {
182                                                if (itm.get_string(handler) == val)
183                                                        return true;
184                                        }
185                                        return false;
186                                };
187                        };
188                        template<typename THandler>
189                        struct operator_false : public binary_operator_impl<THandler>, unary_operator_impl<THandler>, binary_function_impl<THandler> {
190                                expression_ast<THandler> evaluate(THandler &handler, const expression_ast<THandler> &left, const expression_ast<THandler> & right) const {
191                                        handler.error(_T("missing impl for FALSE"));
192                                        return expression_ast<THandler>(int_value(FALSE));
193                                }
194                                expression_ast<THandler> evaluate(THandler &handler, const expression_ast<THandler> &subject) const {
195                                        handler.error(_T("missing impl for FALSE"));
196                                        return expression_ast<THandler>(int_value(FALSE));
197                                }
198                                expression_ast<THandler> evaluate(parsers::where::value_type type,THandler &handler, const expression_ast<THandler> &subject) const {
199                                        handler.error(_T("missing impl for FALSE"));
200                                        return expression_ast<THandler>(int_value(FALSE));
201                                }
202                        };
203
204                        template<typename THandler>
205                        struct function_convert : public binary_function_impl<THandler> {
206                                typename expression_ast<THandler> list_entry;
207                                typedef typename expression_ast<THandler>::list_type list_type;
208                                typename expression_ast<THandler>::list_type list;
209                                bool single_item;
210                                function_convert(const expression_ast<THandler> &subject) : list(subject.get_list()), single_item(list.size()==1) {}
211                                expression_ast<THandler> evaluate(value_type type, THandler &handler, const expression_ast<THandler> &subject) const {
212                                        if (single_item) {
213                                                if (type_is_int(type)) {
214                                                        return expression_ast<THandler>(int_value(list.front().get_int(handler)));
215                                                }
216                                                if (type == type_string) {
217                                                        return expression_ast<THandler>(string_value(list.front().get_string(handler)));
218                                                }
219                                                handler.error(_T("1:Failed to handle type: ") + to_string(type));
220                                                return expression_ast<THandler>(int_value(FALSE));
221                                        }
222                                        if (list.size()==2) {
223                                                list_type::const_iterator item = list.begin();
224                                                list_type::const_iterator unit = item;
225                                                std::advance(unit, 1);
226                                                if (type == type_date) {
227                                                        return expression_ast<THandler>(int_value(parse_time((*item).get_int(handler), (*unit).get_string(handler))));
228                                                }
229                                                handler.error(_T("m:Failed to handle type: ") + to_string(type) + _T(" ") + (*item).to_string() + _T(", ") + (*unit).to_string());
230                                                return expression_ast<THandler>(int_value(FALSE));
231                                        }
232                                        std::wcout << _T("----------------------------------------------\n");
233                                        std::wcout << list.size() << _T("\n");
234                                        std::wcout << subject.to_string() << _T("\n");
235                                        std::wcout << _T("----------------------------------------------\n");
236                                        handler.error(_T("Missing implementation for convert function"));
237                                        return expression_ast<THandler>(int_value(FALSE));
238                                }
239
240                                inline long long parse_time(unsigned int value, std::wstring unit) const {
241                                        long long now = constants::get_now();
242                                        if (unit.empty())
243                                                return now + value;
244                                        else if ( (unit == _T("s")) || (unit == _T("S")) )
245                                                return now + (value);
246                                        else if ( (unit == _T("m")) || (unit == _T("M")) )
247                                                return now + (value * 60);
248                                        else if ( (unit == _T("h")) || (unit == _T("H")) )
249                                                return now + (value * 60 * 60);
250                                        else if ( (unit == _T("d")) || (unit == _T("D")) )
251                                                return now + (value * 24 * 60 * 60);
252                                        else if ( (unit == _T("w")) || (unit == _T("W")) )
253                                                return now + (value * 7 * 24 * 60 * 60);
254                                        return now + value;
255                                }
256
257                        };
258
259
260                        template<typename THandler>
261                        struct simple_bool_unary_operator_impl : public unary_operator_impl<THandler> {
262                                expression_ast<THandler> evaluate(THandler &handler, const expression_ast<THandler> &subject) const {
263                                        value_type type = subject.get_type();
264                                        if (type_is_int(type))
265                                                return eval_int(type, handler, subject)?expression_ast<THandler>(int_value(TRUE)):expression_ast<THandler>(int_value(FALSE));
266                                        if (type == type_string)
267                                                return eval_string(type, handler, subject)?expression_ast<THandler>(int_value(TRUE)):expression_ast<THandler>(int_value(FALSE));
268                                        handler.error(_T("missing impl for bool unary operator"));
269                                        return expression_ast<THandler>(int_value(FALSE));
270                                }
271                                virtual bool eval_int(value_type type, THandler &handler, const expression_ast<THandler> &subject) const = 0;
272                                virtual bool eval_string(value_type type, THandler &handler, const expression_ast<THandler> &subject) const = 0;
273                        };
274
275                        template<typename THandler>
276                        struct operator_not : public unary_operator_impl<THandler>, binary_function_impl<THandler> {
277                                operator_not(const expression_ast<THandler> &subject) {}
278                                operator_not() {}
279                                expression_ast<THandler> evaluate(THandler &handler, const expression_ast<THandler> &subject) const {
280                                        return evaluate(subject.get_type(), handler, subject);
281                                }
282                                expression_ast<THandler> evaluate(value_type type, THandler &handler, const expression_ast<THandler> &subject) const {
283                                        if (type == type_bool)
284                                                return subject.get_int(handler)?expression_ast<THandler>(int_value(TRUE)):expression_ast<THandler>(int_value(FALSE));
285                                        if (type == type_int)
286                                                return  expression_ast<THandler>(int_value(-subject.get_int(handler)));
287                                        if (type == type_date) {
288                                                long long now = constants::get_now();
289                                                long long val = now - (subject.get_int(handler) - now);
290                                                return expression_ast<THandler>(int_value(val));
291                                        }
292                                        handler.error(_T("missing impl for NOT operator"));
293                                        return expression_ast<THandler>(int_value(FALSE));
294                                }
295                        };
296                }
297                template<typename THandler>
298                typename factory<THandler>::bin_op_type factory<THandler>::get_binary_operator(operators op, const expression_ast<THandler> &left, const expression_ast<THandler> &right) {
299                        // op_in, op_nin
300                        if (op == op_eq)
301                                return bin_op_type(new operator_impl::operator_eq<THandler>());
302                        if (op == op_gt)
303                                return bin_op_type(new operator_impl::operator_gt<THandler>());
304                        if (op == op_lt)
305                                return bin_op_type(new operator_impl::operator_lt<THandler>());
306                        if (op == op_le)
307                                return bin_op_type(new operator_impl::operator_le<THandler>());
308                        if (op == op_ge)
309                                return bin_op_type(new operator_impl::operator_ge<THandler>());
310                        if (op == op_ne)
311                                return bin_op_type(new operator_impl::operator_ne<THandler>());
312                        if (op == op_like)
313                                return bin_op_type(new operator_impl::operator_like<THandler>());
314                        if (op == op_not_like)
315                                return bin_op_type(new operator_impl::operator_not_like<THandler>());
316
317                        if (op == op_and)
318                                return bin_op_type(new operator_impl::operator_and<THandler>());
319                        if (op == op_or)
320                                return bin_op_type(new operator_impl::operator_or<THandler>());
321                        if (op == op_in)
322                                return bin_op_type(new operator_impl::operator_in<THandler>(right));
323                        if (op == op_nin)
324                                return bin_op_type(new operator_impl::operator_not_in<THandler>(right));
325                        std::cout << "======== UNHANDLED OPERATOR\n";
326                        return bin_op_type(new operator_impl::operator_false<THandler>());
327                }
328
329                template<typename THandler>
330                typename factory<THandler>::bin_fun_type factory<THandler>::get_binary_function(std::wstring name, const expression_ast<THandler> &subject) {
331                        if (name == _T("convert"))
332                                return bin_fun_type(new operator_impl::function_convert<THandler>(subject));
333                        if (name == _T("auto_convert"))
334                                return bin_fun_type(new operator_impl::function_convert<THandler>(subject));
335                        if (name == _T("neg"))
336                                return bin_fun_type(new operator_impl::operator_not<THandler>(subject));
337                        std::wcout << _T("======== UNDEFINED FUNCTION: ") << name << std::endl;
338                        return bin_fun_type(new operator_impl::operator_false<THandler>());
339                }
340                template<typename THandler>
341                typename factory<THandler>::un_op_type factory<THandler>::get_unary_operator(operators op) {
342                        // op_inv, op_not
343                        if (op == op_not)
344                                return un_op_type(new operator_impl::operator_not<THandler>());
345                        std::cout << "======== UNHANDLED OPERATOR\n";
346                        return un_op_type(new operator_impl::operator_false<THandler>());
347                }
348        }
349}
Note: See TracBrowser for help on using the repository browser.