source: nscp/include/parsers/eval.hpp @ aa3965b

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