MADARA  3.2.3
EvaluationVisitor.cpp
Go to the documentation of this file.
1 /* -*- C++ -*- */
2 #ifndef _EVALUATION_VISITOR_CPP_
3 #define _EVALUATION_VISITOR_CPP_
4 
5 #ifdef _USE_VISITORS_
6 
7 #include <iostream>
8 #include <typeinfo>
9 #include <algorithm>
10 
42 
44 
46 void
47 madara::expression::EvaluationVisitor::visit (
48  const madara::expression::LeafNode &node)
49 {
50  stack_.push (node.item ());
51 }
52 
54 void
55 madara::expression::EvaluationVisitor::visit (
57 {
58  stack_.push (node.item ());
59 }
60 
62 void
63 madara::expression::EvaluationVisitor::visit (
65 {
66  stack_.push (node.item ());
67 }
68 
70 void
71 madara::expression::EvaluationVisitor::visit (
73 {
74  stack_.push (node.item ());
75 }
76 
78 void
79 madara::expression::EvaluationVisitor::visit (
81 {
82  stack_.push (node.item ());
83 }
84 
86 void
87 madara::expression::EvaluationVisitor::visit (
89 {
90  stack_.push (node.item ());
91 }
92 
94 void
95 madara::expression::EvaluationVisitor::visit (
97 {
98  stack_.push (node.item ());
99 }
100 
102 void
103 madara::expression::EvaluationVisitor::visit (
104  const madara::expression::ListNode &node)
105 {
106 }
107 
109 void
110 madara::expression::EvaluationVisitor::visit (
112 {
113  if (stack_.size () >= 1)
114  stack_.push (-stack_.pop ());
115  else
116  {
117  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
118  "\nKARL EVAL ERROR: Negate" \
119  " requires a right expression"));
120 
121  throw KarlException ("madara::expression::CompositeNegateNode: "
122  "KARL COMPILE ERROR: "
123  "Node has no right expression\n");
124  }
125 }
126 
128 void
129 madara::expression::EvaluationVisitor::visit (
131 {
132  if (stack_.size () >= 1)
133  {
134  madara::knowledge::KnowledgeRecord old_value = stack_.pop ();
135  try
136  {
137  VariableNode * right = dynamic_cast <VariableNode *> (node.right ());
138 
139  madara::knowledge::KnowledgeRecord new_value = --old_value;
140  if (right)
141  {
142  new_value = right->dec ();
143  }
144  stack_.push (new_value);
145  }
146  catch (::std::bad_cast &)
147  {
148  stack_.push (--old_value);
149  }
150  }
151  else
152  {
153  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
154  "\nKARL EVAL ERROR: Predecrement" \
155  " requires a right expression"));
156  exit (-1);
157  }
158 }
159 
161 void
162 madara::expression::EvaluationVisitor::visit (
164 {
165  if (stack_.size () >= 1)
166  {
167  madara::knowledge::KnowledgeRecord old_value = stack_.pop ();
168  try
169  {
170  VariableNode * right = dynamic_cast <VariableNode *> (node.right ());
171 
172  madara::knowledge::KnowledgeRecord new_value = ++old_value;
173  if (right)
174  {
175  new_value = right->inc ();
176  }
177  stack_.push (new_value);
178  }
179  catch (::std::bad_cast &)
180  {
181  stack_.push (++old_value);
182  }
183  }
184  else
185  {
186  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
187  "\nKARL EVAL ERROR: Preincrement" \
188  " requires a right expression"));
189  exit (-1);
190  }
191 }
192 
194 void
195 madara::expression::EvaluationVisitor::visit (
197 {
198  if (stack_.size () >= 1)
199  stack_.push (!stack_.pop ());
200  else
201  {
202  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
203  "\nKARL EVAL ERROR: Not" \
204  " requires a right expression"));
205  exit (-1);
206  }
207 }
208 
210 void
211 madara::expression::EvaluationVisitor::visit (
213 {
214  if (stack_.size () >= 2)
215  stack_.push (stack_.pop () + stack_.pop ());
216  else
217  {
218  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
219  "\nKARL EVAL ERROR: Add" \
220  " requires both a left and right expression"));
221  exit (-1);
222  }
223 }
224 
226 void
227 madara::expression::EvaluationVisitor::visit (
229 {
230  if (stack_.size () >= 2)
231  {
232  // for an assignment to be valid, we need a variable to the left
233  // and an expression tree to the right.
234  try
235  {
236  // this is really backwards logic, but it was the only way I could think of
237  // to allow for a = b = c with this type of tree and post-order flow
238  madara::knowledge::KnowledgeRecord right = stack_.pop ();
239  stack_.pop ();
240  VariableNode * left = dynamic_cast <VariableNode *> (node.left ());
241  left->set (right.to_integer ());
242  stack_.push (right);
243  }
244  catch (::std::bad_cast &)
245  {
246  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
247  "\nKARL EVAL ERROR: Assignment" \
248  " must have a variable as the left expression\n"));
249  exit (-1);
250  }
251  }
252  // ::std::cout << "add current top: " << stack_.top () << ::std::endl;
253 }
254 
256 void
257 madara::expression::EvaluationVisitor::visit (
259 {
260  if (stack_.size () >= 2)
261  {
262  madara::knowledge::KnowledgeRecord right = stack_.pop ();
263  madara::knowledge::KnowledgeRecord left = stack_.pop ();
264 
265  stack_.push (left && right);
266  }
267  else
268  {
269  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
270  "\nKARL EVAL ERROR: And" \
271  " requires both a left and right expression\n"));
272  exit (-1);
273  }
274 }
275 
277 void
278 madara::expression::EvaluationVisitor::visit (
280 {
281  if (stack_.size () >= 2)
282  {
283  madara::knowledge::KnowledgeRecord right = stack_.pop ();
284  madara::knowledge::KnowledgeRecord left = stack_.pop ();
285 
286  stack_.push (left || right);
287  }
288  else
289  {
290  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
291  "\nKARL EVAL ERROR: Or" \
292  " requires both a left and right expression\n"));
293  exit (-1);
294  }
295 }
296 
298 void
299 madara::expression::EvaluationVisitor::visit (
301 {
302  if (stack_.size () >= 2)
303  {
304  madara::knowledge::KnowledgeRecord right_v = stack_.pop ();
305  madara::knowledge::KnowledgeRecord left_v = stack_.pop ();
306 
307  // I was trying to use std::max, but it was giving me
308  // some grief, so I just implemented it as is
309  stack_.push (left_v > right_v ? left_v : right_v);
310  }
311  else
312  {
313  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
314  "\nKARL EVAL ERROR: And" \
315  " requires both a left and right expression\n"));
316  exit (-1);
317  }
318 }
319 
321 void
322 madara::expression::EvaluationVisitor::visit (
324 {
325  if (stack_.size () >= 2)
326  {
327  madara::knowledge::KnowledgeRecord right_v = stack_.pop ();
328  madara::knowledge::KnowledgeRecord left_v = stack_.pop ();
329 
330  // I was trying to use std::max, but it was giving me
331  // some grief, so I just implemented it as is
332  stack_.push (left_v > right_v ? right_v : left_v);
333  }
334  else
335  {
336  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
337  "\nKARL EVAL ERROR: And" \
338  " requires both a left and right expression\n"));
339  exit (-1);
340  }
341 }
342 
344 void
345 madara::expression::EvaluationVisitor::visit (
347 {
348 }
349 
351 void
352 madara::expression::EvaluationVisitor::visit (
354 {
355 }
356 
358 void
359 madara::expression::EvaluationVisitor::visit (
361 {
362  if (stack_.size () >= 2)
363  {
364  madara::knowledge::KnowledgeRecord right = stack_.pop ();
365  madara::knowledge::KnowledgeRecord left = stack_.pop ();
366 
367  stack_.push (left == right);
368  }
369  else
370  {
371  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
372  "\nKARL EVAL ERROR: Equality" \
373  " requires both a left and right expression\n"));
374  exit (-1);
375  }
376 }
377 
379 void
380 madara::expression::EvaluationVisitor::visit (
382 {
383  if (stack_.size () >= 2)
384  {
385  madara::knowledge::KnowledgeRecord right = stack_.pop ();
386  madara::knowledge::KnowledgeRecord left = stack_.pop ();
387 
388  stack_.push (left != right);
389  }
390  else
391  {
392  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
393  "\nKARL EVAL ERROR: Inequality" \
394  " requires both a left and right expression\n"));
395  exit (-1);
396  }
397 }
398 
400 void
401 madara::expression::EvaluationVisitor::visit (
403 {
404  if (stack_.size () >= 2)
405  {
406  madara::knowledge::KnowledgeRecord right = stack_.pop ();
407  madara::knowledge::KnowledgeRecord left = stack_.pop ();
408 
409  stack_.push (left >= right);
410  }
411  else
412  {
413  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
414  "\nKARL EVAL ERROR: Greater-than-equal" \
415  " requires both a left and right expression\n"));
416  exit (-1);
417  }
418 }
419 
421 void
422 madara::expression::EvaluationVisitor::visit (
424 {
425  if (stack_.size () >= 2)
426  {
427  madara::knowledge::KnowledgeRecord right = stack_.pop ();
428  madara::knowledge::KnowledgeRecord left = stack_.pop ();
429 
430  stack_.push (left > right);
431  }
432  else
433  {
434  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
435  "\nKARL EVAL ERROR: Greater-than" \
436  " requires both a left and right expression\n"));
437  exit (-1);
438  }
439 }
440 
442 void
443 madara::expression::EvaluationVisitor::visit (
445 {
446  if (stack_.size () >= 2)
447  {
448  madara::knowledge::KnowledgeRecord right = stack_.pop ();
449  madara::knowledge::KnowledgeRecord left = stack_.pop ();
450 
451  stack_.push (left <= right);
452  }
453  else
454  {
455  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
456  "\nKARL EVAL ERROR: Less-than-equal" \
457  " requires both a left and right expression\n"));
458  exit (-1);
459  }
460 }
461 
463 void
464 madara::expression::EvaluationVisitor::visit (
466 {
467  if (stack_.size () >= 2)
468  {
469  madara::knowledge::KnowledgeRecord right = stack_.pop ();
470  madara::knowledge::KnowledgeRecord left = stack_.pop ();
471 
472  stack_.push (left < right);
473  }
474  else
475  {
476  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
477  "\nKARL EVAL ERROR: Less-than" \
478  " requires both a left and right expression\n"));
479  exit (-1);
480  }
481 }
482 
484 void
485 madara::expression::EvaluationVisitor::visit (
487 {
488  if (stack_.size () >= 2)
489  {
490  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
491  stack_.push (stack_.pop () - rhs);
492  }
493  else
494  {
495  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
496  "\nKARL EVAL ERROR: Subtract" \
497  " requires both a left and right expression\n"));
498  exit (-1);
499  }
500 }
501 
503 void
504 madara::expression::EvaluationVisitor::visit (
506 {
507  if (stack_.size () >= 2 && stack_.top ())
508  {
509  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
510  stack_.push (stack_.pop () / rhs );
511  }
512  else
513  {
514  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
515  "\nKARL EVAL ERROR: Division" \
516  " requires both a left and right expression" \
517  " (and right must not be 0)\n"));
518  exit (-1);
519  }
520 }
521 
523 void
524 madara::expression::EvaluationVisitor::visit (
526 {
527  if (stack_.size () >= 2)
528  stack_.push (stack_.pop () * stack_.pop ());
529  else
530  {
531  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
532  "\nKARL EVAL ERROR: Multiply" \
533  " requires both a left and right expression\n"));
534  exit (-1);
535  }
536 }
537 
539 void
540 madara::expression::EvaluationVisitor::visit (
542 {
543  if (stack_.size () >= 2 && stack_.top ())
544  {
545  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
546  stack_.push (stack_.pop () / rhs );
547  }
548  else
549  {
550  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
551  "\nKARL EVAL ERROR: Modulus" \
552  " requires both a left and right expression" \
553  " (and right must not be 0)\n"));
554  exit (-1);
555  }
556 }
557 
559 void
560 madara::expression::EvaluationVisitor::visit (
562 {
563  if (stack_.size () >= 2)
564  stack_.push (stack_.pop () ? stack_.pop () : 0);
565  else
566  {
567  MADARA_ERROR (MADARA_LOG_TERMINAL_ERROR, (LM_ERROR, DLINFO
568  "\nKARL EVAL ERROR: Implies" \
569  " requires both a left and right expression"));
570  exit (-1);
571  }
572 }
573 
575 int64_t
576 madara::expression::EvaluationVisitor::total (void)
577 {
578  if (!stack_.is_empty ())
579  return stack_.top ();
580  else
581  return 0;
582 }
583 
585 void
586 madara::expression::EvaluationVisitor::reset (void)
587 {
588  stack_.erase ();
589 }
590 
591 #endif // _USE_VISITORS_
592 
593 #endif /* _EVALUATION_VISITOR_CPP_ */
This class encapsulates an entry in a KnowledgeBase.
Composite node that divides a variable by some right hand side.
Defines a terminal node of that references the current value stored in a variable.
Definition: VariableNode.h:28
A composite node that increments a right expression.
Defines a terminal node of that references the current value stored in a variable.
A composite node that encompasses addition of two expressions.
A composite node that compares left and right children for inequality.
Composite node that subtracts a variable by some right hand side.
A composite node that encompasses subtraction of a right expression from a left expression.
A composite node that iterates until a condition is met.
A composite node that divides a left expression by a right expression and returns the remainder of th...
A composite node that compares left and right expressions for greater than or equal to...
A composite node that evaluates both left and right expressions regardless of their evaluations...
A composite node that compares left and right children for less than or equal to. ...
A composite node that multiplies a left expression by a right expression.
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
A composite node that performs an implication (inference rule)
A composite node that decrements a right expression.
A composite node that evaluates both left and right expressions regardless of their evaluations...
A composite node that calls a function.
Defines a node that contains a madara::knowledge::KnowledgeRecord::Integer value. ...
Definition: LeafNode.h:23
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
A composite node that performs a logical and.
Composite node that multiplies a variable by some right hand side.
A composite node that compares left and right expressions for equality.
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
A composite node that logically nots a right expression.
A composite node that allows for variable assignment.
A composite node that compares left and right children for greater than.
A composite node that integrally negates a right expression.
Integer to_integer(void) const
converts the value to an integer.
virtual ComponentNode * left(void) const
Returns the left expression.
virtual madara::knowledge::KnowledgeRecord item(void) const
Returns the printable value of the node.
Definition: LeafNode.cpp:53
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
A composite node that performs a logical or.
A composite node that divides a left expression by a right one.
Defines a terminal node of that references the current value stored in a variable.
Defines a terminal node that contains a list.
Definition: ListNode.h:27
virtual ComponentNode * right(void) const
Returns the right expression.
A composite node that compares left and right children for less than.