MADARA  3.1.8
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  {
118  "\nKARL EVAL ERROR: Negate" \
119  " requires a right expression"));
120  exit (-1);
121  }
122 }
123 
125 void
126 madara::expression::EvaluationVisitor::visit (
128 {
129  if (stack_.size () >= 1)
130  {
131  madara::knowledge::KnowledgeRecord old_value = stack_.pop ();
132  try
133  {
134  VariableNode * right = dynamic_cast <VariableNode *> (node.right ());
135 
136  madara::knowledge::KnowledgeRecord new_value = --old_value;
137  if (right)
138  {
139  new_value = right->dec ();
140  }
141  stack_.push (new_value);
142  }
143  catch (::std::bad_cast &)
144  {
145  stack_.push (--old_value);
146  }
147  }
148  else
149  {
151  "\nKARL EVAL ERROR: Predecrement" \
152  " requires a right expression"));
153  exit (-1);
154  }
155 }
156 
158 void
159 madara::expression::EvaluationVisitor::visit (
161 {
162  if (stack_.size () >= 1)
163  {
164  madara::knowledge::KnowledgeRecord old_value = stack_.pop ();
165  try
166  {
167  VariableNode * right = dynamic_cast <VariableNode *> (node.right ());
168 
169  madara::knowledge::KnowledgeRecord new_value = ++old_value;
170  if (right)
171  {
172  new_value = right->inc ();
173  }
174  stack_.push (new_value);
175  }
176  catch (::std::bad_cast &)
177  {
178  stack_.push (++old_value);
179  }
180  }
181  else
182  {
184  "\nKARL EVAL ERROR: Preincrement" \
185  " requires a right expression"));
186  exit (-1);
187  }
188 }
189 
191 void
192 madara::expression::EvaluationVisitor::visit (
194 {
195  if (stack_.size () >= 1)
196  stack_.push (!stack_.pop ());
197  else
198  {
200  "\nKARL EVAL ERROR: Not" \
201  " requires a right expression"));
202  exit (-1);
203  }
204 }
205 
207 void
208 madara::expression::EvaluationVisitor::visit (
210 {
211  if (stack_.size () >= 2)
212  stack_.push (stack_.pop () + stack_.pop ());
213  else
214  {
216  "\nKARL EVAL ERROR: Add" \
217  " requires both a left and right expression"));
218  exit (-1);
219  }
220 }
221 
223 void
224 madara::expression::EvaluationVisitor::visit (
226 {
227  if (stack_.size () >= 2)
228  {
229  // for an assignment to be valid, we need a variable to the left
230  // and an expression tree to the right.
231  try
232  {
233  // this is really backwards logic, but it was the only way I could think of
234  // to allow for a = b = c with this type of tree and post-order flow
235  madara::knowledge::KnowledgeRecord right = stack_.pop ();
236  stack_.pop ();
237  VariableNode * left = dynamic_cast <VariableNode *> (node.left ());
238  left->set (right.to_integer ());
239  stack_.push (right);
240  }
241  catch (::std::bad_cast &)
242  {
244  "\nKARL EVAL ERROR: Assignment" \
245  " must have a variable as the left expression\n"));
246  exit (-1);
247  }
248  }
249  // ::std::cout << "add current top: " << stack_.top () << ::std::endl;
250 }
251 
253 void
254 madara::expression::EvaluationVisitor::visit (
256 {
257  if (stack_.size () >= 2)
258  {
259  madara::knowledge::KnowledgeRecord right = stack_.pop ();
260  madara::knowledge::KnowledgeRecord left = stack_.pop ();
261 
262  stack_.push (left && right);
263  }
264  else
265  {
267  "\nKARL EVAL ERROR: And" \
268  " requires both a left and right expression\n"));
269  exit (-1);
270  }
271 }
272 
274 void
275 madara::expression::EvaluationVisitor::visit (
277 {
278  if (stack_.size () >= 2)
279  {
280  madara::knowledge::KnowledgeRecord right = stack_.pop ();
281  madara::knowledge::KnowledgeRecord left = stack_.pop ();
282 
283  stack_.push (left || right);
284  }
285  else
286  {
288  "\nKARL EVAL ERROR: Or" \
289  " requires both a left and right expression\n"));
290  exit (-1);
291  }
292 }
293 
295 void
296 madara::expression::EvaluationVisitor::visit (
298 {
299  if (stack_.size () >= 2)
300  {
301  madara::knowledge::KnowledgeRecord right_v = stack_.pop ();
302  madara::knowledge::KnowledgeRecord left_v = stack_.pop ();
303 
304  // I was trying to use std::max, but it was giving me
305  // some grief, so I just implemented it as is
306  stack_.push (left_v > right_v ? left_v : right_v);
307  }
308  else
309  {
311  "\nKARL EVAL ERROR: And" \
312  " requires both a left and right expression\n"));
313  exit (-1);
314  }
315 }
316 
318 void
319 madara::expression::EvaluationVisitor::visit (
321 {
322  if (stack_.size () >= 2)
323  {
324  madara::knowledge::KnowledgeRecord right_v = stack_.pop ();
325  madara::knowledge::KnowledgeRecord left_v = stack_.pop ();
326 
327  // I was trying to use std::max, but it was giving me
328  // some grief, so I just implemented it as is
329  stack_.push (left_v > right_v ? right_v : left_v);
330  }
331  else
332  {
334  "\nKARL EVAL ERROR: And" \
335  " requires both a left and right expression\n"));
336  exit (-1);
337  }
338 }
339 
341 void
342 madara::expression::EvaluationVisitor::visit (
344 {
345 }
346 
348 void
349 madara::expression::EvaluationVisitor::visit (
351 {
352 }
353 
355 void
356 madara::expression::EvaluationVisitor::visit (
358 {
359  if (stack_.size () >= 2)
360  {
361  madara::knowledge::KnowledgeRecord right = stack_.pop ();
362  madara::knowledge::KnowledgeRecord left = stack_.pop ();
363 
364  stack_.push (left == right);
365  }
366  else
367  {
369  "\nKARL EVAL ERROR: Equality" \
370  " requires both a left and right expression\n"));
371  exit (-1);
372  }
373 }
374 
376 void
377 madara::expression::EvaluationVisitor::visit (
379 {
380  if (stack_.size () >= 2)
381  {
382  madara::knowledge::KnowledgeRecord right = stack_.pop ();
383  madara::knowledge::KnowledgeRecord left = stack_.pop ();
384 
385  stack_.push (left != right);
386  }
387  else
388  {
390  "\nKARL EVAL ERROR: Inequality" \
391  " requires both a left and right expression\n"));
392  exit (-1);
393  }
394 }
395 
397 void
398 madara::expression::EvaluationVisitor::visit (
400 {
401  if (stack_.size () >= 2)
402  {
403  madara::knowledge::KnowledgeRecord right = stack_.pop ();
404  madara::knowledge::KnowledgeRecord left = stack_.pop ();
405 
406  stack_.push (left >= right);
407  }
408  else
409  {
411  "\nKARL EVAL ERROR: Greater-than-equal" \
412  " requires both a left and right expression\n"));
413  exit (-1);
414  }
415 }
416 
418 void
419 madara::expression::EvaluationVisitor::visit (
421 {
422  if (stack_.size () >= 2)
423  {
424  madara::knowledge::KnowledgeRecord right = stack_.pop ();
425  madara::knowledge::KnowledgeRecord left = stack_.pop ();
426 
427  stack_.push (left > right);
428  }
429  else
430  {
432  "\nKARL EVAL ERROR: Greater-than" \
433  " requires both a left and right expression\n"));
434  exit (-1);
435  }
436 }
437 
439 void
440 madara::expression::EvaluationVisitor::visit (
442 {
443  if (stack_.size () >= 2)
444  {
445  madara::knowledge::KnowledgeRecord right = stack_.pop ();
446  madara::knowledge::KnowledgeRecord left = stack_.pop ();
447 
448  stack_.push (left <= right);
449  }
450  else
451  {
453  "\nKARL EVAL ERROR: Less-than-equal" \
454  " requires both a left and right expression\n"));
455  exit (-1);
456  }
457 }
458 
460 void
461 madara::expression::EvaluationVisitor::visit (
463 {
464  if (stack_.size () >= 2)
465  {
466  madara::knowledge::KnowledgeRecord right = stack_.pop ();
467  madara::knowledge::KnowledgeRecord left = stack_.pop ();
468 
469  stack_.push (left < right);
470  }
471  else
472  {
474  "\nKARL EVAL ERROR: Less-than" \
475  " requires both a left and right expression\n"));
476  exit (-1);
477  }
478 }
479 
481 void
482 madara::expression::EvaluationVisitor::visit (
484 {
485  if (stack_.size () >= 2)
486  {
487  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
488  stack_.push (stack_.pop () - rhs);
489  }
490  else
491  {
493  "\nKARL EVAL ERROR: Subtract" \
494  " requires both a left and right expression\n"));
495  exit (-1);
496  }
497 }
498 
500 void
501 madara::expression::EvaluationVisitor::visit (
503 {
504  if (stack_.size () >= 2 && stack_.top ())
505  {
506  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
507  stack_.push (stack_.pop () / rhs );
508  }
509  else
510  {
512  "\nKARL EVAL ERROR: Division" \
513  " requires both a left and right expression" \
514  " (and right must not be 0)\n"));
515  exit (-1);
516  }
517 }
518 
520 void
521 madara::expression::EvaluationVisitor::visit (
523 {
524  if (stack_.size () >= 2)
525  stack_.push (stack_.pop () * stack_.pop ());
526  else
527  {
529  "\nKARL EVAL ERROR: Multiply" \
530  " requires both a left and right expression\n"));
531  exit (-1);
532  }
533 }
534 
536 void
537 madara::expression::EvaluationVisitor::visit (
539 {
540  if (stack_.size () >= 2 && stack_.top ())
541  {
542  madara::knowledge::KnowledgeRecord rhs = stack_.pop ();
543  stack_.push (stack_.pop () / rhs );
544  }
545  else
546  {
548  "\nKARL EVAL ERROR: Modulus" \
549  " requires both a left and right expression" \
550  " (and right must not be 0)\n"));
551  exit (-1);
552  }
553 }
554 
556 void
557 madara::expression::EvaluationVisitor::visit (
559 {
560  if (stack_.size () >= 2)
561  stack_.push (stack_.pop () ? stack_.pop () : 0);
562  else
563  {
565  "\nKARL EVAL ERROR: Implies" \
566  " requires both a left and right expression"));
567  exit (-1);
568  }
569 }
570 
572 int64_t
573 madara::expression::EvaluationVisitor::total (void)
574 {
575  if (!stack_.is_empty ())
576  return stack_.top ();
577  else
578  return 0;
579 }
580 
582 void
583 madara::expression::EvaluationVisitor::reset (void)
584 {
585  stack_.erase ();
586 }
587 
588 #endif // _USE_VISITORS_
589 
590 #endif /* _EVALUATION_VISITOR_CPP_ */
This class encapsulates an entry in a KnowledgeBase.
#define DLINFO
Definition: LogMacros.h:27
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.
#define MADARA_ERROR(L, X)
Definition: LogMacros.h:114
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.
#define MADARA_LOG_TERMINAL_ERROR
Used for MADARA errors at the point the error exits the process in question, or when a decision is ma...
Definition: LogMacros.h:40
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.